We had a recent IRC discussion about the design of Trusts and how it compares with OAuth version 1.
We need delegation. Beyond the requests from the HEAT team and the other community members that have requested it, delegation allows us to move beyond bearer tokens. Moving this process forward means that the other components need a mechanism for requesting tokens on behalf of their users. The goal with Trusts was to make the simplest mechanism possible in order to enable delegation.
No delegation mechanism can be implemented on top of the current token scheme without a way to link to the tokens. Thus, the idea of adding trusts or oauth as a pure extension could open up a security hole in token revocation. We’ve spent a lot of time inspecting these cases to make sure we are addressing the proper sequence for token revocation as well as linking tokens to the trusts so that all related tokens get revoked at once.
We’ve agreed that the CRUD interface from trusts (or its analogue) should be part of core. The real topic for debate is the mechanism for establishing delegation relationships and fetching tokens based on those relationships.
If Open Stack used OAuth, the interactions would look something like this:
It is worth mentioning that oauth was originally designed for browser based authentications, os the spec discusses redirects. However, the mechanism can be used without redirects. That originally colored my thinking.
The RFC uses the following terminology.
Service Provider: server
User: resource owner
Consumer Key and Secret: client credentials
Request Token and Secret: temporary credentials
Access Token and Secret: token credentials
Here’s my take at assigning these terms to pieces of Open Stack; please correct me if I have it wrong:
The Consumer in this case is Nova Compute (or some other related service) and the service provider is Keystone. The user is the end user of the system. If a user makes a request of Nova that requires additional delegation of authority, the response back from Nova includes sufficient information for the user to agree/disagree with the terms of the delegation. This is identified by the request token. If the user agrees to the delegation proposal, they are responsible for transferring the Secret back to Nova. Now, Nova has the ability to submit the request token at some point in the future.
This is laid out in section 2 of the RFC.
That entire mechanism is skipped in Keystone. Instead, the user must create the trust on their own, and then returns the trust ID to Nova. While this process could be performed by the Keystone client, it has not been implemented yet.
In order to implement a mechanism from section 2.1 in the spec the services need to be able to determine what they require. There is, as of now, no intraspection on the policy mechansim. It would be possible to have an method callable by the services on the policy engine which would return the roles required to perform a given action. If requesting the creation of a new virtual machine in Nova would require fetching an image out of glance, the Nova server would then need to ask “What policy rule protects the API I am about to call.” Nova could do this by fetching the policy file from Keystone. It would then return the status code of 307 (Temporary Redirect) to Keystone in order to create the trust.
There is no reason this mechanism could not follow the oauth standard. It would not conflict with trusts. The trust_id would play the role of the secret. There would be no need for it to be a secret, as only the owner of the trust, in this case the Nova service user, would be allowed to use it. I am not sure how Nova would communicate the Nova Service user_id back to the client, but I suspect that there is a way to marshal this inside the oauth parameters.
After that, the Keystone client would have to send a request to the Keystone server. While this would be comparable to POST /v3/trusts/, the format for oauth is different enough that it should be its own URL. However, the net effect would be the same: the user would create a delegation agreement inside of Keystone. The current Trust format meets the criteria for oauth. There is nothing wrong with maintaining both the deliberate trust create method as well as the oauth method for creating the Trust record. Ideally, the code would get refactored to maximize reuse between the two methods, and the only difference would be the marshalling of the data from the HTTP request.
Stepping back a bit, I don’t know whether OAuth 1 is the right standard to follow on this. The OAuth community has visibly split. OAuth 2 has some serious criticism levelled at it. However, the effort to write version two was based on an attempt to address the perceived weaknesses of the first version. Based on this analysis http://www.mediawiki.org/wiki/OAuth/Issues it looks like version 1 stands up better than 2. Oauth seems to be significantly different from other web based authorization mechanisms in that it explicitly does not attempt to address initial authentication. Compare this with OpenID which is first and foremost an authentication service.
However, there are many other mechanisms for sharing authorization information, to include delegation. SAML comes to the forefront here. The first stab at dealing with delegation came last summer which I wrote up in this proposal. https://wiki.openstack.org/wiki/Keystone/Delegation David Chadwick and Kristy Siu from kent.ac.uk have propsed a more general purpose mechanism and have submitted a a first patch.
Any delegation mechanism we propose must be auditable. With trusts, we have ensured that we can follow the chain of responsibility from action back to actors. It is essential, no matter how the concept of delegation evolves in the future, that we maintain the ability to follow this chain.