<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1250">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; font-size: 14px; font-family: Calibri, sans-serif; color: rgb(0, 0, 0); ">
<div style="color: rgb(0, 0, 0); ">Hi Paul - </div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">A few of these items I would like to take offline.</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">See responses below for the others…</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">On 11/26/11 11:45 AM, "Paul Querna" <<a href="mailto:pquerna@apache.org">pquerna@apache.org</a>> wrote:</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div>On Thu, Nov 24, 2011 at 9:10 AM, Ziad Sawalha</div>
<div><<a href="mailto:ziad.sawalha@rackspace.com">ziad.sawalha@rackspace.com</a>> wrote:</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>Hi Paul - thank you for the good feedback.</div>
<div><br>
</div>
<div>I'm going to address your points individually below, but before I want to</div>
<div>to set some context and address some of your broader concerns.</div>
<div><br>
</div>
<div>The 2.0 API for Keystone is released and multiple implementers are already</div>
<div>working on it (in fact, we at Rackspace have just released ours). There</div>
<div>were many calls for comments on the API throughout the year, but we locked</div>
<div>down the spec finally in September to try to deliver an implementation in</div>
<div>time for Diablo.</div>
</blockquote>
<div><br>
</div>
<div>Sorry I couldn't be more involved earlier in the process earlier, we</div>
<div>had many other projects to get done before we were worried about</div>
<div>looking into Keystone integration.  I hope my feedback is helpful as</div>
<div>(one of the first?) non-core integrations with Keystone.</div>
</blockquote>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">We've added a lot more documentation on integration (and more to come) - you can see much of it here: http://keystone.openstack.org. We would be happy to be directly involved in helping you out with Keystone integration (including
 adding functionality or new APIs if needed). Please let us know what you need.</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<div>... snip ...</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>A) The Token Validation API is fail deadly, because of support for</div>
<div>Tokens without a Tenant ID scope:</div>
<div><br>
</div>
<div><br>
</div>
<div><<a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/GET_">http://docs.openstack.org/api/openstack-identity-service/2.0/content/GET_</a></div>
<div>validateToken_v2.0_tokens__tokenId__Admin_API_Service_Developer_Operations</div>
<div>-d1e1356.html></div>
<div><br>
</div>
<div>When you are implementing a service that needs to validates tokens,</div>
<div>you pass in the tenant scope as the belongsTo parameter with the</div>
<div>Tenant ID.  However, this parameter is optional.  If a malicious</div>
<div>Tenant Id is passed in, for example if a service doesn't perform</div>
<div>sufficient validation, like letting a user pass in a & into the</div>
<div>tenantId, a token is considered valid for _all_ contexts.  Now, in</div>
<div>theory, you should be looking at the roles provided under the user,</div>
<div>and the examples given in the OpenStack documentation echo back the</div>
<div>validated Tentant ID to you, however in practice, and as seen in</div>
<div>production environments, this response body includes a default</div>
<div>identity role, and does not echo back the validated Tenant ID.</div>
</blockquote>
<div><br>
</div>
<div>Tokens without scope are supported by the API - we had requests with use</div>
<div>cases for it - but it is not required. In fact, the Rackspace</div>
<div>implementation always returns a scoped token.</div>
</blockquote>
<div><br>
</div>
<div>Maybe I am misunderstanding what you mean here by scopped token -- in</div>
<div>the Rackspace production implementation, belongsTo is optional.  If</div>
<div>belongsTo isn't present, isn't that an unscopped token?</div>
<div><br>
</div>
<div>I really wish that the validate token call would echo back the</div>
<div>tenantIds that the token is valid for to the validator.  This would</div>
<div>enable validators to ensure both their parsing of the tenantId and</div>
<div>that of Keystone was the same.</div>
</blockquote>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">belongsTo is just a method for validation. It does not determine if a token is scoped or not. Generally, if you do a check with belongsTo on an unstopped token it should fail with a 401 Unauthorized. If that's not the behavior
 you are seeing let us know; it might be a bug.</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">Whether a token is scoped or not is determined when a user authenticates. Here are the combinations:</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">1. If a user supplies a tenant when authenticating, they should get a token scoped to that tenant. A check with belongsTo where the value is anything but that tenant should fail.</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">2. A user does not supply a tenant and they get an unscoped token. That's how Keystone should behave. I say should because we've been working hard to undo a concept that was introduced earlier this year called a default tenant.
 The default tenant concept gives you back a scoped token always. We decided to undo that late before the Diablo release, but there are deployments of the code out there that already have that and removing it from our code without breaking compatibility has
 been a challenge. We have in review in progress to remove that: https://review.openstack.org/#change,1068</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">3. A user does not supply a tenant and they get back a scoped token. That's how Rackspace Auth works and how Keystone behaves if default tenant is set. The difference between Rackspace and Keystone is that Rackspace scopes
 your token to two tenants by default. Keystone only supports scoping to one tenant at a time.</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">We have some sequence diagrams to describe these (attached). They've been merged into trunk but don't show up on the OpenStack docs site yet. I'll check on that with the doc team.</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div style="color: rgb(0, 0, 0); ">The validate call does echo back the tenants the token is scoped to. Here's the response:</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<div>
