Skip to content

Instantly share code, notes, and snippets.

@dolph
Created July 2, 2014 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dolph/b799b92488afffc09388 to your computer and use it in GitHub Desktop.
Save dolph/b799b92488afffc09388 to your computer and use it in GitHub Desktop.

Keystone to Keystone federation

bp keystone-to-keystone-federation

Enable the ability to federate identities between Keystone instances, with Keystone acting on behalf of the user to deliver cross-cloud authorization and a homogeneous cross-cloud service list.

Problem Description

Actors

  • Cloud Implementer - The person or group of people deploying and configuring an OpenStack cloud.
  • Service Provider (SP) - An entity that offers an OpenStack compatible cloud service (public or private).
  • Identity provider (IdP) - The federated identity provider of the end user. The service responsible for managing the authentication of the end user.
  • End user - An identity with access to one or many OpenStack clouds.

In the Icehouse release, we identified a way to establish trust between an IdP and Keystone using SAML. This allowed Cloud Implementers to set-up single-sign-on when configuring their cloud and not incur the administrative overhead that comes with provisioning identities in Keystone. Keystone trusts the IdP enough to accept federated identities from them. However, there is no way right now for one Keystone to trust another Keystone. This is where one Keystone trusts another to assert federation identities to it.

Use Case 1: Multiple Re-sellers

CERN has one OpenStack cloud set-up within their data center. They have Keystone sitting on top of an LDAP instance. They would like to allocate cloud workload between multiple public service providers, should their cloud not have enough bandwidth or storage.

Use Case 2: Cloud bursting

ACME has one OpenStack cloud set-up within their data center that surfaces a large eCommerce site. They have a promotion coming up on Black Friday, but do not have the infrastructure in place to handle the projected traffic. They are even unsure of what the projected traffic could be. They would like to auto-scale their application across SPs.

Use Case 3: Multiple in-house OpenStack deployments

ACME has several OpenStack clouds setup, and each one maintains its own set of assignments. They would like to enable identity federation across their multiple clouds so that an identity accessing each cloud doesn't need to maintain several tokens and credentials.

Use Case 4: Storage-only Provisioning

A service provider wishes to provide only storage services to external users. Hence, in any federation, the SP must be able to "advertise" only it's Swift service endpoints, and no others. Furthermore, the storage provider may wish to enforce access policies (who can access which containers) based on the set of roles that it defines. Hence, the User's Keystone must be able to acquire this set of roles and assign them to users accordingly.

The following can be considered requirements:

  1. The solution needs to be recursive, so that if Cloud A burst to Cloud B when it is overloaded, and Cloud B burst to Cloud C when it is overloaded, then jobs from A can be burst to C via B.
  2. The solution needs to require minimum changes to existing non-Keystone components, such as clients and OpenStack services. To put it another way, the majority of the changes should be applied to Keystone.
  3. (A) If changes have to be applied to either clients or OpenStack services, then changes to clients should take precedence over changes to OpenStack services. It would be optimum if only the Keystone client needs to change in this situation.

    OR

    (B) The current user-experience, that is used by non-federation-aware clients, should not need to change. Thus changes to service should take precedence over changes to clients.

  4. The solution must be as secure as the existing implementation of Keystone and Openstack, i.e., we must not downgrade the overall security by the introduction of Keystone federation. On the other hand it does not need to be more secure since attackers will always go for the weakest link.
  5. The solution must not reduce the functionality of existing clients and services.
  6. The solution must work for both federated users and non-federated users.
  7. The solution should not unduly impact on the non-functional aspects of existing OpenStack services e.g. performance, scalability etc.
  8. The local Keystone administrator must be able to have full control over the external entities that he trusts. This is relatively easy to achieve for direct trust relationships. but is more complex for indirect trust relationships, e.g., Keystone A trusts IdP 1 and external Keystone B, but not IdP2. Keystone B trusts IdP 1 and IdP 2. Keystone A must be able to stop users from IdP2 authenticating to Keystone B and then accessing its services via this indirect route.
  9. Should a token be revoked (either by its holder or issuer), there needs to be some way for all recipients (i.e. CSPs) to know about this event. E.g., there is a revocation service that the recipient can contact, or the issuer broadcasts out to its trusted CSPs, so that the revocation is all encompassing. The alternative is for the IdP to issue short lived tokens that will never be revoked, e.g., as in SAML. Keystone should be able to handle both of these scenarios.

