<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;
color:black;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0in;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New";
color:black;}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:Consolas;
color:black;}
span.EmailStyle19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body bgcolor="white" lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><span style="color:windowtext">Nice summary Henry. My comments in brown.<o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:windowtext"> Adam Young [mailto:ayoung@redhat.com]
<br>
<b>Sent:</b> Tuesday, May 5, 2015 8:35 PM<br>
<b>To:</b> openstack-dev@lists.openstack.org<br>
<b>Subject:</b> Re: [openstack-dev] [keystone] On dynamic policy, role hierarchies/groups/sets etc.<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On 05/05/2015 07:05 AM, Henry Nash wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
</blockquote>
<p class="MsoNormal">This is a great summary. Thanks Henry.<br>
<br>
<span style="color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><span style="color:windowtext">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.<o:p></o:p></span></span></p>
<p class="MsoNormal"><br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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):<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><span style="color:windowtext">david8hu> I can see “per domain policy” becoming a
hot topic for the reseller scenario.<o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal">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: <a href="https://github.com/openstack/keystone/blob/master/etc/policy.v3cloudsample.json">https://github.com/openstack/keystone/blob/master/etc/policy.v3cloudsample.json</a>).
Adding more capability to this will likely only make the situation worse.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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: <a href="https://review.openstack.org/#/c/147651/">https://review.openstack.org/#/c/147651/</a> and <a href="https://review.openstack.org/#/c/133814/">https://review.openstack.org/#/c/133814/</a> as
examples.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><span style="color:windowtext">david8hu> It is import that we have a robust and intuitive
interface (API, CLI, …etc) for administrators. We need to work on this from the start. I think we are building something great here. Don’t let the interface cripple the administrator experience
</span></span><span style="font-size:11.0pt;font-family:Wingdings;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><span style="color:windowtext">J</span></span><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal">c) We have had competing suggestions for role sets/group/hierarchies (see: <a href="https://review.openstack.org/#/c/125704/">https://review.openstack.org/#/c/125704/</a> and <a href="https://review.openstack.org/#/c/133855/">https://review.openstack.org/#/c/133855/</a> ).
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
<o:p></o:p></p>
</div>
</blockquote>
<p class="MsoNormal">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.<br>
<br>
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.<br>
<br>
<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">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.<o:p></o:p></p>
</div>
</blockquote>
<p class="MsoNormal">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.<br>
<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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”.<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><span style="color:windowtext">david8hu> One of the first thing we have to do is get
all of our glossary straight </span></span><span style="font-size:11.0pt;font-family:Wingdings;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><span style="color:windowtext">J</span></span><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#843C0C;mso-style-textfill-fill-color:#843C0C;mso-style-textfill-fill-alpha:100.0%"><span style="color:windowtext">
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.<o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></p>
</div>
</blockquote>
<p class="MsoNormal">That should work. In order for a user to get access to those new capabilites we'd have three choices:<br>
<br>
1. Add them to an existing role<br>
2. Add them to a new role and assign that new role as a subset of an existing role<br>
3. Add them to a new role and assign them to the user directly.<br>
<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Henry<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p class="MsoNormal"><br>
<br>
<br>
<o:p></o:p></p>
<pre>__________________________________________________________________________<o:p></o:p></pre>
<pre>OpenStack Development Mailing List (not for usage questions)<o:p></o:p></pre>
<pre>Unsubscribe: <a href="mailto:OpenStack-dev-request@lists.openstack.org?subject:unsubscribe">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><o:p></o:p></pre>
<pre><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><o:p></o:p></pre>
</blockquote>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>