[keycloak-user] Permissions: Slow/complex interactions

Pedro Igor Silva psilva at redhat.com
Wed Aug 1 11:57:58 EDT 2018


Docker

On Wed, Aug 1, 2018 at 12:17 PM, Corentin Dupont <corentin.dupont at gmail.com>
wrote:

>
> Are you making you perf evaluation with Docker or without?
>
>
> On Wed, Aug 1, 2018 at 3:50 PM, Pedro Igor Silva <psilva at redhat.com>
> wrote:
>
>> Hi,
>>
>> I also noticed JS slow. I'm working with some changes [1] which seems to
>> improve JS and evaluation as a whole. if you want I can give you a docker
>> image based on 4.2.0-SNAPSHOT + changes, wdyt ? Would be nice to see how
>> you perform with this version ...
>>
>> Also noticed better response time when running Keycloak on top of graalvm
>> (maybe because of graaljs) and jdk9+.
>>
>> I'm using a client with 1000 resources, 1000 permissions (one for each
>> resource) each with 10 role policies associated by default, 500 role
>> policies and 3 permissions using a mix of 4 JS (including your
>> publicResource and owner policies), roles and groups. Where these 3
>> permissions are evaluated based on scopes and they are considered to
>> calculate access to every single resource.
>>
>> My tests are not making "all entitlements" requests, but several
>> concurrent requests (trying to keep a constant of 300/400 req/s) asking for
>> individual resources.
>>
>> When I try to obtain all entitlements I usually get response times from
>> 800ms to 1200ms. Considering the number of resources I have, you should get
>> a much better response.
>>
>> I've also introduced a "response_mode" parameter to the authorization
>> request. You can now set this parameter as "decision" or "permissions". The
>> "decision" mode returns only a json with a single claim indicating whether
>> or not request was granted, where "permissions" just returns the
>> permissions (no tokens).
>>
>>
>> On Wed, Aug 1, 2018 at 10:25 AM, Corentin Dupont <
>> corentin.dupont at gmail.com> wrote:
>>
>>> I tried to make some more performance testing.
>>> With the same settings than before (70 resources, one scope), I obtain:
>>>
>>> - User policy (3 users): 15 ms
>>> - Javascript policy 1: 41ms
>>> - Javascript policy 2: 45ms
>>>
>>> It seems that Javascript policies are very slow.
>>> Actually I think the user policy does not take more than 3 ms to run
>>> over all the resources (if we remove the time due to HTTP overhead).
>>> While the Javascript policies take around 30ms to run over the resources.
>>> Is it a problem due to loading/switching to the Javascript engine for
>>> each resource?
>>>
>>>
>>>
>>> On Wed, Jul 25, 2018 at 12:58 PM, Corentin Dupont <
>>> corentin.dupont at gmail.com> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Jul 24, 2018 at 11:11 PM, Pedro Igor Silva <psilva at redhat.com>
>>>> wrote:
>>>>
>>>>> We have now a performance testsuite (thanks to Tomaz) that can
>>>>> generate also generate datasets to cover different scenarios. I'm the
>>>>> middle of checking Tomaz work and preparing some datasets to include in our
>>>>> testsuite.
>>>>>
>>>>
>>>> Great!
>>>>
>>>>
>>>>>
>>>>> I'm going to give a try to your use case and see if I can get the same
>>>>> numbers. Not sure if this is your case, but I found some performance issues
>>>>> when defining multiple resources with a type where the owner is the
>>>>> resource server itself. This causes an overhead during evaluation where the
>>>>> engine tries to consider permissions granted to any of these typed
>>>>> resources. Someone reported this some time ago, and IMO, this is an invalid
>>>>> usage of resource types ... Not sure if this is your case though.
>>>>>
>>>>
>>>> I don't really use the type of resource, actually... How do you make a
>>>> permission request based on types?
>>>>
>>>>
>>>>
>>>>>
>>>>> More answers inline.
>>>>>
>>>>> On Tue, Jul 24, 2018 at 7:24 PM, Corentin Dupont <
>>>>> corentin.dupont at gmail.com> wrote:
>>>>>
>>>>>>
>>>>>>
>>>>>> On Tue, Jul 24, 2018 at 11:51 AM, Pedro Igor Silva <psilva at redhat.com
>>>>>> > wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Jul 24, 2018 at 7:54 AM, Corentin Dupont <
>>>>>>> corentin.dupont at gmail.com> wrote:
>>>>>>>
>>>>>>>> Hi guys,
>>>>>>>> I experience some performance issue on my API server using Keycloak.
>>>>>>>> After someone issue a GET on my API server, here is what happens:
>>>>>>>>
>>>>>>>> - API server -> DB server: get requested resources
>>>>>>>> - API server -> Keycloak: get client token (to get resources)
>>>>>>>> - API server -> Keycloak: get resources (to complement DB server
>>>>>>>> with
>>>>>>>> resource owner & visibility)
>>>>>>>> - API server -> Keycloak: get user token (to get permission)
>>>>>>>> - API server -> Keycloak: get permission (to filter resources)
>>>>>>>> At this point the filtered resources are returned.
>>>>>>>>
>>>>>>>> But this process is quite slow. I noticed a call to KC can take up
>>>>>>>> to 100ms.
>>>>>>>> The complete call on the API server can take up to 600ms on my
>>>>>>>> laptop, in
>>>>>>>> localhost setting.
>>>>>>>> The delays become noticeable on my UI...
>>>>>>>>
>>>>>>>
>>>>>>> Are you able to confirm the step(s) spending more time to process ?
>>>>>>> If when obtaining client tokens, resources or during evaluation ?
>>>>>>>
>>>>>>
>>>>>> I made a quick benchmark, here is the result:
>>>>>>
>>>>>> - API server -> Keycloak: get client token: 400ms
>>>>>> - API server -> Keycloak: get resources: 1356ms
>>>>>> - API server -> Keycloak: get user token: 162ms
>>>>>> - API server -> Keycloak: get permission: 2400ms
>>>>>> Total: 4366ms
>>>>>>
>>>>>> However, this timings are obtained only on the first try after I
>>>>>> reboot the server.
>>>>>> The next calls are faster. Maybe it's due to caching?
>>>>>>
>>>>>
>>>>>> - API server -> Keycloak: get client token: 17ms
>>>>>> - API server -> Keycloak: get resources: 19ms
>>>>>> - API server -> Keycloak: get user token: 92ms
>>>>>> - API server -> Keycloak: get permission: 314ms
>>>>>> Total: 476ms
>>>>>>
>>>>>
>>>>> Yeah, it is caching. But numbers for steps #2 and #4 are high. Will
>>>>> see what we can improve.
>>>>>
>>>>> Thanks for the numbers. Wondering if you have percentiles for these
>>>>> requests ? Or this happens when you send a single request ?
>>>>>
>>>>
>>>> This is a single request... I scrapped the timestamps in my traces.
>>>>
>>>>
>>>>
>>>>>
>>>>>
>>>>>>
>>>>>> So yes, it's the evaluation taking time (and user token on a lesser
>>>>>> extent).
>>>>>> On this call, I need to get permissions for all resources on one
>>>>>> scope: permissions=#sensors:view
>>>>>> Because I need to filter out the resources the user cannot see.
>>>>>> There are around 70 resources and 3 policies (one user policy and 2
>>>>>> javascript).
>>>>>> Keycloak is in a docker container.
>>>>>>
>>>>>
>>>>> I'm working with more aggresive numbers, and results are better than
>>>>> yours. However, all depends on how you are setting up your settings. Need
>>>>> to check your setup and see if I can create a dataset based on it.
>>>>>
>>>>> Could you send me an example of those javascript policies ? Are they
>>>>> doing much ? Do you have more than one user per user policy ?
>>>>>
>>>>
>>>> I attach my 2 javascript policies. They are very simple, should be O(1).
>>>> The user policy has 3 users.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Also, could you elaborate more what this step is doing: "- API
>>>>>>> server -> Keycloak: get resources (to complement DB server with
>>>>>>> resource owner & visibility)" ?
>>>>>>>
>>>>>>
>>>>>> I read the resources from Keycloak (authz/protection/resource_set/)
>>>>>> because I need to return the owner of the resource in my server response.
>>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> With a resource SPI strategy (if developed), it should be:
>>>>>>>>
>>>>>>>> - API server -> DB server: get requested resources
>>>>>>>> - API server -> Keycloak: get user token (to get permission)
>>>>>>>> - API server -> Keycloak: get permission (to filter resources)
>>>>>>>> - Keycloak -> DB server: get resources
>>>>>>>>
>>>>>>>> There is a little less requests. Additional gain is that resources
>>>>>>>> are not
>>>>>>>> split between 2 databases.
>>>>>>>>
>>>>>>>> I wonder if resources could be pushed during the permission
>>>>>>>> request? Like a
>>>>>>>> "pushed claim".
>>>>>>>> This would be even more straightforward:
>>>>>>>>
>>>>>>>> - API server -> DB server: get requested resources
>>>>>>>> - API server -> Keycloak: get user token (to get permission)
>>>>>>>> - API server -> Keycloak: get permission and push resources
>>>>>>>
>>>>>>>
>>>>>>>> Can this work?
>>>>>>>>
>>>>>>>
>>>>>>> I think this is an area we might want to improve in order to allow
>>>>>>> evaluating permissions solely based on claims pushed to the server. That
>>>>>>> means you won't need to manage resources in the server but rely on policies
>>>>>>> to process the "pushed claims".
>>>>>>>
>>>>>>
>>>>>> Yes that would be great. Let me open a Jira to track this.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> +1
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> keycloak-user mailing list
>>>>>>>> keycloak-user at lists.jboss.org
>>>>>>>> https://lists.jboss.org/mailman/listinfo/keycloak-user
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>


More information about the keycloak-user mailing list