Currently, in order to make use of a given OpenStack service—when Keystone is in use—, a token issued by Keystone must be presented in the request. This falls short of the federation goal, where a customer running an OpenStack instance could issue a request to a contracted service provider also running OpenStack, using their existing authentication tokens. In this proposal, I put forward a mechanism by which this federation can be accomplished, along with a terminology that can help simplify future discussions.
A “realm”, in the context of OpenStack, consists of a set of services which all rely on a single Keystone data set for authentication. Note that this is not necessarily a single Keystone service: multiple Keystone services could be in use; the defining characteristic is that they all use the same data set, however that set is distributed. As an example, consider a large hosting provider: they may have many compute instances distributed across a number of zones, but all of them would use a common, possibly redundant, Keystone service. Another example could be a large customer of the hosting provider: they may have one or more zones, but also wish to have a contract with the hosting provider to provide more capacity or redundancy; again, all of their zones would use a common, possibly redundant, Keystone service.
In the above message sequence diagram, we see an example of a cross-realm interaction. In the first part of the interaction, we see a fairly typical authenticated query: the user issues a request, authenticated with a token from the user's realm, and this request is rejected (since the token is from another realm). In the second part of the interaction, we see the user obtain a cross-realm authentication token from the service provider's realm, and the third part of the interaction illustrates a successful authenticated request. The new interaction being proposed is this cross-realm authentication step, which allows the user to obtain an authentication token for the service provider realm using a token from the customer realm. Let us consider each step in the diagram in turn.
The user generates a request to the service provider's Keystone service. This would look like a normal username/password login request, except that a reference to the customer's Keystone service and the user's current authentication token would be included; we will call this token `R2_tok` for brevity. (It is assumed that, initially, this entry point would be defined by means of an extension.) The service provider's Keystone service will check this reference and determine whether the customer's Keystone service has been registered, and if not, the request will be rejected. (The registration requirement is the first part of establishing a limited trust relationship between the two zones, as we shall see later on in this interaction.)
Assuming that such a registration step has been performed, the service provider Keystone service would then contact the customer's Keystone service to verify the `R2_tok` authenticity. Although this is an existing operation, there is likely a need for a new endpoint or for a new parameter to the verification message, in order to inform the customer's Keystone service that this is a step in a cross-realm authentication interaction. This will also allow the customer's Keystone service to perform an authorization check: presumably, customers may want to restrict which of their users are additionally authorized to access the customer's assets on the service provider.
Verified Token and Map to Username
In the cross-realm authentication interaction, the customer's Keystone service not only needs to verify that `R2_tok` is valid and identifies an authorized user, but it must also map that user to a username known by the service provider's Keystone service. Additionally, it must inform the service provider's Keystone service as to the tenant(s), groups, roles, and other authentication data that corresponds to the user. It should also be pointed out that a customer may have relationships with more than one service provider.
The service provider's Keystone service, upon receiving this message, must perform authorization checks on the data provided by the customer's Keystone service: primarily, ensuring that the user and tenant are applicable for that customer and that the groups and roles are within reason. Without this verification step, it would be possible for a malicious customer to obtain administrative access to the service provider's realm. This is where the registration information mentioned in the first step above comes in.
Authentication Token and Service Catalog
Once the interaction is complete, the service provider's Keystone service generates a new authentication token, `R1_tok`, and returns it to the user, along with the service catalog. This message is identical to the normal message generated by a Keystone service when a user logs in using normal username/password login.
Required Changes to Keystone
The primary change required for Keystone to support cross-realm authentication is the addition of the concept of a realm, along with associated data to be used for contacting remote realms and mapping and authorizing token verification and authentication data mappings (the mapping of a user from one realm to another, along with mappings of tenants, roles, groups, etc.). From the standpoint of the API, an additional endpoint or, more likely, a new login message extension will be required, as is a means of performing the cross-realm token verification step and transferring the authentication data mapping. It is quite likely that this could be implemented easily as an extension to the existing Keystone service.