[openstack-dev] [keystone][oslo] Handling contexts and policy enforcement in services

Jamie Lennox jamielennox at redhat.com
Mon Dec 1 01:51:20 UTC 2014


TL;DR: I think we can handle most of oslo.context with some additions to
auth_token middleware and simplify policy enforcement (from a service
perspective) at the same time.

There is currently a push to release oslo.context as a
library, for reference:
https://github.com/openstack/oslo.context/blob/master/oslo_context/context.py

Whilst I love the intent to standardize this
functionality I think that many of the requirements in there
are incorrect and don't apply to all services. It is my
understanding for example that read_only, show_deleted are
essentially nova requirements, and the use of is_admin needs
to be killed off, not standardized.

Currently each service builds a context based on headers
made available from auth_token middleware and some
additional interpretations based on that user
authentication. Each service does this slightly differently
based on its needs/when it copied it from nova.

I propose that auth_token middleware essentially handle the
creation and management of an authentication object that
will be passed and used by all services. This will
standardize so much of the oslo.context library that I'm not
sure it will be still needed. I bring this up now as I am
wanting to push this way and don't want to change things
after everyone has adopted oslo.context.

The current release of auth_token middleware creates and
passes to services (via env['keystone.token_auth']) an auth
plugin that can be passed to clients to use the current user
authentication. My intention here is to expand that object
to expose all of the authentication information required for
the services to operate.

There are two components to context that I can see:

 - The current authentication information that is retrieved
   from auth_token middleware.
 - service specific context added based on that user
   information eg read_only, show_deleted, is_admin,
   resource_id

Regarding the first point of current authentication there
are three places I can see this used:

 - communicating with other services as that user
 - associating resources with a user/project
 - policy enforcement

Addressing each of the 'current authentication' needs:

 - As mentioned for service to service communication
   auth_token middleware already provides an auth_plugin
   that can be used with (at this point most) of the
   clients. This greatly simplifies reusing an existing
   token and correctly using the service catalog as each
   client would do this differently. In future this plugin
   will be extended to provide support for concepts such as
   filling in the X-Service-Token [1] on behalf of the
   service, managing the request id, and generally
   standardizing service->service communication without
   requiring explicit support from every project and client.

 - Given that this authentication plugin is built within
   auth_token middleware it is a fairly trivial step to
   provide public properties on this object to give access
   to the current user_id, project_id and other relevant
   authentication data that the services can access. This is
   fairly well handled today but it means it is done without
   the service having to fetch all these objects from
   headers.

 - With upcoming changes to policy to handle features such
   as the X-Service-Token the existing context will need to
   gain a bunch of new entries. With the keystone team
   looking to wrap policy enforcement into its own
   standalone library it makes more sense to provide this
   authentication object directly to policy enforcement.
   This will allow the keystone team to manipulate policy
   data from both auth_token and the enforcement side,
   letting us introduce new features to policy transparent
   to the services. It will also standardize the naming of
   variables within these policy files.

What is left for a context object after this is managing
serialization and deserialization of this auth object and
any additional fields (read_only etc) that are generally
calculated at context creation time. This would be a very
small library.

There are still a number of steps to getting there:

 - Adding enough data to the existing authentication plugin
   to allow policy enforcement and general usage.
 - Making the authentication object serializable for
   transmitting between services.
 - Extracting policy enforcement into a library.

However I think that this approach brings enough benefits to
hold off on releasing and standardizing the use of the
current context objects.

I'd love to hear everyone thoughts on this, and where it
would fall down. I see there could be some issues with how
the context would fit into nova's versioned objects for
example - but I think this would be the same issues that an
oslo.context library would face anyway.

Jamie


[1] This is where service->service communication includes
the service token as well as the user token to allow smarter
policy and resource access. For example, a user can't access
certain neutron functions directly however it should be
allowed when nova calls neutron on behalf of a user, or an
object that a service made on behalf of a user can only be
deleted when the service makes the request on behalf of that
user.





More information about the OpenStack-dev mailing list