<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 05/05/2015 07:05 AM, Henry Nash
      wrote:<br>
    </div>
    <blockquote cite="mid:34C577D2-C111-4B14-9AF2-338CAECC669A@mac.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      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.
      <div class=""><br class="">
      </div>
    </blockquote>
    This is a great summary.  Thanks Henry.<br>
    <br>
    <br>
    <blockquote cite="mid:34C577D2-C111-4B14-9AF2-338CAECC669A@mac.com"
      type="cite">
      <div class="">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.</div>
      <div class=""><br class="">
      </div>
      <div class="">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):</div>
      <div class=""><br class="">
      </div>
      <div class="">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.</div>
      <div class=""><br class="">
      </div>
      <div class="">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.</div>
      <div class=""><br class="">
      </div>
      <div class="">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 moz-do-not-send="true"
href="https://github.com/openstack/keystone/blob/master/etc/policy.v3cloudsample.json"
          class="">https://github.com/openstack/keystone/blob/master/etc/policy.v3cloudsample.json</a>).
        Adding more capability to this will likely only make the
        situation worse.</div>
      <div class=""><br class="">
      </div>
      <div class="">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:</div>
      <div class=""><br class="">
      </div>
      <div class="">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 moz-do-not-send="true"
          href="https://review.openstack.org/#/c/147651/" class="">https://review.openstack.org/#/c/147651/</a> and <a
          moz-do-not-send="true"
          href="https://review.openstack.org/#/c/133814/" class="">https://review.openstack.org/#/c/133814/</a> as
        examples.</div>
      <div class=""><br class="">
      </div>
      <div class="">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.</div>
      <div class=""><br class="">
      </div>
      <div class="">c) We have had competing suggestions for role
        sets/group/hierarchies (see: <a moz-do-not-send="true"
          href="https://review.openstack.org/#/c/125704/" class="">https://review.openstack.org/#/c/125704/</a> and <a
          moz-do-not-send="true"
          href="https://review.openstack.org/#/c/133855/" class="">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 </div>
    </blockquote>
    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>
    <blockquote cite="mid:34C577D2-C111-4B14-9AF2-338CAECC669A@mac.com"
      type="cite">
      <div class="">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.</div>
    </blockquote>
    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>
    <blockquote cite="mid:34C577D2-C111-4B14-9AF2-338CAECC669A@mac.com"
      type="cite">
      <div class=""><br class="">
      </div>
      <div class="">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”.</div>
    </blockquote>
    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>
    <blockquote cite="mid:34C577D2-C111-4B14-9AF2-338CAECC669A@mac.com"
      type="cite">
      <div class=""><br class="">
      </div>
      <div class="">Henry</div>
      <div class=""><br class="">
      </div>
      <div class=""><br class="">
      </div>
      <div class=""><br class="">
      </div>
      <div class=""><br class="">
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">__________________________________________________________________________
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: <a class="moz-txt-link-abbreviated" href="mailto:OpenStack-dev-request@lists.openstack.org?subject:unsubscribe">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a>
<a class="moz-txt-link-freetext" href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>