-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add caching for authorization checks #87
Conversation
Thank you @krithika369 for such a detailed PR description and well-documented code!
Did you consider some options for immediate cache expiration in the event of updates to the AuthZ policies? If I understood it correctly, with this change, it will take up to |
This is tricky. The reason being, the cache will be stored in-memory, within each component (Turing, Merlin, etc.) but the MLP API is the one that handles the Authz update. We could introduce an internal It might be better if this were communicated using an event-bus. Both of these approaches may require some work. Since the only way that users can change the Authz permissions today is via the UI, I'm thinking that, for now, we can add a notice when the setting is edited (the Next Steps, will open another PR for this). Though, in doing this, there is another problem - the LMK if you have other thoughts. |
Yes, that would be handy. Could also be a WebSocket connection to deliver system events between CaraML components or/and UI
I don't think we need too precise here. A simple disclaimer that "it could take several minutes for the changes to take effect" will do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Late to the party... |
The Authz cache is entirely server-side. It's not related to the contents loaded by the browser. Is this relevant? |
I am aware of that part. |
I see... If we took this route, based on the architecture we have today, the user will have to perform a hard-refresh on the app where they want to see the permission changes. This can be somewhat natural to do for user accounts + UI workflows (eg: user navigates to Merlin, cannot see models and does a hard-refresh) but not so much when altering permissions for service accounts. Also, it can be confusing - if they did a hard refresh on the List Routers view and subsequently opened a router's settings, the permissions on the experiment engine (XP management) may not be updated still. Besides, I'm a little reluctant to invalidate all the backed cache based on So, for now, I prefer we simply warn the users to wait a few minutes (UI changes here). |
<!-- Thanks for sending a pull request! Here are some tips for you: 1. Run unit tests and ensure that they are passing 2. If your change introduces any API changes, make sure to update the e2e tests 3. Make sure documentation is updated for your PR! --> **What this PR does / why we need it**: <!-- Explain here the context and why you're making the change. What is the problem you're trying to solve. ---> This PR largely replicates the changes for the API in caraml-dev/mlp#87, to have the option of caching authz responses. As a part of this implementation, the API dependency on MLP has been upgraded. **Which issue(s) this PR fixes**: <!-- *Automatically closes linked issue when PR is merged. Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`. --> None **Does this PR introduce a user-facing change?**: <!-- If no, just write "NONE" in the release-note block below. If yes, a release note is required. Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required". For more information about release notes, see kubernetes' guide here: http://git.k8s.io/community/contributors/guide/release-notes.md --> ```release-note Add caching options for authorization responses, to improve the performance of the control plane APIs ``` **Checklist** - [ ] Added unit test, integration, and/or e2e tests - [x] Tested locally - [ ] Updated documentation - [ ] Update Swagger spec if the PR introduce API changes - [ ] Regenerated Golang and Python client if the PR introduce API changes
Motivation
This PR adds an in-memory cache for the authorization checks. The purpose of this cache is to reduce the load on the underlying authz API server, given that these mappings rarely change.
Implementation
api/pkg/authz
A simple map-based in-memory caching mechanism is introduced in
api/pkg/authz/enforcer/enforcer.go
, which stores the result (true/false) of eachaction:subject:resource
combination that is checked for.The cache itself is implemented in
api/pkg/authz/enforcer/cache.go
and includes some minor optimization on the cache key used (mapping action/subject/resource names to auto-generated IDs) so that the data stored in the cache is concise.Eg:
GET:firstname.lastname@domain.com:projects
->1:1:2
If the cache is enabled on the Enforcer, it will be initialised and used as a read-aside cache. The key expiration and cache clean up interval are configurable.
This package is used in multiple CaraML components such as the MLP API (changes described below), Turing, Merlin, etc. If the in-memory cache is enabled, the onus is on the consumers of this package to:
a
anda:**
together (and there are no DENY permissions involved), when the app must check for permissions ona:b:c
, it can instead decide to check for the permission ona
only, to reduce the number of unique cache keys created.api/api
api/config/config.go
- Add config options for using caching with the authz layerapi/middleware/authorization.go
- Manipulate the resource names to only run checks against the first 2 levels. This is sufficient because most permissions are granted project-wide (with the exception of the/applications
API, which doesn't have any sub-resources).api/api/router.go
- Enable authz cachingNext steps
Other changes
golanci-lint
action directly