You can use federation for the Identity service (keystone) in two ways:
Supporting keystone as a SP: consuming identity assertions issued by an external Identity Provider, such as SAML assertions or OpenID Connect claims.
Supporting keystone as an IdP: fulfilling authentication requests on behalf of Service Providers.
Note
It is also possible to have one keystone act as an SP that consumes Identity from another keystone acting as an IdP.
There is currently support for two major federation protocols:
To enable federation:
Run keystone under Apache. See Configure the Apache HTTP server for more information.
Note
Other application servers, such as nginx, have support for federation extensions that may work but are not tested by the community.
Configure Apache to use a federation capable module. We recommend Shibboleth, see the Shibboleth documentation for more information.
Note
Another option is mod_auth_melon
, see the mod’s github repo
for more information.
Configure federation in keystone.
Note
The external IdP is responsible for authenticating users and communicates the result of authentication to keystone using authentication assertions. Keystone maps these values to keystone user groups and assignments created in keystone.
To have keystone as an SP, you will need to configure keystone to accept assertions from external IdPs. Examples of external IdPs are:
Configure authentication drivers in keystone.conf
by adding the
authentication methods to the [auth]
section in keystone.conf
.
Ensure the names are the same as to the protocol names added via Identity
API v3.
For example:
[auth]
methods = external,password,token,saml2,openid
Note
saml2
and openid
are instances of the mapped
plugin. These
must match the name of the of the federation protocol created via the
Identity API. The other names in the example are not related to
federation.
Create local keystone groups and assign roles.
Important
The keystone requires group-based role assignments to authorize federated users. The federation mapping engine maps federated users into local user groups, which are the actors in keystone’s role assignments.
Create an IdP object in keystone. The object must represent the IdP you will use to authenticate end users:
PUT /OS-FEDERATION/identity_providers/{idp_id}
More configuration information for IdPs can be found Register an Identity Provider.
Add mapping rules:
PUT /OS-FEDERATION/mappings/{mapping_id}
More configuration information for mapping rules can be found Create a mapping.
Note
The only keystone API objects that support mapping are groups and users.
Add a protocol object and specify the mapping ID you want to use with the combination of the IdP and protocol:
PUT /OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id}
More configuration information for protocols can be found Add a protocol and attribute mapping to an identity provider.
Authenticate externally and generate an unscoped token in keystone:
Note
Unlike other authentication methods in keystone, the user does
not issue an HTTP POST request with authentication data in the request body.
To start federated authentication a user must access the dedicated URL with
IdP’s and protocol’s identifiers stored within a protected URL.
The URL has a format of:
/v3/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id}/auth
.
GET/POST /OS-FEDERATION/identity_providers/{identity_provider}/protocols/{protocol}/auth
Determine accessible resources. By using the previously returned token, the user can issue requests to the list projects and domains that are accessible.
GET /OS-FEDERATION/projects
Get a scoped token. A federated user can request a scoped token using the unscoped token. A project or domain can be specified by either ID or name. An ID is sufficient to uniquely identify a project or domain.
POST /auth/tokens
When acting as an IdP, the primary role of keystone is to issue assertions about users owned by keystone. This is done using PySAML2.
There are certain settings in keystone.conf
that must be set up, prior
to attempting to federate multiple keystone deployments.
Within keystone.conf
, assign values to the [saml]
related fields, for example:
[saml]
certfile=/etc/keystone/ssl/certs/ca.pem
keyfile=/etc/keystone/ssl/private/cakey.pem
idp_entity_id=https://keystone.example.com/v3/OS-FEDERATION/saml2/idp
idp_sso_endpoint=https://keystone.example.com/v3/OS-FEDERATION/saml2/sso
idp_metadata_path=/etc/keystone/saml2_idp_metadata.xml
We recommend the following Organization configuration options. Ensure these values contain not special characters that may cause problems as part of a URL:
idp_organization_name=example_company
idp_organization_display_name=Example Corp.
idp_organization_url=example.com
As with the Organization options, the Contact options are not necessary, but it is advisable to set these values:
idp_contact_company=example_company
idp_contact_name=John
idp_contact_surname=Smith
idp_contact_email=jsmith@example.com
idp_contact_telephone=555-55-5555
idp_contact_type=technical
Metadata must be exchanged to create a trust between the IdP and the SP.
Create metadata for your keystone IdP, run the keystone-manage
command
and pipe the output to a file. For example:
$ keystone-manage saml_idp_metadata > /etc/keystone/saml2_idp_metadata.xml
Note
The file location must match the value of the idp_metadata_path
configuration option assigned previously.
To setup keystone-as-a-Service-Provider properly, you will need to understand what protocols are supported by external IdPs. For example, keystone as an SP can allow identities to federate in from a ADFS IdP but it must be configured to understand the SAML v2.0 protocol. ADFS issues assertions using SAML v2.0. Some examples of federated protocols include:
The following instructions are an example of how you can configure keystone as an SP.
Create a new SP with an ID of BETA.
Create a sp_url
of http://beta.example.com/Shibboleth.sso/SAML2/ECP.
Create a auth_url
of http://beta.example.com:5000/v3/OS-FEDERATION/identity_providers/beta/protocols/saml2/auth.
Note
Use the sp_url
when creating a SAML assertion for BETA and signed by
the current keystone IdP. Use the auth_url
when retrieving the token
for BETA once the SAML assertion is sent.
Set the enabled
field to true
. It is set to
false
by default.
Your output should reflect the following example:
$ curl -s -X PUT \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"service_provider": {"auth_url": "http://beta.example.com:5000/v3/OS-FEDERATION/identity_providers/beta/protocols/saml2/auth", "sp_url": "https://example.com:5000/Shibboleth.sso/SAML2/ECP", "enabled": true}}' \
http://localhost:5000/v3/OS-FEDERATION/service_providers/BETA | python -mjson.tool
Keystone acting as an IdP is known as k2k or k2k federation, where a keystone somewhere is acting as the SP and another keystone is acting as the IdP. All IdPs issue assertions about the identities it owns using a Protocol.
Mapping adds a set of rules to map federation attributes to keystone users or groups. An IdP has exactly one mapping specified per protocol.
A mapping is a translation between assertions provided from an IdP and the permission and roles applied by an SP. Given an assertion from an IdP, an SP applies a mapping to translate attributes from the IdP to known roles. A mapping is typically owned by an SP.
Mapping objects can be used multiple times by different combinations of IdP and protocol.
A rule hierarchy is as follows:
{
"rules": [
{
"local": [
{
"<user> or <group>"
}
],
"remote": [
{
"<condition>"
}
]
}
]
}
rules
: top-level list of rules.local
: a rule containing information on what local attributes
will be mapped.remote
: a rule containing information on what remote attributes will
be mapped.condition
: contains information on conditions that allow a rule, can
only be set in a remote rule.For more information on mapping rules, see Mapping Rules.
Mapping creation starts with the communication between the IdP and SP. The IdP usually provides a set of assertions that their users have in their assertion document. The SP will have to map those assertions to known groups and roles. For example:
Identity Provider 1:
name: jsmith
groups: hacker
other: <assertion information>
The Service Provider may have 3 groups:
Admin Group
Developer Group
User Group
The mapping created by the Service Provider might look like:
Local:
Group: Developer Group
Remote:
Groups: hackers
The Developer Group
may have a role assignment on the
Developer Project
. When jsmith authenticates against IdP 1, it
presents that assertion to the SP.The SP maps the jsmith user to the
Developer Group
because the assertion says jsmith is a member of
the hacker
group.
A bare bones mapping is sufficient if you would like all federated users to have the same authorization in the SP cloud. However, mapping is quite powerful and flexible. You can map different remote users into different user groups in keystone, limited only by the number of assertions your IdP makes about each user.
A mapping is composed of a list of rules, and each rule is further composed of a list of remote attributes and a list of local attributes. If a rule is matched, all of the local attributes are applied in the SP. For a rule to match, all of the remote attributes it defines must match.
In the base case, a federated user simply needs an assertion containing an email address to be identified in the SP cloud. To achieve that, only one rule is needed that requires the presence of one remote attribute:
{
"rules": [
{
"remote": [
{
"type": "Email"
}
],
"local": [
{
"user": {
"name": "{0}"
}
}
]
}
]
}
However, that is not particularly useful as the federated user would receive no
authorization. To rectify it, you can map all federated users with email
addresses into a federated-users
group in the default
domain. All
federated users will then be able to consume whatever role assignments that
user group has already received in keystone:
Note
In this example, there is only one rule requiring one remote attribute.
{
"rules": [
{
"remote": [
{
"type": "Email"
}
],
"local": [
{
"user": {
"name": "{0}"
}
},
{
"group": {
"domain": {
"id": "0cd5e9"
},
"name": "federated-users"
}
}
]
}
]
}
This example can be expanded by adding a second rule that conveys
additional authorization to only a subset of federated users. Federated users
with a title attribute that matches either Manager
or
Supervisor
are granted the hypothetical observer
role, which would
allow them to perform any read-only API call in the cloud:
{
"rules": [
{
"remote": [
{
"type": "Email"
},
],
"local": [
{
"user": {
"name": "{0}"
}
},
{
"group": {
"domain": {
"id": "default"
},
"name": "federated-users"
}
}
]
},
{
"remote": [
{
"type": "Title",
"any_one_of": [".*Manager$", "Supervisor"],
"regex": "true"
},
],
"local": [
{
"group": {
"domain": {
"id": "default"
},
"name": "observers"
}
}
]
}
]
}
Note
any_one_of
and regex
in the rule above map federated users into
the observers
group when a user’s Title
assertion matches any of
the regular expressions specified in the any_one_of
attribute.
Keystone also supports the following:
not_any_of
, matches any assertion that does not include one of
the specified valuesblacklist
, matches all assertions of the specified type except
those included in the specified valuewhitelist
does not match any assertion except those listed in the
specified value.Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.