Jump to: navigation, search


Short Term AuthZ in Nova

The Problem

AuthZ is the ability to ask the question "Can <User> <Do something> to <some resource>?" For example, "Can [Sandy] [Delete Instance] [virus-laden-server]?"

Keystone is the blessed auth system for Nova. In order to provide the above functionality, Keystone uses some special abstractions:

  • Roles - Groups of users may have similar job functions. Roles are a way to group these users. This way, we don't have to explicitly state that Bob, Mary and Alice can console into the Financial server, we can say that Bob, Mary and Alice have the Finance Role.
  • Capabilities - Capabilities are the <do something> part of AuthZ. What operations can the <user> perform on the <resource>? There will be a set of standard, agreed-upon capabilities for all of Nova, Swift, etc as well as the ability for each service to add their own.

And finally the mapping of Roles & Capabilities to Resources. This will give the full data model AuthZ needs to be functional.

The problem is complicated once we adopt Zones. In this situation, the model defined in the AuthZ system needs to apply to resources across multiple Nova installations. Even more complicated is the Federated deployment model where the customer has their own Nova deployment and wishes to "burst" out to use a service providers nova deployment. These requirements are documented here: http://wiki.openstack.org/FederatedAuthZwithZones

The good news is, there are plans afoot to add all of this functionality to Keystone (which, up until now, has been focused on AuthN). The bad news is, we may need some primitive AuthZ functionality in Nova before the Keystone implementation is ready.

This page will propose a way to get crude AuthZ support in Nova, in the short term.

We are hoping to talk about this problem and the steps proposed on this page at the Essex Design Summit http://summit.openstack.org/sessions/view/80

The Keystone AuthZ Roadmap

Keystone will be holding a session at the Essex Design Summit to talk about their AuthZ plans http://wiki.openstack.org/keystone and plan to ratify these plans by mid-November 2011.

In a nutshell, the planned roll-out will be in 3 phases:

In phase 1, empty roles will be added. Empty roles are roles without capabilities. We will be able to relate users to roles, but not say what these roles can do. In phase 2, roles will have capabilities. But these capabilities will not be in the context of any given resource. In phase 3, the role, capability, resource collection will be complete. At this point our stop-gap AuthZ efforts may be removed from Nova and replaced with Keystone.

The Problem at a Technical Level

Resource Management

The end goal of AuthZ in Nova is that Nova should not have to worry about Roles or User-Resource mappings. Instead we should only have to map Resources to Roles. The keystone administrator should handle all of the assignment of capabilities to these roles as well as which users have these roles. Why? Because as we move into federated deployments and multi-zone deployments, we cannot assume to have access to the role or user information contained in external AuthZ systems. We will only have a tuples of "<Token> can <do something> on <Resource UUID>" ... all the rest will be hidden from us. The sooner we adopt that mindset in Nova, the easier it will be for us down the road.

But let's consider what we mean by a Resource. The natural assumption is that a resource is some entity that nova manages. The obvious resources are instances, networks and volumes. But, at a practical level, if we had to go back to keystone for every instance, network or volume that was added or removed from the environment, keystone would be very busy indeed.

Instead, we need to be able to group these resources into Resource Groups. Nova can effortlessly add or remove instances from these resource groups without having to tax keystone. Keystone can handle the assignment of Roles to Resource Groups (or lower-level Resources if absolutely required, since they're really just UUID's in the system anyway).


Task: Add Resource Groups to Nova

We will need to add management (and admin api?) support for CRUD operations of Resource Groups. It's not clear yet if these resource groups need be homogeneous or heterogeneous, but I'm assuming hetero since we'd likely want to bundle networks, instances and volumes into a single group for control.

Task: Inform the AuthZ system about these Resource Groups

The AuthZ system can't manage what it doesn't know. When resource groups are added/removed we need to inform the AuthZ system so that the administrator can sew up the relationships.

Capability Enforcement

Once we have our mapping of Resource Groups to Tokens in place, at some point we have to find out if the current token can <do something> to the resource in question.

The question is, who performs this check? Should Nova have a cache of all of the token-to-resource mappings that are associated with the current token? Probably not, if the list is large. Should Nova query back to the AuthZ system to ask "Can <token> <do this> to <resource>?" ... that would be nice, but will have a time/network cost.

Task: Make a(n) (in-memory?) service that we can query for AuthZ checks

Down the road, this will be replaced by keystone ... ideally with some caching to keep it efficient.

Next, where should these permissions checks occur? Let's have a quick look back at the nova flow:


There are three places we can do these checks:

  1. At the Public API layer (which means we'd have to put checks in OS API and EC2 API
  2. At the Service API layer. The common meeting are for all operations, but before the work is actually done.
  3. In the service itself. Where the rubber meets the road.

Personally, I think #2 the Service API layer is the right place for this.

We could do the check via decorators, but it's hard to put the Resource ID in the decorator since we may not know what the target resource actually is until we're deep into the function. So I think decorators are out. This means explicit function calls to the auth service in the service api methods.

    self.authz.check_can_delete(context, resource)

which would raise an exception if not permitted

Task: write this authz enforcement class

Later, this class will delegate the operations to keystone, but for now it will just do the work itself.

Task: Decide what the core set of capabilities should be

Task: Add this authz class to the service API's in the appropriate places

Task: Add an exception handler somewhere to give meaningful error messages (maybe not needed?)


Finally, we need some sort of data store to keep this temporary authZ data. This doesn't need to be fancy, since it's all going to be replaced. We don't need all kinds of db schema updates with nova-manage changes, etc.

Thinking about some sort of .conf / .py or .json file that has the basic relationships of Resource Group -> User/Token -> Capability.

Question is, is it ok that this is static data that may require bringing down the dependent services when changed? Or we could make it auto-detect file changes and reload as needed? Perhaps overkill?

Task: Write a primitive data store for AuthZ data