Proposed Change

  1. Build the concept of a trusted service provider into Keystone. The trusted service provider is an external service (likely another Keystone), which trusts the local Keystone to assert federated identities to it.

    This will allow the cloud implementer to explicitly manage trust relationships. For example, BETA is a service provider. ACME would like to use BETA's resources. To establish a relationship between the two, ACME would trust BETA as a service provider, and BETA would trust ACME as an identity provider. That will allow ACME to burst into BETA cloud but not the other way around.

    For a real-life example, ACME might want to buy some resources from BETA, whereas ACME doesn't want BETA to use their resources. Of course, the reciprocal trust arrangements can be made between ACME and BETA, but this should be considered to be a repeat of the above, only in the opposite direction.

  2. ACME's Keystone mentioned in the above use cases should have knowledge of what services and endpoints BETA offers so that it could build adequate token scope across both OpenStack clouds.
  3. BETA's Keystone, acting as a trusted service provider, will get many tokens that are not within its local store. It will need to be able to decipher where the originating Keystone is from. The token can be validated if it is self contained, like a PKI token. The recipient can validate it given some pre-configured trust information (e.g. Root CA public key). The SignerInfo field in CMS can also tell us where it is coming from. http://tools.ietf.org/html/rfc5652#section-5.3

The following diagrams attempt to display the flow between the actors.

Figure 1: Creating a trust relationship

+----------+ +---------------+ | | | ACME | | ACME Cloud | | | | Implementer | | | +----------+ +---------------+ | | Out of Band | +----------+ +---------------+ | | | BETA | | BETA Cloud | | | | Implementer | | | +----------+ +---------------+ | | Out of Band | +----------+ +---------------+ | | | DELTA | | DELTA Cloud | | | | Implementer | | | | | +----------+ +---------------+

The flow illustrated in Figure 1 includes the following steps:

  1. Cloud Implementer at ACME adds BETA as a trusted SP via: PUT http://ACME.COM/v3/OS-FEDERATION/service_providers/BETA Within the request it contains BETAs authentication URL, which was obtained out of band.
  2. Cloud Implementer at ACME adds IdP 1 as a trusted IdP etc.
  3. Cloud Implementer at BETA adds ACME as a trusted IdP via: PUT http://BETA.COM/v3/OS-FEDERATION/identity_provider/ACME Within the request it contains a public key that can be used to verify signatures from ACME issued tokens. The Cloud Implementer must also create a Mapping and associate the Mapping with ACME IdP and a Protocol.
  4. Cloud Implementor at BETA adds DELTA as a trusted SP etc.
  5. Cloud Implementor at DELTA adds BETA as a trusted IdP etc.
Figure 2: Authentication Flow

                                        +----------+
                                        |          |

+-------(1') IdP sends assertion ---------| IdP | | | | | +----------+ | | | (1) | Authenticates | | v |

+----------+ +---------------+ | | | | | | | | | ACME | | USER | | | | | | | | | +----------+ +---------------+ | ^ | | | | | | +---------+ User authenticates | | | | BETA | via OS-FEDERATION | | | | | |----(7)----- BETA token returned ------------' +---------+

The flow illustrated in Figure 2 includes the following steps:

  1. User authenticates through their local IdP, and the IdP sends assertion data to ACME.
  2. User asks for an extended service catalog, possible using a query parameter to select an SP.
  3. ACME returns a token with one or more SPs, BETA included.
  4. User scopes to a project or domain at ACME, and requests that the BETA SP is used.
  5. ACME returns a token, scoped to the requested project or domain, and makes it usable with BETA only. The role assignments in this token represent the Keystone assertion attributes that a user can then pass to BETA.
  6. User authenticates with BETA, presenting the token returned from step 4.
  7. BETA validates the token, sees it was issued by ACME who is trusted. The role assignments in this token are treated as assertion attributes and fed into BETAs federated mapping rules, resulting in a new set of assignments on a project or domain in BETA. BETA returns a valid token scoped to the mapped project or domain and the respective assignments.

Alternatives

  1. Require the user to obtain multiple credentials in advance, one for each CSP he is going to visit, so that he can be authorised for any CSP service he wants to use by using the correct local token.
    • This is very undesirable as it requires client configuration or code changes each time a new CSP is trusted, and it makes the client code more complex to handle multiple tokens with different scope and varying expiration times.
  2. All CSP services will cater for users from any trusted IdP or proxy IdP by accepting every credential issued within the circle of trust, so regardless of the token the user has, he can obtain the service that is provided. (This requires every service such as Swift to be altered to accept any credential, not just locally issued ones).
    • This is very undesirable as it means that every OpenStack service will need to change in order to support remote users
  3. Each CSP hosts a local token exchange service (which could be Keystone) so that when users land at the CSP then whatever credential they currently hold can be exchanged for the local one used by the CSP's services.
    • This is a workable model if Keystone becomes the local token exchange service. None of the CSP's services need to change. If the user hits Keystone first it will simply exchange the remote token for a local one and then redirect the user to the local services. If the user hits a service first, it can simply send every token it receives from every user to the local Keystone to validate and Keystone will send back to the service information that it can use and understand for authorisation purposes.
  4. A new circle of trust (CoT) token service is set up which allows users to get "international" credentials prior to visiting remote CSPs. Users can present these CoT tokens to every CSP in the circle of trust. The CSP sends the CoT token to the CoT Service for validation, then gives the user a local credential valid for the CSP's services.
    • This is also a workable solution. If Keystone gives users two tokens: one issued by itself that is valid for its local services, and one issued by the CoT service that is valid for all remote services in the CoT. When the user goes to a remote CSP, this now behaves as in iii) above, except that the CoT token is sent to the CoT service for validation rather than the local Keystone service, and it returns a token valid for the local CSP.

