Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc. - Role Assignment

2015-05-09 Thread David Chadwick
Hi Tim

I was implying that the addRole operation would not be used or needed in
the federation case, because all user roles are initially created by
IdPs and then by attribute mappings.

I was not saying anything about the various admin roles that might exist
because as I understand it, there is no limitation on the number of
roles that can be defined in OpenStack.

regards

David

On 08/05/2015 15:52, Tim Hinrichs wrote:
 Hi David,
 
 See below.
 
 On 5/7/15, 1:01 AM, David Chadwick d.w.chadw...@kent.ac.uk wrote:
 
 Hi Tim

 On 06/05/2015 21:53, Tim Hinrichs wrote:
 I wondered if we could properly protect the API call for adding a new
 Role using the current mechanism.  So I came up with a simple example.

 Suppose we want to write policy about the API call: addRole(user,
 role-name).  If we¹re hosting both Pepsi and Coke, we want to write a
 policy that says that only someone in the Pepsi admin role can change
 roles for Pepsi users (likewise for Coke).  We¹d want to write something
 likeŠ

 addRole(user, role) is permitted for caller if
 caller belongs to the Pepsi-admin role and
 user belongs to the Pepsi role

 The policy engine knows if ³caller belongs to the Pepsi-admin role²
 because that¹s part of the token.  But the policy engine doesn¹t know if
 ³user belongs to the Pepsi role² because user is just an argument to
 the API call, so we don¹t have role info about user.  This helps me
 understand *why* we can¹t handle the multi-customer use case right now:
 the policy engine doesn¹t have all the info it needs.

 But otherwise, it seems, we could handle the multi-customer use-case
 using mechanism that already exists.  Are there other examples where
 they can¹t write policy because the engine doesn¹t have enough info?


 Your simple example does not work in the federated case. This is because
 role and attribute assignments are not done by Keystone, or by any part
 of Openstack, but by a remote IDP. It is assumed that the administrator
 of this remote IDP knows who his users are, and will assign the correct
 attributes to them. However, these are not necessarily OpenStack roles
 (they most certainly wont be).

 Therefore, we have built a perfectly good mechanism into Keystone, to
 ensure that the users from any IDP (Coke, Pepsi or Virgin Cola etc.) get
 the right Keystone/Openstack role(s), and this is via attibute mapping.
 When the mapping takes place, the user is in the process of logging in,
 therefore Keystone knows the attributes of the user (assigned by the
 IDP) and can therefore know which Openstack role to assign to him/her.
 
 I understand the idea of mapping attributes from a remote IDP to
 OpenStack/Keystone roles.  But I don¹t understand the impact on my
 example.  In my example, the policy statement fails to work for one of 2
 reasons:
 
 1. there¹s no such thing as a Pepsi-admin role
 2. The policy engine can¹t check if ³user belongs to Pepsi
 
 The policy statement fails to work because of (2) for sure.  But are you
 saying it also fails to work because of (1) in the federated case?  I
 would have thought that the Keystone roles used to represent the Pepsi IDP
 attributes would be separate from the Keystone roles used to represent
 Coke IDP attributes, and therefore there¹s be some role corresponding to
 Pepsi-admin and Coke-admin.
 
 Sorry if this is obvious.
 
 Tim
 

 I hope this helps.

 regards

 David

 __
 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
 

__
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


Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc. - Role Assignment

2015-05-08 Thread Tim Hinrichs
Hi David,

See below.

On 5/7/15, 1:01 AM, David Chadwick d.w.chadw...@kent.ac.uk wrote:

Hi Tim

