<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 02/03/15 08:53, Dmitry Tantsur
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAAL3yRtMFkyhh0bwcmYhDPDSmvzyOyixGsU7rjF4A7pGHPbJdQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">2015-02-27 17:27 GMT+01:00 Dolph Mathews <span
          dir="ltr"><<a moz-do-not-send="true"
            href="mailto:dolph.mathews@gmail.com" target="_blank">dolph.mathews@gmail.com</a>></span>:<br>
        <div class="gmail_extra">
          <div class="gmail_quote">
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div dir="ltr">
                <div class="gmail_extra"><br>
                  <div class="gmail_quote">On Fri, Feb 27, 2015 at 8:39
                    AM, Dmitry Tantsur <span dir="ltr"><<a
                        moz-do-not-send="true"
                        href="mailto:dtantsur@redhat.com"
                        target="_blank">dtantsur@redhat.com</a>></span>
                    wrote:<br>
                    <blockquote class="gmail_quote" style="margin:0px
                      0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi
                      all!<br>
                      <br>
                      This (presumably) pretty basic question tortures
                      me for several months already, so I kindly seek
                      for help here.<br>
                      <br>
                      I'm working on a Flask-based service [1] and I'd
                      like to use Keystone tokens for authentication.
                      This is an admin-only API, so we need to check for
                      an admin role. We ended up with code [2] first
                      accessing Keystone with a given token and
                      (configurable) admin tenant name, then checking
                      'admin' role. Things went well for a while.<br>
                      <br>
                      Now I'm writing an Ironic driver accessing API of
                      [1]. Pretty naively I was trying to use an Ironic
                      service user credentials, that we use for
                      accessing all other services. For TripleO-based
                      installations it's a user with name 'ironic' and a
                      special tenant 'service'. Here is where problems
                      are. Our code perfectly authenticates a mere user
                      (that has tenant 'admin'), but asks Ironic to go
                      away.<br>
                      <br>
                      We've spent some time researching documentation
                      and keystone middleware source code, but didn't
                      find any more clues. Neither did we find a way to
                      use keystone middleware without rewriting half of
                      project. What we need is 2 simple things in a
                      simple Flask application:<br>
                      1. validate a token<br>
                      2. make sure it belongs to admin<br>
                    </blockquote>
                    <div><br>
                    </div>
                    <div>I'm not really clear on what problem you're
                      having, because I'm not sure if you care about an
                      "admin" username, "admin" tenant name, or "admin"
                      role name. If you're implementing RBAC, you only
                      really need to care about the user have an "admin"
                      role in their list of roles.</div>
                  </div>
                </div>
              </div>
            </blockquote>
            <div><br>
              Yeah, I guess that's what I need.<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    It's probably worth calling out that, the Keystone middleware itself
    doesn't have any concept of "admin" built in (and this is a good
    thing!). Your nova admins may be a totally different group of people
    to your Swift admins. Instead, the Keystone middleware will simply
    tell you the facts about the user/tenant making the API call, their
    username, tenant_id/project_id, the list of roles assigned to them
    etc. Given this information, most OpenStack projects use the oslo
    policy library to take this info, apply some rules, and then allow
    you to ask "Can the user perform action X?" rather than "Is this
    user an admin?".<br>
    <br>
    For a small internal project, this kind of flexibility may not
    matter, and it's certainly not required to use the KS middleware..
    But if you're trying to dig through the various projects codebase's
    to see how things are done, knowing this will help :)<br>
     <br>
    <blockquote
cite="mid:CAAL3yRtMFkyhh0bwcmYhDPDSmvzyOyixGsU7rjF4A7pGHPbJdQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div dir="ltr">
                <div class="gmail_extra">
                  <div class="gmail_quote">
                    <div><br>
                    </div>
                    <div>You can wrap your flask application with a
                      configured instance of auth_token middleware; this
                      is about the simplest way to do it, and this also
                      demos the environment variables exposed to your
                      application that you can use to validation
                      authorization:</div>
                    <div><br>
                    </div>
                    <div>  <a moz-do-not-send="true"
href="https://github.com/dolph/keystone-deploy/blob/master/playbooks/roles/http/templates/echo.py#L33-L41"
                        target="_blank">https://github.com/dolph/keystone-deploy/blob/master/playbooks/roles/http/templates/echo.py#L33-L41</a><br>
                    </div>
                  </div>
                </div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Thanks a lot, I will give it a try!<br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    If you happen to be using paste-deploy with Flask, Designate has
    some code that does just that.. <br>
    <br>
    We use a piece of WSGI Middleware[1] to read the info provided by
    the keystone middleware and attach it to the Request object for
    later use, and the api-paste.ini itself[2] to wire up the KS
    middleware, our KeystoneContextMiddleware" and the Flask app itself.<br>
    <br>
    [1]:
<a class="moz-txt-link-freetext" href="https://github.com/openstack/designate/blob/master/designate/api/middleware.py#L62-119">https://github.com/openstack/designate/blob/master/designate/api/middleware.py#L62-119</a><br>
    [2]:
<a class="moz-txt-link-freetext" href="https://github.com/openstack/designate/blob/master/etc/designate/api-paste.ini">https://github.com/openstack/designate/blob/master/etc/designate/api-paste.ini</a><br>
    <br>
    Good luck!<br>
    <br>
    Thanks,<br>
    Kiall<br>
  </body>
</html>