On 05/05/2015 07:05 AM, Henry Nash wrote:
We’ve been discussing changes to these areas for a while - and
although I think there is general agreement among the keystone cores
that we need to change *something*, we’ve been struggling to get
agreement on exactly how.. So to try and ground the discussion that
will (I am sure) occur in Vancouver, here’s an attempt to take a step
back, look at what we have now, as well as where, perhaps, we want to
get to.
This is a great summary. Thanks Henry.
The core functionality all this is related to is that of how does
keystone & policy allow the checking of whether a given API call to an
OpenStack service should be allowed to take place or not. Within
OpenStack this is a two step process for an API caller….1) Get
yourself a token by authentication and getting authorised for a
particular scope (e.g. a given project), and then 2) Use that token as
part of your API call to the service you are interested in. Assuming
you do, indeed, have the rights to execute this API, somehow steps 1)
and 2) give the policy engine enough info to say yes or no.
So first, how does this work today and (conceptually) how should we
describe that? Well first of all, in fact, strictly we don’t control
access at the raw API level. In fact, each service defines a series
“capabilities” (which usually, but not always, map one-to-one with an
API call). These capabilities represent the finest grained access
control we support via the policy engine. Now, in theory, the most
transparent way we could have implemented steps 1) and 2) above would
have been to say that users should be assigned capabilities to
projects….and then those capabilities would be placed in the
token….allowing the policy engine to check if they match what is
needed for a given capability to be executed. We didn’t do that since,
a) this would probably end up being very laborious for the
administrator (there would be lots of capabilities any given user
would need), and b) the tokens would get very big storing all those
capabilities. Instead, it was recognised that, usually, there are sets
of these capabilities that nearly always go together - so instead
let’s allow the creation of such sets….and we’ll assign those to users
instead. So far, so good. What is perhaps unusual is how this was
implemented. These capability sets are, today, called Roles…but rather
than having a role definition that describes the capabilities
represented by that role….instead roles are just labels - which can be
assigned to users/projects and get placed in a tokens. The expansion
to capabilities happens through the definition of a json policy file
(one for each service) which must be processed by the policy engine in
order to work out what whether the roles in a token and the
role->capability mapping means that a given API can go ahead. This
implementation leads to a number issues (these have all been raised by
others, just pulling them together here):
i) The role->capability mapping is rather static. Until recently it
had to be stored in service-specific files pushed out to the service
nodes out-of-band. Keystone does now provide some REST APIs to store
and retrieve whole policy files, but these are a) course-grained and
b) not really used by services anyway yet.
ii) As more and more clouds become multi-customer (i.e. a cloud
provider hosting multiple companies on a single OpenStack
installation), cloud providers will want to allow those customers to
administer “their bit of the cloud”. Keystone uses the Domains concept
to allow a cloud provider to create a namespace for a customer to
create their own projects, users and groups….and there is a version of
the keystone policy file that allows a cloud provider to effectively
delegate management of these items to an administrator of that
customer (sometimes called a domain administrator). However, Roles
are not part of that namespace - they exists in a global namespace
(within a keystone installation). Diverse customers may have different
interpretations of what a “VM admin” or a “net admin” should be
allowed to do for their bit of the cloud - but right now that
differentiation is hard to provide. We have no support for roles or
policy that are domain specific.
iii) Although as stated in ii) above, you can write a policy file that
differentiates between various levels of admin, or fine-tunes access
to certain capabilities, the reality is that doing this is pretty
un-intuative. The structure of a policy.json file that tries to do
this is, indeed, complex (see Keystone’s as an example:
https://github.com/openstack/keystone/blob/master/etc/policy.v3cloudsample.json).
Adding more capability to this will likely only make the situation worse.
We have a number of specs taking shape to try and address the above (a
number of them competing), so I wanted to propose with a set of
guidelines for these:
a) Making the policy centrally sourced (i.e. in keystone) and more
dynamic seems eminently sensible. We’ll need to work on notifications
etc. for how services know the policy has changed, of course. Such a
centralised capability allows us to not just use a json file to store
policy, but perhaps a database - allowing more fine-grained access to
policy rules via an API. See:
https://review.openstack.org/#/c/147651/ and
https://review.openstack.org/#/c/133814/ as examples.
b) One of the core disagreements has been around whether any
additional structure we add to roles is processed at token generation
time or at token analysis time by the policy engine. To be honest, I
don’t think our deployers care - as long as we don’t break something
like making tokens even bigger. What they will care about is whether
they can hold in the heads the concepts for what it is they need to
set up to achieve the policy framework that want. Let’s concentrate on
making this easy for them, and under the hood we’ll solve the bits and
bites.
c) We have had competing suggestions for role sets/group/hierarchies
(see: https://review.openstack.org/#/c/125704/ and
https://review.openstack.org/#/c/133855/ ). I would suggest that we go
for a base functionality of role sets (where a role set can contain
roles or other role sets)….where these can either be global in scope or
While I agree with the basic approach, I would argue instead that a Role
is a set of capabilities, and so we don't need role sets, we need
capability sets (which we have) and then we say a role can contain other
roles. The set of capabilites is then defined as the union of the
capabilities assigned to it directly and the capabilites assigned to
subordinate roles.
The set can be easily defined in the policy.json file. So the
requirment then is to keep the Keystone view of these nested roles in
sync. The database driven approach makes this simpler, but this can be
done today by hand with the existing policy file. Demonstrating this is
part of my dynamic policy presentation.
domain specific. Both need to be supported and it must be possible
for a cloud provider to delegate to a domain admin the ability to
create their own role sets. Whether roles sets are processed by the
policy engine or at token generation time (see b) above) is something
we need to hash out. I’m actually Ok with either…as long as one
development route is not inordinately longer than the other - and, at
least for me, domain specific role sets must be in any first
implementation (this is the customer need I see most). I wouldn’t rule
out a development plan where we 1) get the API right, 2) implement it
so that the tokens and policy doesn’t have to change (i.e. we expand
role sets at token generation time), and then 3) push this capability
into the policy engine itself. If we can skip 2) and get to 3)
quickly, more the better.
I think do step 3 first; we can make the policy engine handle the rules
inferences for roles as sets of capabilities. Policy generation from
the database happens second, and the API for more fine grained control
happens third.
d) I’d like to keep in mind an eventual destination where services
could “register their capabilities” via an API, policy rules and
roles/sets can then be created via APIs that then allow assignments to
be made in terms that make sense to a domain administrator (i.e. in
terms that are meaningful to them), that make a customer hosted on a
shared cloud feel that this really is "their cloud”.
That should work. In order for a user to get access to those new
capabilites we'd have three choices:
1. Add them to an existing role
2. Add them to a new role and assign that new role as a subset of an
existing role
3. Add them to a new role and assign them to the user directly.
Henry
__________________________________________________________________________
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
__________________________________________________________________________
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev