From 0015e1a41e0ea355cc278db0eb060d1bab26fa7f Mon Sep 17 00:00:00 2001 From: David Stanek Date: Thu, 19 Jan 2017 18:49:01 +0000 Subject: [PATCH] Federated mapping doc improvements The documentation was originally written using imprecise language. This resulted in lots of confusion when read. Change-Id: I9f1af3cee3216c4c10c0bf6d91a6353a28f27dd5 --- .../federation/mapping_combinations.rst | 159 +++++++++++++++--- 1 file changed, 138 insertions(+), 21 deletions(-) diff --git a/doc/source/federation/mapping_combinations.rst b/doc/source/federation/mapping_combinations.rst index 9e79a9aba8..6b2205e852 100644 --- a/doc/source/federation/mapping_combinations.rst +++ b/doc/source/federation/mapping_combinations.rst @@ -20,17 +20,28 @@ Mapping Combinations Description ----------- -Mapping adds a set of rules to map federation attributes to Keystone users and/or -groups. An Identity Provider has exactly one mapping specified per protocol. +During the authentication process an identity provider (IdP) will present +keystone with a set of user attributes about the user that is authenticating. +For example, in the SAML2 flow this comes to keystone in the form of a SAML +document. -Mapping objects can be used multiple times by different combinations of Identity -Provider and Protocol. +The attributes are typically processed by third-party software and are presented +to keystone as environment variables. The original document from the IdP is +generally not available to keystone. This is how the `Shibboleth` and `Mellon` +implementations work. + +The mapping format described in this document maps these environment variables +to a local keystone user. The mapping may also define group membership for +that user and projects the user can access. + +An IdP has exactly one mapping specified per protocol. Mappings themselves can +be used multiple times by different combinations of IdP and protocol. ----------- Definitions ----------- -A rule hierarchy looks as follows: +A mapping looks as follows: .. code-block:: javascript @@ -39,23 +50,127 @@ A rule hierarchy looks as follows: { "local": [ { - " or " + + [] + [] } ], "remote": [ { - "" + + [] } ] } ] } -* `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. -* ``: contains information on conditions that allow a rule, can only - be set in a `remote` rule. +* `mapping`: a JSON object containing a list of rules. +* `rules`: a property in the mapping that contains the list of rules. +* `rule`: a JSON object containing `local` and `remote` properties to define + the rule. There is no explicit `rule` property. +* `local`: a JSON object containing information on what local attributes will + be mapped. The mapping engine processes this using the `context` (defined + below) and the result is a representation of the user from keystone's + perspective. + + * ``: the local user that will be mapped to the federated user. + * ``: (optional) the local groups the federated user will be placed in. + * ``: (optional) the local projects mapped to the federated user. + +* `remote`: a JSON object containing information on what remote attributes will be mapped. + + * ``: a JSON object that tells the mapping engine what federated attribute + to make available for substitution in the local object. There can be one or more + of these objects in the `remote` list. + * ``: a JSON object containing conditions that allow a rule. There can be + zero or more of these objects in the `remote` list. + +* `direct mapping`: the mapping engine keeps track of each match and makes them + available to the local rule for substitution. +* `assertion`: data provided to keystone by the IdP to assert facts + (name, groups, etc) about the authenticating user. This is an XML document when + using the SAML2 protocol. +* `mapping context`: the data, represented as key-value pairs, that is used by the + mapping engine to turn the `local` object into a representation of the user + from keystone's perspective. The mapping context contains the environment of the + keystone process and any `direct mapping` values calculated when processing the + `remote` list. + +-------------------------- +How Mappings Are Processed +-------------------------- + +A mapping is selected by IdP and protocol. Then keystone takes the mapping and +processes each rule sequentially stopping after the first matched rule. A rule +is matched when all of its conditions are met. + +First keystone evaluates each condition from the rule's remote property to see +if the rule is a match. If it is a match, keystone saves the data captured by +each of the matches from the rule's remote property in an ordered list. We call +these matches `direct mappings` since they can be used in the next step. + +After the rule is found using the rule's conditions and a list of direct mappings is +stored, keystone begins processing the rule's `local` property. Each object in +the `local` property is collapsed into a single JSON object. For example: + +.. code-block:: javascript + + { + "local": [ + { + "user": {...} + }, + { + "projects": [...] + }, + ] + } + +becomes: + +.. code-block:: javascript + + { + "local": { + "user": {...} + "projects": [...] + }, + } + +when the same property exists in the local multiple times the first occurrence wins: + +.. code-block:: javascript + + { + "local": [ + { + "user": {#first#} + }, + { + "projects": [...] + }, + { + "user": {#second#} + }, + ] + } + +becomes: + +.. code-block:: javascript + + { + "local": { + "user": {#first#} + "projects": [...] + }, + } + +We take this JSON object and then recursively process it in order to apply +the direct mappings. This is simply looking for the pattern `{#}` and +substituting it with values from the direct mappings list. The index of the +direct mapping starts at zero. ------------- Mapping Rules @@ -72,9 +187,9 @@ tested with the ``keystone-manage mapping_engine`` command: $ keystone-manage mapping_engine --rules --input .. NOTE:: - Although the rules file is formated as json the input file of assertion - data is formatted as individual lines of key: value pairs, - see `keystone-manage mapping_engine --help` for details. + Although the rules file is formated as JSON, the input file of assertion + data is formatted as individual lines of key: value pairs, see + `keystone-manage mapping_engine --help` for details. Mapping Conditions @@ -668,7 +783,7 @@ between this mapping and the other examples is the addition of a ``projects`` section within the ``local`` rules. The ``projects`` list supplies a list of projects that the federated user will be given access to. The projects will be automatically created if they don't exist when the user -authenticates and the mapping engine has applied values from the assertion +authenticated and the mapping engine has applied values from the assertion and mapped them into the ``local`` rules. In the above example, an authenticated federated user will be granted the @@ -758,21 +873,23 @@ federated user's name. In addition to that, they will also be placed in the ``Finance`` group and receive all role assignments that group has on projects and domains. -Keystone to Keystone +keystone-to-keystone -------------------- -Keystone to Keystone federation also utilizes mappings, but has some +keystone-to-keystone federation also utilizes mappings, but has some differences. -An attribute file (``/etc/shibboleth/attribute-map.xml``) is used to add -attributes to the Keystone Identity Provider. Attributes look as follows: +An attribute file (e.g. ``/etc/shibboleth/attribute-map.xml`` in a Shibboleth +implementation) is used to add attributes to the mapping `context`. Attributes +look as follows: .. code-block:: xml + -The Keystone Service Provider must contain a mapping as shown below. +The service provider must contain a mapping as shown below. ``openstack_user``, and ``openstack_user_domain`` match to the attribute names we have in the Identity Provider. It will map any user with the name ``user1`` or ``admin`` in the ``openstack_user`` attribute and