<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 14 (filtered medium)"><base href="x-msg://474/"><style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
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;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
span.apple-style-span
        {mso-style-name:apple-style-span;}
span.apple-converted-space
        {mso-style-name:apple-converted-space;}
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:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1132407901;
        mso-list-type:hybrid;
        mso-list-template-ids:1277851466 134807569 134807577 134807579 134807567 134807577 134807579 134807567 134807577 134807579;}
@list l0:level1
        {mso-level-text:"%1\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level5
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level8
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
@list l0:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></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 lang=EN-GB link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Hi Vish, <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><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Please see my comments inline.<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 style='border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=EN-US style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span lang=EN-US style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> Vishvananda Ishaya [mailto:vishvananda@gmail.com] <br><b>Sent:</b> 18 July 2011 17:36<br><b>To:</b> Salvatore Orlando<br><b>Cc:</b> Ziad Sawalha; openstack@lists.launchpad.net<br><b>Subject:</b> Re: [Openstack] OpenStack Identity: Keystone API Proposal<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Below:<o:p></o:p></p><div><p class=MsoNormal><o:p> </o:p></p><div><div><p class=MsoNormal>On Jul 18, 2011, at 3:28 AM, Salvatore Orlando wrote:<o:p></o:p></p></div><p class=MsoNormal><br><br><o:p></o:p></p><div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Hi,</span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'> </span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>I’m jumping in this thread to understand whether there’s a chance KeyStone can implement some use cases around the concept of object ownership.</span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>I apologise if this email turns out to be a bunch of nonsense; unfortunately I don’t have a strong AAA background<span class=apple-converted-space> </span></span><span style='font-size:11.0pt;font-family:Wingdings;color:#1F497D'>J</span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>.</span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'> </span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>As pointed out several times in this thread, this is something which should be enforced in the service: once a request comes in, the AA middleware validates the token and retrieves user identity with Keystone, using it to verify whether the user owns the objects on which the request operates.</span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>However, sometimes requests operate on objects defined in different services; for instance in the Quantum service (L2 networking), the operation for plugging an interface on a port operate on the following resources:</span><o:p></o:p></p></div><div style='margin-left:36.0pt'><p class=MsoNormal style='text-indent:-18.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>-</span><span style='font-size:7.0pt;color:#1F497D'>         <span class=apple-converted-space> </span></span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>The network and the port, defined in quantum</span><o:p></o:p></p></div><div style='margin-left:36.0pt'><p class=MsoNormal style='text-indent:-18.0pt'><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>-</span><span style='font-size:7.0pt;color:#1F497D'>         <span class=apple-converted-space> </span></span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>The interface being plugged, defined in nova</span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>The AA middleware needs to verify that the user ‘owns’ all these resources, in order to ensure, for instance, that a tenant does not plug another tenant’s interface in his own network.</span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>As this process involves resources defined in two distinct services, I was wondering whether Keystone could help in any way, by exposing APIs for registering/unregistering/listing object ownership relationships.</span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>These relationships could be stored in the form <service-name>:<object-uuid> and associated to the appropriate Keystone object, tenant or user. AA middleware in services such as Quantum could query Keystone for the list of objects owned by a given user/tenant in a service or for establishing whether a user/tenant owns specific object(s).</span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'> </span><o:p></o:p></p></div><div><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Would it be reasonable to expect to have something like that in Keystone?</span><o:p></o:p></p></div></div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Object ownership is a bit of a nebulous concept.  Instead each service should define particular actions. For example:<o:p></o:p></p></div><div><p class=MsoNormal><role> can_attach_port <port_id><o:p></o:p></p></div><div><p class=MsoNormal><role> can_plug_interface <interface><o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>The system can go through and do checks on each particular action in the context of a subject (role), predicate (action), and object (object).  In my mind, the most bang for the buck is to think of the subject as a role (or list of roles).<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></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>In this model, authn is responsible for mapping a token to user / tenant / roles and authz is responsible for mapping roles / actions / objects.<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:#1F497D'>Agreed. A model where authZ is defined in terms of  <subject><predicate><object> rules is where we ultimately want to end up. <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>Now it is possible to define some shared cases where your authz mapping could use wildcard matching.  For example<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>*, can_attach_port, 75 -> any role can attach to port 75<o:p></o:p></p></div><div><p class=MsoNormal>admin, can_plug_interface, * -> an admin can plug into any interface.<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></div><div><p class=MsoNormal>You can create more control by allowing the authz system to group objects in the same way that roles can "group" tenants, for example:<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>big_tenant, can_attach_ports, (owned_by_big_tenant) -> allow anyone with the big_tenant role to attach to any port owned by big_tenant<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:#1F497D'>If I get your last example correctly, “(owned_by_big_tenant)” is something that should be enforced in the authZ middleware for the service. Which is fine in many cases, and it should work even for the use case I was mentioning (plugging interface into Quantum networks). <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>However, IMHO this kind of use case is a bit more convoluted, as the user/tenant/role mapped to the auth token needs to satisfy both a predicate for the interface (likely to be defined in nova) and the network (defined in quantum), so the rules should be something like: <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><p class=MsoListParagraph style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><span style='mso-list:Ignore'>1)<span style='font:7.0pt "Times New Roman"'>      </span></span></span><![endif]><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>nova: tenant_X_user, can_manage_interface, {<interface-id> | *}<o:p></o:p></span></p><p class=MsoListParagraph style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><span style='mso-list:Ignore'>2)<span style='font:7.0pt "Times New Roman"'>      </span></span></span><![endif]><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>quantum: tenant_X_user, can_plug_interface, {<network-id> | *}<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><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>If the identity service would provide a way to manage this rules, then the authZ middleware for the specific service could implement the logic for enforcing them, without having to query other services for deciding whether a user/tenant is authorized to perform an operation or not.  I think Ziad’s proposal for service-specific roles goes into this direction. <o:p></o:p></span></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>"ownership" is an implicit grouping of objects by "owner".  The most general case would allow objects to be grouped in arbitrary ways, but I think the majority of use cases are solved by allowing very specific grouping according to owner_id<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>This is how we implemented it in the authn / authz branch of many moons ago, and it seemed to provide enough flexibility.<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:#1F497D'>Are you referring to the authN/authZ middleware which is now part to the Openstack API? In that case I could use this as a reference for implementing our middleware.<o:p></o:p></span></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Vish<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><o:p> </o:p></p></div></div></div></body></html>