<div>
<div style="color: rgb(0, 0, 0); ">{</div>
<div style="color: rgb(0, 0, 0); ">    "access": {</div>
<div style="color: rgb(0, 0, 0); ">        "token": {</div>
<div style="color: rgb(0, 0, 0); ">            "expires": "2012-02-05T00:00:00", </div>
<div style="color: rgb(0, 0, 0); ">            "id": "887665443383838", </div>
<div><b><font class="Apple-style-span" color="#ff0000">            "tenant": {</font></b></div>
<div><b><font class="Apple-style-span" color="#ff0000">                "id": "1", </font></b></div>
<div><b><font class="Apple-style-span" color="#ff0000">                "name": "customer-x"</font></b></div>
<div><b><font class="Apple-style-span" color="#ff0000">            }</font></b></div>
<div style="color: rgb(0, 0, 0); ">        }, </div>
<div style="color: rgb(0, 0, 0); ">        "user": {</div>
<div style="color: rgb(0, 0, 0); ">            "id": "1", </div>
<div style="color: rgb(0, 0, 0); ">            "name": "joeuser", </div>
<div style="color: rgb(0, 0, 0); ">            "roles": [</div>
<div style="color: rgb(0, 0, 0); ">                {</div>
<div style="color: rgb(0, 0, 0); ">                    "id": "3", </div>
<div style="color: rgb(0, 0, 0); ">                    "name": "Member", </div>
<div style="color: rgb(0, 0, 0); ">                    "serviceId": "1"</div>
<div style="color: rgb(0, 0, 0); ">                }</div>
<div style="color: rgb(0, 0, 0); ">            ], </div>
<div style="color: rgb(0, 0, 0); ">            "tenantId": "1", </div>
<div style="color: rgb(0, 0, 0); ">            "tenantName": "customer-x", </div>
<div style="color: rgb(0, 0, 0); ">            "username": "joeuser"</div>
<div style="color: rgb(0, 0, 0); ">        }</div>
<div style="color: rgb(0, 0, 0); ">    }</div>
<div style="color: rgb(0, 0, 0); ">}</div>
</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
</div>
<div style="color: rgb(0, 0, 0); "><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<div>... snip ...</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>B) Requiring consumers to pass Tenant IDs around is not a common</div>
<div>pattern in other cloud APIs.  A consumer was already keeping track of</div>
<div>their username, apikey, and temporal token, and now they essentially</div>
<div>need to keep another piece of information around, the Tenant ID.</div>
<div>This seems like it is an unneeded variable.  For example, Amazon</div>
<div>implements AWS Identity and Access Management by changing the API key</div>
<div>& secret that is used against the API depending on the role of the</div>
<div>account -- this hides the abstraction away from both client libraries</div>
<div>and validating services -- they still just care about the API key and</div>
<div>secret, and do not need to pass around an extra Tenant ID.</div>
</blockquote>
<div><br>
</div>
<div>This sounds like a concern with the OpenStack implementation and not the</div>
<div>API spec.</div>
<div><br>
</div>
<div>The Keystone API spec doesn't require consumers to pass Tenant IDs around.</div>
<div>It even allows for a full implementation without the consumer having to</div>
<div>know or manage their tenant IDs. We've done that at Rackspace where you</div>
<div>auth with your credentials, get URLs back for the services you have, and</div>
<div>then you call those URLs using your token. Granted, the tenant ID (a.k.a</div>
<div>account numbers) is embedded in the URL, but this comes from the Rackspace</div>
<div>Cloud Servers and Swift API and is not a Keystone API design requirement.</div>
<div><br>
</div>
<div>Can you give an example of where you are having to maintain tenant IDs?</div>
</blockquote>
<div><br>
</div>
<div>Consumers do, because as a client language API consumer, none of the</div>
<div>services I need to access are actually in the Service Catalog.</div>
<div>Things like staging, beta, and even production services are not listed</div>
<div>in the Service Catalog, so I need to extract out the tenant Id, and</div>
<div>then munge it onto a base url supplied by the user.</div>
</blockquote>
<div><br>
</div>
<div>
<div>I'm confused by this. You say "none of the services I need to access are actually in the Service Catalog." Why is that? What's stopping you from registering your services in the catalog? (see latest docs on doing that in the attached PDF).</div>
</div>
<div><br>
</div>
<div>Note also that endpoints contain a tenantId attribute PRECISELY so you don't have to parse it out of the URL.</div>
<div><br>
</div>
<div>I think I need more data on which Keystone-compatible server you are calling, what your relationship is to it and the operator, and what's the data you expect to get out of it. You may have a unique use case we may not have covered. If so, we can work
 on getting that covered.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<div>On Services: How would a service implement authentication of a user</div>
