jenskeiner opened a new issue #3274: URL: https://github.com/apache/apisix/issues/3274
I'm opening this issue to get some feedback on some proposed changes to the `auth-keycloak` plugin before I shoot off and start working on them. The current incarnation of the plugin has some limitations that limit its usefulness. The most visible limitation, to me at least, is that you can only configure a static set of resource/scope pairs. Without delving into too many details of the Keycloak Authorization Services API (described here in all its glory: https://www.keycloak.org/docs/latest/authorization_services/index.html), it's worth mentioning that permissions are defined in terms of resource/scope pairs. If you think of some REST service that you want to protect, then a resource would typically be a subset of the available endpoints, defined by some URI pattern, e.g. `/foo/bar/*`. A scope typically describes the type of action to perform on the resource, e.g. read, write, delete, but can also really be something completely different and abstract, depending on the use case. To check if an incoming request should be allowed to proceed to the upstream, or if it should be rejected, the plugin currently uses the token endpoint (which is also used for OIDC authentication) with a special grant type. The requested permissions, specified by resource/scope pairs are sent as a parameter to that endpoint together with the bearer token from the request. Keycloak evaluates the permissions and answers with the decision, i.e. whether the permissions are granted or not. If yes, then the request can proceed, otherwise, it is rejected. As I said above, the set of resource/scope pairs is currently fixed in the plugin configuration. But often, what you want to do is to determine the resource and scope from features of the incoming request like HTTP method and URI. Actually, the documentation mentions this as future work, but that has so far not materialized. Just upfront: The changes I want to propose would need to be split into smaller PRs that build onto each other. Basically, I want to propose to implement (optional) dynamic resource and scope resolution as follows: - The scope is determined by the HTTP method of the request (i.e. a GET request maps to scope GET). - The resource is determined by using Keycloak's resource registration endpoint which can return the resources that match a given URI. I have a working example of this in a branch. There are some points to observe though: - Using the resource registration endpoint requires another request to Keycloak on top of the one to the token endpoint that returns the decision. Longer term, but maybe not in the first iteration, caching can be implemented to reduce the number of necessary requests. - To be able to invoke the resource registration endpoint, the plugin first needs to obtain a separate access token for itself from the token endpoint via client ID and secret. This is a special token that has the `uma_protection` scope which allows access to the Protection API and hence the resource registration endpoint. It's relative easy to obtain the token, but some management needs to be implemented because the token needs to be refreshed regularly as it will typically be short-lived. This will make the code base a bit more complex, but cannot be avoided. - Longer term, it may be better to load all resources from Keycloak once (maybe with periodic updates), and match the request URI to the resources in the plugin, e.g. with the help of the radix tree library already used for routes. This would avoid the requests that are needed just to determine the resource. To sum up, I would propose above changes, but with the focus on first getting the scope and resource discovery working properly, before focusing on further optimizations like caching. Would love to hear anyone's thoughts. Maybe @sshniro can chime in because you've worked a lot with the plugin already. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected]