On 06/05/2015 21:53, Tim Hinrichs wrote:
 I wondered if we could properly protect the API call for adding a new
 Role using the current mechanism.  So I came up with a simple example.
 
 Suppose we want to write policy about the API call: addRole(user,
 role-name).  If we¹re hosting both Pepsi and Coke, we want to write a
 policy that says that only someone in the Pepsi admin role can change
 roles for Pepsi users (likewise for Coke).  We¹d want to write something
 likeŠ
 
 addRole(user, role) is permitted for caller if
 caller belongs to the Pepsi-admin role and
 user belongs to the Pepsi role
 
 The policy engine knows if ³caller belongs to the Pepsi-admin role²
 because that¹s part of the token.  But the policy engine doesn¹t know if
 ³user belongs to the Pepsi role² because user is just an argument to
 the API call, so we don¹t have role info about user.  This helps me
 understand *why* we can¹t handle the multi-customer use case right now:
 the policy engine doesn¹t have all the info it needs.
 
 But otherwise, it seems, we could handle the multi-customer use-case
 using mechanism that already exists.  Are there other examples where
 they can¹t write policy because the engine doesn¹t have enough info?
 

Your simple example does not work in the federated case. This is because
role and attribute assignments are not done by Keystone, or by any part
of Openstack, but by a remote IDP. It is assumed that the administrator
of this remote IDP knows who his users are, and will assign the correct
attributes to them. However, these are not necessarily OpenStack roles
(they most certainly wont be).

Therefore, we have built a perfectly good mechanism into Keystone, to
ensure that the users from any IDP (Coke, Pepsi or Virgin Cola etc.) get
the right Keystone/Openstack role(s), and this is via attibute mapping.
When the mapping takes place, the user is in the process of logging in,
therefore Keystone knows the attributes of the user (assigned by the
IDP) and can therefore know which Openstack role to assign to him/her.

I understand the idea of mapping attributes from a remote IDP to
OpenStack/Keystone roles.  But I don¹t understand the impact on my
example.  In my example, the policy statement fails to work for one of 2
reasons:

1. there¹s no such thing as a Pepsi-admin role
2. The policy engine can¹t check if ³user belongs to Pepsi

The policy statement fails to work because of (2) for sure.  But are you
saying it also fails to work because of (1) in the federated case?  I
would have thought that the Keystone roles used to represent the Pepsi IDP
attributes would be separate from the Keystone roles used to represent
Coke IDP attributes, and therefore there¹s be some role corresponding to
Pepsi-admin and Coke-admin.

Sorry if this is obvious.

Tim


I hope this helps.

regards

David

__
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


Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc. - Role Assignment

2015-05-07 Thread David Chadwick
Hi Tim

On 06/05/2015 21:53, Tim Hinrichs wrote:
 I wondered if we could properly protect the API call for adding a new
 Role using the current mechanism.  So I came up with a simple example.
 
 Suppose we want to write policy about the API call: addRole(user,
 role-name).  If we’re hosting both Pepsi and Coke, we want to write a
 policy that says that only someone in the Pepsi admin role can change
 roles for Pepsi users (likewise for Coke).  We’d want to write something
 like…
 
 addRole(user, role) is permitted for caller if 
 caller belongs to the Pepsi-admin role and
 user belongs to the Pepsi role
 
 The policy engine knows if “caller belongs to the Pepsi-admin role”
 because that’s part of the token.  But the policy engine doesn’t know if
 “user belongs to the Pepsi role” because user is just an argument to
 the API call, so we don’t have role info about user.  This helps me
 understand *why* we can’t handle the multi-customer use case right now:
 the policy engine doesn’t have all the info it needs.
 
 But otherwise, it seems, we could handle the multi-customer use-case
 using mechanism that already exists.  Are there other examples where
 they can’t write policy because the engine doesn’t have enough info?  
 

Your simple example does not work in the federated case. This is because
role and attribute assignments are not done by Keystone, or by any part
of Openstack, but by a remote IDP. It is assumed that the administrator
of this remote IDP knows who his users are, and will assign the correct
attributes to them. However, these are not necessarily OpenStack roles
(they most certainly wont be).

Therefore, we have built a perfectly good mechanism into Keystone, to
ensure that the users from any IDP (Coke, Pepsi or Virgin Cola etc.) get
the right Keystone/Openstack role(s), and this is via attibute mapping.
When the mapping takes place, the user is in the process of logging in,
therefore Keystone knows the attributes of the user (assigned by the
IDP) and can therefore know which Openstack role to assign to him/her.

I hope this helps.

regards

David

__
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


Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc.

2015-05-07 Thread Adam Young