Data Model Impact

The concept of service providers would likely include new data objects and schema changes:

{
    "service_provider": {
        "description": "BETA's service provider",
        "enabled": true,
        "id": "BETA_SP",
        "endpoints": [
            {
                "enabled": true,
                "id": "6fedc0",
                "interface": "public",
                "region_id": "us-east-1",
                "service_id": "ee057c",
                "url": "https://beta.service.example.com:5000/"
            }
        ]
    }
}

The existing identity provider data model need to be changed or to allow for storing the signing keys of an external Keystone IdP:

{
    "identity_provider": {
        "description": "ACME's identity provider",
        "enabled": true,
        "id": "ACME_IdP",
        "signing_key": "signing_key_value"
    }
}

If this change is required, we would have to create a migration script to account for upgrading and downgrading the OS-FEDERATION database.

REST API Impact

  • Register a service provider: PUT /OS-FEDERATION/service_providers/{sp_id}
  • List service providers: GET /OS-FEDERATION/service_providers
  • Get service provider: GET /OS-FEDERATION/service_providers/{sp_id}
  • Delete service provider: DELETE /OS-FEDERATION/service_providers/{sp_id}
  • Update a service provider: PATCH /OS-FEDERATION/service_providers/{sp_id}

Security Impact

This change does touch several sensitive data components, specifically Tokens:

  • If the SP deletes the IdP, then the issued tokens need to be revoked, and any new authentication requests should fail.
  • If the IdP deletes the SP, then the SP should delete the IdP as well. This is an out-of-band operation, and beyond the scope of this specification.
  • Possible information leakage. The token could contain a catalog, roles, etc. from ACME and that information is available to BETA. Though the information may not be important at the moment, it could be important in the future.
  • Does this increase the surface area of an attack if a cloud is compromised? For example, say ACME has a partnership with BETA and DELTA as SPs. A compromise of BETA is a Compromise of ACME and DELTA at the token level.
    • We may add a flag to the token, something like 'USABLE_WITH', and set it to the SP value. This approach should mitigate this attack vector.

Notifications Impact

  • Keystone will emit a CADF notitifcation (to authenticated and authorized identities), what revocations should occur for previously issued assertions.

Other End User Impact

python-keystoneclient may need to handle multiple tokens (one token per federated cloud).

Performance Impact

The following operations may impact performance:

  • A potentially larger catalog contains more data to send and sift through.
  • More certificates to validate tokens against.

Other Deployer Impact

None

Developer Impact

None

Implementation

Assignee(s)

Primary assignee:

Other contributors:

Work Items

  • Define a specification for adding and maintaining service providers.
  • Define and implement a method for storing the signing keys of the external IdP. This work may potentially be done using Barbican.
  • Define and implement a method of validating foreign tokens.
  • Define and implement a method of invalidating tokens across service providers.

Dependencies

None

Testing

  • Add unit tests for the new REST APIs.
  • If possible, create Tempest tests where multiple Keystone implementations exist; currently awaiting client support before we can start.

Documentation Impact

Extensive documentation will have to be performed to describe any new configurations necessary.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment