Ever get that feeling that an epiphany is right around the corner? I spent a good portion of the OpenStack summit with that feeling. I knew that it would not be earth shattering, or lead me to want to rewrite Keystone, but rather a clarification of how a bunch of things should fall together. The “click” happened on the second to last day, and it can be summarized in a few key points.
When discussing the OAUTH1.0 extension to Keystone, several people commented on how it was similar to trusts, and that we should have a unified mechanism between them for delegation. During a discussion with David Chadwick, he mentioned that the role assignments themselves were a form of delegation, and lamented that we were losing the chain of delagtion by how we delegate roles. So the first point was this:
Keystone should have a single, unified mechanism for delegation.
One key feature that feeds into that is the ability to break a big role into a small one. I had posted a spec for hierarchical roles prior to the summit, but wasn’t clear for how to implement it; I could see how it coule be implemented on the token side, but all people I talked to insisted it made more sense on the enforcement side. That is the second big point.
Role inheritance should be expanded by policy enforcement.
Policy is almost all static. Each OpenStack project had it’s own policy file in its own it repo. Extending it to cover is user requests for things like project specific policy or more granular roles has not been possible.
UPDATE: I’ve been asked to make clearer what problems this addresses.
- Determine what roles a user can assign to another user
- Allow a user to determine what roles they need to perform some action
- Allow some user interface to determine what a user is capable of doing based on their roles
- Establish an iterative process solve the long-standing bug that a user with admin on any scope has admin on all scoped.
- Allow a user to delegate a subset of their capabilites to a remote service.
What we have now is a simple set of specs that build on each other that will, in the end, provide a much more powerful, flexible, and consistant delegation mechanism for Keystone. Here are the General steps:
- Graduate oslo policy to a library
- Add to the policy library the essential code to enforce policy based on a keystone token. I’ve looked at both the Keystone and Nova pieces that do this, and they are similar enough that we should not have too much problem making this happen.
- Add in the ability to fetch the policy.json file from Keystone.
- Add a rule to the Keystone policy API to return the default policy file if no policy file is specified for an endpoint.
- Merge the current default policy files from all of the projects into a single policy file, with namespaces that keep the rules from conflicting across services. Reduce the duplication of rules like “admin_or_owner” so that we have a consistent catalog of capabilities across OpenStack. Make this merged file the default that is served out of Keystone when an endpoint asks for a policy file and Keystone does not have an endpoint specific file to give it.
- Make a database schema to hold the rules from the policy file. Use this to generate the policy files served by Keystone. There should be no functional difference between the global file and the one produced in the above merge.
- Use the hierarchical role definitions to generate the rules for the file above. For example, rules that essentially say “grant access to a user with any role on this project” will now say “grant access to any user with the member role, or with any role that inherits the member role. The member role will be the lowest form of access. Admin will inherit member, as will all other defined roles.
- Break member up into smaller roles. For example, we could distinguish between actions that can only read state from those that can change it: “Observer” and “Editor” Member would inherit editor, and editor would inherit observer.
- Change the rules for specific API policy enforcement points to know about the new roles. For example, the API to create a new image in glance might now require the editor role instead of the member role. But, since member inherits editor, all current users will be able to perform the same set of operations.
- Change the role assignment mechanism so that a user can only assign a role that they themselves have on the designated scope. In order to assign Member, the user must have the member role, or a role that inherits Member,such as admin. Role assignment, trusts, oauth, and any other mechanism out there will follow this limitation. We will have to perform additional limitations, such as determining what happens to a delegated role when the person that does the delegation has that role removed; perhaps one will need a specific role in order to perform “sticky” role assignments that last past your employment, or perhaps we will allow a user to pass some/all their delegations on to another user.
This is still in the planning stage. One nice thing about a plan like this is that each stage shows value on its own, so that if we only get as far as, say stage 3, we still have a better system than we do today. Many of the details are still hiding in the weeds, and will require more design. But I think the above approach makes sense, and will make Keystone do what a lot of people need it to do.