On 05/06/2015 06:54 PM, Hu, David J (Converged Cloud) wrote:
david8hu One of the first thing we have to do is get all of our 
glossary straight J  I am starting to hear about “capability”.  Are we 
talking about “rule” in oslo policy terms? Or “action” in nova policy 
terms? Or this is something new.  For example, 
“compute:create_instance” is a “rule” in oslo.policy enforce(…) 
definition,  “compute:create_instance” is an “action” in nova.policy 
enforce(…) definition.


By capability, I ( think I ) mean  Action in Nova terms, as I am trying 
to exclude the internal rules that policy lets you define. However, to 
further muddy the water, you can actually enforce on one of these 
rules./  For example, the Keystone server enforces on admin_required  
for the V2 API.


The term capability has been thrown around a few times and I picked it 
up.  Really what I want to delineate is the point in the code at which  
policy gets enforced.
__
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


Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc.

2015-05-07 Thread Dolph Mathews
On Thursday, May 7, 2015, Adam Young ayo...@redhat.com wrote:

  On 05/06/2015 06:54 PM, Hu, David J (Converged Cloud) wrote:

 david8hu One of the first thing we have to do is get all of our glossary
 straight J  I am starting to hear about “capability”.  Are we talking
 about “rule” in oslo policy terms? Or “action” in nova policy terms? Or
 this is something new.  For example, “compute:create_instance” is a “rule”
 in oslo.policy enforce(…) definition,  “compute:create_instance” is an
 “action” in nova.policy enforce(…) definition.


 By capability, I ( think I ) mean  Action in Nova terms, as I am trying to
 exclude the internal rules that policy lets you define.  However, to
 further muddy the water, you can actually enforce on one of these rules./
 For example, the Keystone server enforces on admin_required  for the V2
 API.

 The term capability has been thrown around a few times and I picked it
 up.  Really what I want to delineate is the point in the code at which
 policy gets enforced.


I completely agree with Adam. Capabilities are the actions a user is
allowed to perform. But I'd rather talk in terms of authorized HTTP API
calls.

I've tossed around the idea of something like GET /capabilities where the
response included something analogous to a list of APIs where the user
(i.e. current token / authorization context) match the relevant policy
rules -- but implementing that concept in more than one service would be a
huge challenge.
__
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


Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc.

2015-05-06 Thread Hu, David J (Converged Cloud)
Nice summary Henry.  My comments in brown.


From: Adam Young [mailto:ayo...@redhat.com]
Sent: Tuesday, May 5, 2015 8:35 PM
To: openstack-dev@lists.openstack.org
Subject: Re: [openstack-dev] [keystone] On dynamic policy, role 
hierarchies/groups/sets etc.

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.

david8hu  We need at least one use case to capture or to tight all of the 
specs together.  I think an use case would really help the dynamic policy 
overview spec.  I can help add 1 or 2.


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 caller1) 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 
projectsand then those capabilities would be placed in the 
tokenallowing 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 setsand 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 
roleinstead 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 groupsand 
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.

david8hu  I can see per domain policy becoming a hot topic for the reseller 
scenario.

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

Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc.

2015-05-06 Thread Tim Hinrichs
Hi all,

Inline.

From: Adam Young ayo...@redhat.commailto:ayo...@redhat.com
Reply-To: OpenStack Development Mailing List (not for usage questions) 
openstack-dev@lists.openstack.orgmailto:openstack-dev@lists.openstack.org
Date: Tuesday, May 5, 2015 at 8:34 PM
To: 
openstack-dev@lists.openstack.orgmailto:openstack-dev@lists.openstack.org 
openstack-dev@lists.openstack.orgmailto:openstack-dev@lists.openstack.org
Subject: Re: [openstack-dev] [keystone] On dynamic policy, role 
hierarchies/groups/sets etc.

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.

Super helpful for sure!



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):
As I understand how this works conceptually, a policy makes go/no-go decisions 
based on two kinds of properties: (1) properties about the user making the API 
call  (which are encoded in the token) and (2) the API call name and arguments. 
  Is that right?


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

Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc.

2015-05-05 Thread Adam Young

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 

[openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc.

2015-05-05 Thread Henry Nash
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.

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 
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