Keystone/Federation/UserIDsInACLs

Handling ACLs that use UserIDs in Federated Keystone
Version 0.5                                 11 April 2013 Authors: David Chadwick and Kristy Siu

Note Not all cloud services use ACLs and UserIDs. Those services that use roles for authorisation are not affected by the issue specified in this blueprint.

Introduction
Federated Keystone does not store permanent user entries for users who authenticate via external Identity Providers (IdPs). Instead temporary user entries are created for the duration of the validity time of the assertion issued by the Identity Provider. In this way, there are no Keystone administration costs associated with managing user entries. User management and provisioning is done by the IdPs. The Keystone federation code creates temporary entries on user login and automatically deletes them when they have expired. (Note that permanent entries can still be created by omitting the validity time when the entry is created.)

Problem Statement
A consequence of this is that the same user, with the same set of identity attributes, will have new temporary user entries created each time he logs into OpenStack (unless the existing temporary entry has not expired). Each temporary entry will have a new user_id assigned to it. So the existing user_id for federated users can no longer be used in service ACLs, as the user’s user_id will change every time he logs in. For example, in Swift, container ACLs can hold user_ids in one of three forms: (A) tenant_name:user_id, (B) tenant_id:user_id and (C) *:user_id.

Proposed Solution
The solution should not affect existing cloud service providers, and they should not have to change their code, so that adding federation to Keystone is backwards compatible to the non-federated use of Keystone. It is the case that users often still have unique identifiers assigned to them by IdPs. These typically come in two forms: identity attributes that are globally unique, such as email address, and persistent Ids (PIds) issued by the IdP to identify the subject of the assertion to the SP. This blueprint places no requirements on IdPs other than that they should issue one of these unique identifiers if the cloud service uses user-ids in its ACLs.

If a cloud service wishes to use federated identities, and also wishes to use user_ids in ACL, then the following solution is proposed:


 * 1) 	The IdP must issue the user with an identifier whose value is unique throughout the entire federation. We will call this attribute X (it could be an email address or a PId or any other attribute with the required uniqueness property).
 * 2) 	The protocol specific credential validation code must ensure that attribute X is present in the set of identity attributes that are returned to the Keystone federation controller code.
 * 3) 	The service catalog entry for the IdP may record the name of this attribute in the identifier_attribute parameter e.g. identifier_attribute=attributeX if this is appropriate for the protocol used by the IdP. In cases where the protocol always returns the same unique identifying attribute (e.g. Google IdP always uses OpenID as the unique attribute) then this can be handled by protocol specific code.
 * 4) 	The federation code (FIM Core) that creates temporary user entries will use the value of the identifier attribute as the basis for the value of the user_id when the entry is created. Because the value of this attribute could be arbitrarily long, the FIM Controller will SHA1 hash the attribute value (-> 20 bytes) then convert it to 28 base64 characters.
 * 5) 	The Keystone code will be modified so that if the value of the user_id is passed on user creation, it will be used, otherwise the code will behave as before and automatically create a new value.

In this way, the cloud service provider is not impacted by the use of federated identities, and is unaware that anything has changed (except that the value of the user_id attribute may be significantly different than before, and could contain a much wider character set, although if the value is converted and stored in hex (using uuid4.hex) then the service will not see any difference at all).

Creating ACLs – The Who Am I? Service
Since the temporary user entry probably won’t exist when the service wants to create the ACL, then there must be a way for the service provider to get the user’s user_id. The following is proposed
 * 1) 	A new Keystone service request/response (the Who Am I? service) will be provided which will allow the user to find out all of his attributes (both IdP provided and Keystone provided).
 * 2) 	The user will enter the two command line parameters –F and -? (F for federated, ? for who am I?)
 * 3) 	The API call will contain the headers X-Authentication-Type: federated and X-Request-Type:WhoAmI
 * 4) 	The FIM Controller will trap this request, and after it has created the temporary user entry and performed the attribute mapping, it will return the set of identity attributes and the unique identifier value issued by the IdP and the Keystone temporary entry that has been created (user name, user id, project, roles etc.)