<div>for a tenant without either burning that tenant ID into the URL, or</div>
<div>requiring the consumer to pass in an X-Tenant-Id header?  With the</div>
<div>current token structure you must somehow pass this to the service --</div>
<div>otherwise the only thing the service can assert is that a Username has</div>
<div>a Valid token -- it cannot tell what tenant(s) it is valid for,</div>
<div>because a single token spans multiple tenants.</div>
</blockquote>
<div><br>
</div>
<div>As long as the service receives a token scoped to a tenant, it can find that tenant out from Keystone.</div>
<div><br>
</div>
<div>Here's the call the service would make:</div>
<div><span class="Apple-tab-span" style="white-space: pre; font-family: Courier; ">$ curl -H "X-Auth-Token: 999888777666" http://localhost:35357/v2.0/tokens/887665443383838</span></div>
<div><br>
</div>
<div>Note, the service only knows where the Keystone server is and how to authenticate to it. And the token from the user (no tenant).</div>
<div><br>
</div>
<div>The response has the tenant ID in it:</div>
<div>
<div>{</div>
<div>    "access": {</div>
<div>        "token": {</div>
<div>            "expires": "2012-02-05T00:00:00", </div>
<div>            "id": "887665443383838", </div>
<div><b><font class="Apple-style-span" color="#00970a">            "tenant": {</font></b></div>
<div><b><font class="Apple-style-span" color="#00970a">                "id": "1", </font></b></div>
<div><b><font class="Apple-style-span" color="#00970a">                "name": "customer-x"</font></b></div>
<div><b><font class="Apple-style-span" color="#00970a">            }</font></b></div>
<div>        }, </div>
<div>        "user": {</div>
<div>            "id": "1", </div>
<div>            "name": "joeuser", </div>
<div>            "roles": [</div>
<div>                {</div>
<div>                    "id": "3", </div>
<div>                    "name": "Member", </div>
<div>                    "serviceId": "1"</div>
<div>                }</div>
<div>            ], </div>
<div>            "tenantId": "1", </div>
<div>            "tenantName": "customer-x", </div>
<div>            "username": "joeuser"</div>
<div>        }</div>
<div>    }</div>
<div>}</div>
</div>
<div><br>
</div>
<div>So neither the service or the consumer need to know or pass the tenant around.</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>C) Requiring Services to encode the Tenant ID into their URLs is not a</div>
<div>common design, and can cause issues.  By encoding identity both into</div>
<div>the Token and the Tenant in the URL, there are now multiple attack</div>
<div>vectors from a security perspective, and can make URL routing in some</div>
<div>frameworks more painful.</div>
</blockquote>
<div><br>
</div>
<div>As I mention above, that's not a Keystone requirement and was not driven</div>
<div>by Keystone. As user who has multiple accounts myself I find the model</div>
<div>works for me, but it is certainly not forced or required upon services in</div>
<div>order to work with Keystone.</div>
<div><br>
</div>
<div>I know that much thought went into that design taking into consideration</div>
<div>things like rate limiting, caching, etcŠ</div>
<div><br>
</div>
<div>This is probably a broader OpenStack API conversation. Fair warning, those</div>
<div>conversations have historically lead to bike and blood shedding :-)</div>
</blockquote>
<div><br>
</div>
<div>I don't understand the assertion that rate limiting or caching have to</div>
<div>do with the URL structure in this case.  For example with caching,</div>
<div>you'll want to Vary on X-Auth-Token regardless, as a user may have</div>
<div>different roles inside the same Tenant.  If a URL was cached solely</div>
<div>based on tenantId, a user with a more restrictive role (granted, this</div>
<div>doesn't quite exist in OpenStack yet?), could view content they</div>
<div>shouldn't have access to.</div>
</blockquote>
<div><br>
</div>
<div>I'll connect you with someone who knows more about this than I to continue the conversation.</div>
<div><br>
</div>
<div>But from a Keystone perspective, this is not required (per the previous example).</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>D) The Service Catalog makes it difficult to run testing, beta, and</div>
<div>staging environments.  This is because in practice many services are</div>
<div>not registered in the service catalog.  To work around this, we</div>
<div>commonly see that a regex is used to extract the Tenant Id from</div>
<div>another URL, and then the client builds a new URL.  You can see this</div>
<div>even being recommended by Rackspace in the Disqus comments ont he</div>
<div>Cloud DNS API here:</div>
<div><<a href="http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/Service_Acc">http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/Service_Acc</a></div>
<div>ess_Endpoints-d1e753.html></div>
</blockquote>
<div><br>
</div>
<div>Is the problem "in practice many services are not registered in the</div>
<div>service catalog"?</div>
<div><br>
</div>
<div>I'm wondering if we need to make it easier for services to register</div>
<div>themselves in the catalog or evolve the service catalog to handle use</div>
<div>cases like staging, beta, and testing environments?</div>
</blockquote>
<div><br>
</div>
<div>Yes, this is a huge integration problem right now in both Reach and</div>
<div>$UnannoucnedProduct.  For $UnannoucnedProduct our welcome packet is</div>
<div>going to tell Users to Regex out their TenantId out of the Compute</div>
<div>URL.  I don't see an alternative right now.</div>
</blockquote>
<div><br>
</div>
<div>We can do this. This is a Rackspace conversation so I'll follow up with you offline.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<div>For Reach we had to put in the ex_force_base_url feature to Apache</div>
<div>Libcloud, to ignore the URLs returned by the Service Catalog, because</div>
<div>they never contain the endpoints actually used by Reach.</div>
<div><br>
</div>
<div>... snip ...</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>E) The Service catalog should make it easy to expose many tenants to</div>
<div>the same service.  Currently you need to build a unique tentant</div>
<div>specific URL for each service.   The most common use case is enabling</div>
<div>all or a large set of tenants to access the same service, and it seems</div>
<div>like this use case is not well covered.</div>
</blockquote>
<div><br>
</div>
<div>I'm not sure I get the pain point you have here, but I can talk to the</div>
<div>Keystone API aspect of this.</div>
<div><br>
</div>
<div>Given that Keystone has support for services that want to embed a tenant</div>
<div>in their URL (as well as those that don't), the spec includes a definition</div>
<div>of the service catalog that doesn't assume either. All the catalog focuses</div>
<div>on is providing endpoints and data about each endpoint.</div>
<div><br>
</div>
<div>Are you asking specifically for support to return one endpoint and have a</div>
<div>list of tenants that</div>
<div>can exist under that endpoint? Something like this:</div>
<div><br>
</div>
<div><br>
</div>
<div>"serviceCatalog":[{</div>
<div>       "name":"Cloud Servers",</div>
<div>       "type":"compute",</div>
<div>       "endpoints":[{</div>
<div>               "publicURL":"<a href="https://compute.north.host.com/v1/">https://compute.north.host.com/v1/</a>",</div>
<div>               "tenants": ["t1000", "t2000", "t3000", etc...]</div>
<div>               }]</div>
<div><br>
</div>
<div><br>
</div>
<div>It can be done. We've seen (and as you pointed out) the usability</div>
<div>decreases with the number of use cases we support. For example, that use</div>
<div>case above would not work for anyone using tenants in their URLs, so</div>
<div>they;d be limited to one tenant in the array and someone could feasibly</div>
<div>complain about having to put one tenant in an array every time.</div>
<div><br>
</div>
<div>But if this is a needed use case for consumers it can be done.</div>
<div><br>
</div>
<div>The process we would follow be be to add it as an extension (since the</div>
<div>core API is released) and f it gains traction, propose it for core in the</div>
<div>next API. The next API will likely be a topic brought up in the next</div>
<div>summit in April.</div>
</blockquote>
<div><br>
</div>
<div>No, this isn't really what I would like.</div>
<div><br>
</div>
<div>On the Consumer side: I would like a Token per Tenant.  Under each</div>
<div>tenant is the list of known service urls.  Preferably I never have to</div>
<div>concat a tenant ID onto an alpha/beta/staging URL.</div>
<div><br>
</div>
<div>On the Validation side: I would really like there to be a mapping of</div>
<div>Tokens -> Single Tenant.  And when I validate that token, I don't need</div>
<div>another parameter with the belongsTo, it returns to me the single</div>
<div>tenant and roles this token is valid for.</div>
</blockquote>
<div><br>
</div>
<div>The single token per tenant is available in Keystone. If you're looking for this in Rackspace Auth we can that conversation offline as well.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>F) Features like API Keys, are marked as Extensions to the API, and</div>
<div>not part of the core API.</div>
</blockquote>
<div><br>
</div>
<div>Correct. We asserted that all the backends we would support (and that</div>
<div>operators of OpenStack would be running) have support for passwords. Not</div>
<div>all backends have support for API Keys, though. If API Keys go into the</div>
<div>core API they would need to be supported by all implementers and that</div>
<div>raises the bar to deploying OpenStack in some enterprises.</div>
<div><br>
</div>
<div>Example: say Rackspace wants to deploy OpenStack internally for employee</div>
<div>use and wants to integrate it with an enterprise directory running LDAP.</div>
<div>Password authentication is a simple tie in. If we also had to find a way</div>
<div>to support issuing employees API keys, that becomes a much more complex</div>
<div>project. As most enterprise directories don't support API keys natively.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div><br>
</div>
<div><br>
</div>
<div>G) Support for multifactor authentication (MFA) is not currently</div>
<div>available in any way.  This is very worrisome since the only 'in core'</div>
<div>Authentication mechanism is a username and a password.  With previous</div>
<div>systems, where the Username and Password were not 'owned' by a service</div>
<div>like Keystone, products like the control panel could implement MFA</div>
<div>themselves, but now that you can authenticate to the backend APIs</div>
<div>using only a password, Keystone must also support MFA.   Password Auth</div>
<div>is very different from API Key auth -- yes, they are both in theory</div>
<div>randomly generated and big, but in practice Passwords are weak, and</div>
<div>reused widely, while only API keys are big and random.</div>
</blockquote>
<div><br>
</div>
<div>Same argument as above. The extension mechanism is robust and would allow</div>
<div>any operator to add an MFA extension and offer that to their customers.</div>
<div>Putting it in core would make the prerequisites for deploying OpenStack</div>
<div>heavy.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div><br>
</div>
<div><br>
</div>
<div>H) There doesn't seem to be an open discussion about where the</div>
<div>Keystone API is going -- I hear mumbles about $OtherBigCompanies</div>
<div>wanting to extend the Keystone APIs in various ways, but there is no</div>
<div>discussion on this mailing list.  I know of at least 4 implementations</div>
<div>of Keystone within just Rackspace, but all of them are adding custom</div>
<div>extensions to even accomplish their baseline of use cases.</div>
</blockquote>
<div><br>
</div>
<div>Correct. As I mentioned initially, all the focus now is on documenting and</div>
<div>stabilizing.</div>
<div><br>
</div>
<div>There are blueprints out there and work being done on extensions which</div>
<div>will "show up". IMO, that's a sign of an active community and evidence</div>
<div>that the extension mechanism allows people to work on their features and</div>
<div>evolve the domain without having to drive the core project one way or the</div>
<div>other or be gated by others.</div>
<div><br>
</div>
<div>The four implementations within Rackspace is a testament to the level of</div>
<div>innovation going on. My expectation is that the implementation that best</div>
<div>serves our customers will prevail and the learnings should feed back into</div>
<div>the Keystone API to continue evolving it.</div>
</blockquote>
<div><br>
</div>
<div>Multiple implementations and extensions less than 6 months into the</div>
<div>existence of the API to me is a sign that the base API and reference</div>
<div>implementation is not suitable anyone's needs.  If no one can use the</div>
<div>reference implementation without any extensions in a production</div>
<div>environment then we are doing something wrong.</div>
</blockquote>
<div><br>
</div>
<div>I disagree. The implementations all work fully without the need for extensions. Extensions exist to support features that exist only in one implementation and to expose features not in the core API but proposed for future use cases or use cases that were
 not incorporated when we developed the API.</div>
<div><br>
</div>
<div>The multiple extensions speaks to the dynamic community debate going on the direction we should take that API. And the fact theta all the extensions can coexist is a testament to the work that went into the extension mechanism to support that ecosystem.</div>
<div><br>
</div>
<div>The proliferation of extensions is by design and intent. The fact that the extensions allow the dynamic change while providing a stable, predictable contract that can be coded to for core functionality means they are achieving their design goal.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<div>It seems we either missed too many base use cases, and/or that</div>
<div>something is seriously wrong with the reference implementation.  The</div>
<div>reference implementation doesn't need to be everything to everyone,</div>
<div>but it should be a reasonable default that even large providers are</div>
<div>comfortable using in production -- but that doesn't seem to be the</div>
<div>case at all.</div>
</blockquote>
<div><br>
</div>
<div>We did intentionally set aside many use cases. The goal for Diablo was to get Keystone in OpenStack Core and support only existing use cases. The extension mechanism is what is allowing us to deliver on new use cases without modifying the Keystone 2.0
 API. We will continue delivering new functionality that way and based on feedback and success of extensions, we will derive the 3.0 API.</div>
<div><br>
</div>
<div>Meanwhile, if you have use cases that were not solved for we can deliver them either through addinging additional functionality within the API or providing an extension.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>Part 2: My Thoughts / Recommendations</div>
<div><br>
</div>
<div><br>
</div>
<div>A) More open discussion about the issues in Keystone.  Issues won't</div>
<div>get fixed until there is an open and honest dialog between the various</div>
<div>groups which depend on Keystone.  Identity, Authentication and</div>
<div>Authorization must be rock solid -- everything else in OpenStack and</div>
<div>many other commercial products are built upon it.</div>
</blockquote>
<div><br>
</div>
<div>I fully support that. Thank you for driving it. There are a number of</div>
<div>threads and items you bring up here that I think could and should drive</div>
<div>blueprints and new features.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div><br>
</div>
<div><br>
</div>
<div>B)  I believe fundamentally that the data model for service catalogs</div>
<div>as exposed to the user is over complicated and broken.  I would prefer</div>
<div>that you hit the auth service with your username + apikey or password.</div>
<div>This returns to you a list of tenantIds aka billable cloud accounts.</div>
<div>Each of those records have a unique API Token. When you hit a service</div>
<div>using that Token, you do not include a TenantId. The service validates</div>
<div>the token, and its always in the context of a single tenant.</div>
<div><br>
</div>
<div>I believe we should consider changing the get Token API to return</div>
<div>something more like this:</div>
<div><br>
</div>
<div> {access: [</div>
<div>       {tenantId: "42",</div>
<div>        token: 'XXXXXX',</div>
<div>        serviceCatalog: [{type: 'compute', baseURL: '<a href="https://..../">https://..../</a>',</div>
<div>region: 'us-west'} ... ]</div>
<div>       }]};</div>
<div>The major change here is to make tenants a first level object, instead</div>
<div>of being a component of the service catalog --  each tenant has their</div>
<div>potentially unique service catalog, and each tenant has a unique API</div>
<div>token that is valid for this users's roles on it.</div>
</blockquote>
<div><br>
</div>
<div>We intentionally made the API token centric (other standards like OAUTH</div>
<div>and SAML have come to that conclusion). That's the most flexible model.</div>
<div>For example, Rackspace has at least two tenants for each customer (cloud</div>
<div>files and cloud servers). We don't want to force customers to have</div>
<div>separate tokens for each. Your proposal would force us to do that.</div>
</blockquote>
<div><br>
</div>
<div>This could be accomplished inside Rackspace by merging their 'two'</div>
<div>tenant Ids. This wouldn't actually be that complicated, because we</div>
<div>could easily add an cloudFilesLegacyId to the validate token response.</div>
<div>If we are already requiring services to migrate to the Keystone API,</div>
<div>them needing to reference a specific variable for their legacy needs</div>
<div>would be a small price to pay, and would eliminate the need for</div>
<div>scopeless tokens.</div>
</blockquote>
<div><br>
</div>
<div>That's an internal Rackspace conversation. Let's take offline.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div>The current spec lets our customers manage only one token and we, as an</div>
<div>operator, can decide what goes in the token. That's what we were solving</div>
<div>for. Maybe there's a simpler model for the service catalog, but I haven't</div>
<div>seen it yet. But a good topic to keep iterating on.</div>
<div><br>
</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div><br>
</div>
<div>This would slightly complicate "service users" with access to many</div>
<div>tenants, but it would massively simplify the common use cases of a</div>
<div>user with a small number of tenants, and for a service which needs to</div>
<div>validate the token.  A service user with access to many tenants would</div>
<div>need to fetch a unique token for each tenant, but this is the place to</div>
<div>put the complexity -- people writing a service that spans hundreds or</div>
<div>thousands of tenants are already doing something complicated --</div>
<div>fetching a unique auth token is the least of their issues.</div>
<div><br>
</div>
<div>This reduces the number of variables on both the consumer and the</div>
<div>service for passing around, and makes it less fail-deadly.</div>
<div><br>
</div>
<div>This approach also eliminates the need to encode the tenant ID into</div>
<div>the URLs of services.</div>
<div><br>
</div>
<div><br>
</div>
<div>C) There needs to be a reduction in the number of implementations of</div>
<div>Keystone, and a reduction in the number of extensions needed to even</div>
<div>operate a reasonable baseline of services.   More things, like API</div>
<div>keys and how one would do a multifactor authentication backend must be</div>
<div>part of the core specification, and we should strive to have the</div>
<div>reference implementation actually used by companies in the ecosystem,</div>
<div>instead of how today pretty much every $BigCo using OpenStack is</div>
<div>implementing their own Keystone service from scratch -- people will</div>
<div>always have custom needs, but those should be plugins to a solid</div>
<div>reference implementation as much as possible, instead of today where</div>
<div>everyone is rebuilding it from scratch.</div>
<div><br>
</div>
</blockquote>
<div><br>
</div>
<div>We can do better, yes. And we can hope to settle towards one</div>
<div>implementation. There's a world of identity solutions out there and we</div>
<div>didn't start Keystone to enter that market, but to enable easier</div>
<div>integration in a cloud paradigm.</div>
<div><br>
</div>
<div>And not everyone is going to want to run a Python identity server. We've</div>
<div>split the API spec from the implementation to allow for diversity.</div>
</blockquote>
<div><br>
</div>
<div>Generic-ism and Diversity is helpful once the problem space is well</div>
<div>understood.  I don't believe the space in which Keystone lives is</div>
<div>actually well worn.   The space of Cloud Service Identity,</div>
<div>authentication, authorization and token management on a whole is still</div>
<div>much younger than Identity on the web -- and Identity on the web in</div>
<div>general is still a mess.</div>
</blockquote>
<div><br>
</div>
<div>I agree. The space is not mature or easy to navigate. We've been taking a very pragmatic approach while balancing more stakeholders than most are aware of. If we've erred to far away from the side of usability, we can adjust. But I believe one of the biggest
 gaps we have had is in documentation and education around what the API provides and what Keystone (and other implementations) provide.</div>
<div><br>
</div>
<div>We've been heavily focused on remedying that.</div>
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="BORDER-LEFT: #b5c4df 5 solid; PADDING:0 0 0 5; MARGIN:0 0 0 5;">
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div>Thoughts?</div>
</blockquote>
<div><br>
</div>
<div>Thank you again, Paul. Good topics. And please keep the discussion going.</div>
<div>I'd be happy to continue on this thread and also to work with anyone on</div>
<div>blueprints or enhancements to Keystone and the API.</div>
<div><br>
</div>
<div>I have a few questions for you and would like to hear your thoughts on how</div>
<div>to optimize the user experience, especially around the service catalog.</div>
<div><br>
</div>
<div>Thank you!</div>
</blockquote>
<div><br>
</div>
<div>Thanks,</div>
<div><br>
</div>
<div>Paul</div>
</blockquote>
<blockquote id="MAC_OUTLOOK_ATTRIBUTION_BLOCKQUOTE" style="color: rgb(0, 0, 0); border-left-color: rgb(181, 196, 223); border-left-width: 5px; border-left-style: solid; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; ">
<div><br>
</div>
</blockquote>
</body>
</html>