diff --git a/defaults/main.yml b/defaults/main.yml index 688256a4..3ed206e6 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -405,7 +405,7 @@ keystone_sp: {} # metadata_file: 'metadata-testshib-idp.xml' # metadata_reload: 1800 # federated_identities: -# - domain: Default +# - domain: default # project: fedproject # group: fedgroup # role: _member_ @@ -431,7 +431,7 @@ keystone_sp: {} # metadata_file: 'metadata-adfs-idp.xml' # metadata_reload: 1800 # federated_identities: -# - domain: Default +# - domain: default # project: fedproject # group: fedgroup # role: _member_ diff --git a/doc/source/configure-federation-mapping.rst b/doc/source/configure-federation-mapping.rst index 95be9d96..6ee55553 100644 --- a/doc/source/configure-federation-mapping.rst +++ b/doc/source/configure-federation-mapping.rst @@ -2,18 +2,20 @@ Configure keystone mappings =========================== -The following is an example SP mapping configuration for an ADFS IdP: +The federated_identities functionality can be used to create +projects, groups, roles and domains before your federation attribute +mappings route users towards those resources. If you manage creation of +projects, groups, roles and domains via a separate mechanism making use +of federated_identities is not required. .. code-block:: yaml federated_identities: - - domain: Default + - domain: default project: fedproject group: fedgroup role: _member_ -Each IdP trusted by an SP must have the following configuration: - #. ``project``: The project that federation users have access to. If the project does not already exist, create it in the domain with the name, ``domain``. @@ -27,6 +29,7 @@ Each IdP trusted by an SP must have the following configuration: #. ``domain``: The domain where the ``project`` lives, and where the you assign roles. Create the domain if it does not already exist. + This should be the ID of the domain. Ansible implements the equivalent of the following OpenStack CLI commands: @@ -42,22 +45,22 @@ Ansible implements the equivalent of the following OpenStack CLI commands: openstack role create _member_ # if the project does not already exist - openstack project create --domain Default fedproject + openstack project create --domain default fedproject # map the role to the project and user group in the domain openstack role add --project fedproject --group fedgroup _member_ -To add more mappings, add options to the list. +To extend simply add more entries to the list. For example: .. code-block:: yaml federated_identities: - - domain: Default + - domain: default project: fedproject group: fedgroup role: _member_ - - domain: Default + - domain: default project: fedproject2 group: fedgroup2 role: _member_ @@ -151,8 +154,10 @@ produces the following in keystone. ] The interpretation of the above mapping rule is that any federation user -authenticated by the IdP maps to an ``ephemeral`` (non-existant) user in -keystone. The user is a member of a group named ``fedgroup``. This is -in a domain called ``Default``. The user's ID and Name (federation uses -the same value for both properties) for all OpenStack services is -the value of ``upn``. +authenticated by the IdP maps to an ``ephemeral`` user in keystone. +The user is a member of a group named ``fedgroup``. This is in a domain +called ``Default``. As we have specified the domain, the users +assignments in the keystone backend will be looked up alongside the +assignments made in the mapping. +The user's ID and Name (federation uses the same value for both properties) +for all OpenStack services is the value of ``upn``. diff --git a/doc/source/configure-federation-sp.rst b/doc/source/configure-federation-sp.rst index 38369cb9..7aaebc20 100644 --- a/doc/source/configure-federation-sp.rst +++ b/doc/source/configure-federation-sp.rst @@ -2,24 +2,165 @@ Configure keystone as a federated Service Provider ================================================== -In OpenStack-Ansible, keystone is set up to use Apache with ``mod_wsgi``. +In OpenStack-Ansible, the default installation of keystone uses NGINX +and ``uWSGI``, however when deploying federation we instead use Apache +with ``uWSGI``. The additional configuration of keystone as a federation service provider -adds Apache ``mod_shib`` and configures it to respond to specific locations -requests from a client. +adds Apache ``mod_shib`` or ``mod_auth_openidc`` and configures it to +respond to authentication specific request locations from a client. .. note:: There are alternative methods of implementing federation, but at this time only SAML2-based federation using - the Shibboleth SP is instrumented in Openstack-Ansible. + the Shibboleth SP via mod_shib or OIDC-based federation using + mod_auth_openidc are supported in Openstack-Ansible. + Currently only one of these apache modules is supported at a time, + with a single trusted IdP in the keystone_sp.trusted_idp_list. When requests are sent to those locations, Apache hands off the -request to the ``shibd`` service. +request to the ``shibd`` daemon or ``mod_auth_openidc`` module. .. note:: Handing off happens only with requests pertaining to authentication. +Service provider configuration using keystone_sp +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +keystone_sp is a dictionary variable which contains various settings that +describe both the SP and the IDPs it trusts. The values required in +keystone_sp will differ slightly between Shibboleth SAML based deployments +and OIDC mod_auth_openidc deployments. + +The following settings can be set to configure a service provider (SP) +for both SAML or OIDC deployments: + +#. ``apache_mod`` can be used to switch between mod_shib and + mod_auth_openidc. If left undefined or misspelled Shibboleth will + be used by default. Valid values are 'shibboleth' or 'mod_auth_openidc'. + (Optional) + +#. ``cadf_notifications`` toggle Cloud Auditing Data Federation (CADF) + Notifications. These are off by default. Valid values are true or + false. More information is available in the + `keystone developer documentation + `_. + +#. ``cadf_notifications_opt_out`` ignore producing certain CADF notifications + when CADF notifications are enabled. The keystone documentation recommends + to opt out of: identity.authenticate.success, identity.authenticate.pending + and identity.authenticate.failed notifications as they are noisy. + +#. ``trusted_dashboard_list`` is the list of trusted URLs that keystone + accepts redirects for Web Single-Sign. This setting ensures that keystone + only sends token data back to trusted servers. This is performed as a + precaution, specifically to prevent man-in-the-middle (MITM) attacks. + This list contains all URLs that horizon is presented on, suffixed by + ``/auth/websso/`` which is the path for horizon's WebSSO component. + The trusted_dashboard_list may comprise of IP addresses and/or DNS names. + +#. ``trusted_idp_list`` is a dictionary attribute containing the list + of settings which correspond to each trusted IDP for the SP. + +The following are attributes that can be set on an entry in the +``trusted_idp_list``. Note while trusted_idp_list is a list, it can currently +only support one entry. + +#. ``name`` is the name of the IDP used within Keystone and is the name shown + by default in Horizon within the IDP dropdown. + +#. ``display_name`` an alternative name for your IDP to be displayed on + Horizon, should your name attribute not be user friendly. (Optional) + +#. ``domain_id`` is the domain the IDP will be created in. If this is not set + on creation of a new IDP, a new domain will be autogenerated with a random + ID. It is this domain that will become associated to the IDP. (Optional) + +#. ``entity_ids`` is a list of reference entity IDs. This specify's the + redirection of the login request to the SP when authenticating to + IDP. + +#. ``federated_identities`` is a mapping list of domain, project, group, and + users. See `Configure Identity Service (keystone) mappings`_ for more + information. (Optional) + +#. ``protocols`` is a list of protocols supported for the IDP and the set + of mappings and attributes for each protocol. This only supports protocols + with the name ``saml2`` or ``openid``. + +#. ``mapping`` is the local to remote mapping configuration for federated + users. See `Configure Identity Service (keystone) mappings`_ + for more information. + +.. _Configure Identity Service (keystone) mappings: configure-federation-mapping.html + +Service provider configuration for SAML using Shibboleth +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the attributes in keystone_sp defined above the following +attributes can be set in the entry for the ``trusted_idp_list`` for Shibboleth +SAML-based deployments. + +#. ``cert_duration_years`` designates the valid duration for the SP's + signing certificate (for example, ``/etc/shibboleth/sp-key.pem``). + +#. ``metadata_uri`` is the location of the IdP's metadata. This provides + the SP with the signing key and all the IdP's supported endpoints. + +#. ``metadata_file`` is the file name of the local cached version of + the metadata which will be stored in ``/var/cache/shibboleth/``. + +#. ``metadata_reload`` is the number of seconds between metadata + refresh polls. + +#. ``protocols.attributes`` add to the Shibboleth attributes mapping + directory. See `Configure Identity Service (keystone) mappings`_ + for more information. + .. _Configure Identity Service (keystone) mappings: configure-federation-mapping.html + +Below is an example keystone_sp for setting up keystone to be a SAML-based +service provider to an IDP using Shibboleth with CADF notifications on. + + .. code-block:: yaml + + keystone_sp: + apache_mod: 'shibboleth' + cert_duration_years: 5 + cadf_notifications: true + cadf_notifications_opt_out: + - identity.authenticate.failed + - identity.authenticate.pending + - identity.authenticate.success + trusted_dashboard_list: + - "https://{{ external_lb_vip_address }}/auth/websso/" + - "https://{{ horizon_server_name }}/auth/websso/" + trusted_idp_list: + - name: 'testshib-idp' + entity_ids: + - 'https://idp.testshib.org/idp/shibboleth' + metadata_uri: 'http://www.testshib.org/metadata/testshib-providers.xml' + metadata_file: 'metadata-testshib-idp.xml' + metadata_reload: 1800 + federated_identities: + - domain: default + project: fedproject + group: fedgroup + role: _member_ + protocols: + - name: saml2 + mapping: + name: testshib-idp-mapping + rules: + - remote: + - type: eppn + local: + - group: + name: fedgroup + domain: + name: Default + - user: + name: '{0}' + Handle the ``shibd`` service configuration through the following files in ``/etc/shibboleth/`` in the keystone containers: @@ -50,10 +191,10 @@ containers: ``log4j.rootCategory=DEBUG`` at the top of the file. The log file is output to ``/var/log/shibboleth/shibd.log``. -Configure keystone-to-keystone (k2k) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Service provider configuration for keystone-to-keystone (k2k) with Shibboleth +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The following settings must be set to configure a service provider (SP): +Please set the following attributes: #. ``keystone_public_endpoint`` is automatically set by default to the public endpoint's URI. This performs redirections and @@ -75,8 +216,8 @@ The following settings must be set to configure a service provider (SP): expects SSL URL's in the assertions (otherwise it will invalidate the assertions). -#. ADFS requires that a trusted SP have a trusted certificate that - is not self-signed. +#. Most professional IDPs such as ADFS and Google require that a trusted + SP have a trusted certificate that is not self-signed. #. Ensure the endpoint URI and the certificate match when using SSL for the keystone endpoint. For example, if the certificate does not have @@ -87,84 +228,178 @@ The following settings must be set to configure a service provider (SP): be set to use the DNS name. #. ``horizon_endpoint_type`` must be set to ``publicURL`` to ensure that - horizon uses the public endpoint for all its references and - queries. + horizon uses the public endpoint for all its references and queries. -#. ``keystone_sp`` is a dictionary attribute which contains various - settings that describe both the SP and the IDP's it trusts. For example: +Below is an example keystone_sp for setting up keystone to be a SAML-based +service provider to a keystone IDP using Shibboleth with CADF notifications on. +For k2k the ``trusted_dashboard_list`` may include Horizon entries from +multiple clouds. .. code-block:: yaml keystone_sp: + apache_mod: 'shibboleth' cert_duration_years: 5 + cadf_notifications: true + cadf_notifications_opt_out: + - identity.authenticate.failed + - identity.authenticate.pending + - identity.authenticate.success trusted_dashboard_list: + - "https://{{ horizon_server_name }}/auth/websso/" - "https://{{ external_lb_vip_address }}/auth/websso/" trusted_idp_list: - - name: 'testshib-idp' + - name: "keystone-idp" entity_ids: - - 'https://idp.testshib.org/idp/shibboleth' - metadata_uri: 'http://www.testshib.org/metadata/testshib-providers.xml' - metadata_file: 'metadata-testshib-idp.xml' + - 'https://keystone-idp:5000/v3/OS-FEDERATION/saml2/idp' + metadata_uri: 'https://keystone-idp:5000/v3/OS-FEDERATION/saml2/metadata' + metadata_file: 'metadata-keystone-idp.xml' metadata_reload: 1800 federated_identities: - - domain: Default + - domain: default project: fedproject group: fedgroup role: _member_ protocols: - name: saml2 mapping: - name: testshib-idp-mapping + name: keystone-idp-mapping rules: - remote: - - type: eppn + - type: openstack_user local: - group: name: fedgroup domain: name: Default - - user: + user: + name: '{0}' + attributes: + - name: openstack_user + id: openstack_user + - name: openstack_roles + id: openstack_roles + - name: openstack_project + id: openstack_project + - name: openstack_user_domain + id: openstack_user_domain + - name: openstack_project_domain + id: openstack_project_domain + + +Service provider configuration for OIDC using mod_auth_openidc +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In addition to the generic attributes in keystone_sp defined previously the +following attributes can be set in the entry for the ``trusted_idp_list`` +for mod_auth_openidc OIDC-based deployments. + +#. ``oidc_provider_metadata_url`` URL where OpenID Connect Provider + metadata can be found. + +#. ``oidc_client_id`` is the Client identifier used in calls to the + statically configured OpenID Connect Provider. + +#. ``oidc_client_secret`` is the Client secret used in calls to the + statically configured OpenID Connect Provider. + +#. ``oidc_crypto_passphrase`` the crypto passphrase is a password used for + encryption of state cookies and cache entries in mod_auth_openidc. + Mod_auth_openidc's documentation does not specify any format or + restrictions for this password. This should be set to a randomly generated + string of a sensible length. + +#. ``oidc_redirect_uri`` is the redirect_uri for this OpenID Connect + client; this is a vanity URL that must ONLY point to a path on your + server protected by this module but it must NOT point to any actual + content that needs to be served. + +#. ``oidc_claim_prefix`` is the prefix to use when setting claims in the + HTTP headers/environment variables. Defaults to 'OIDC-'. + +#. ``oidc_resp_type`` is the response type (or OpenID Connect Flow) used. + Defaults to 'id_token'. + +#. ``oidc_scope`` can be used to change the OpenID Connect scope(s) that + are requested from the IDP. Defaults to 'openid email profile'. + +#. ``oidc_auth_verify_jwks_uri`` is the URL on which the signing keys + for this OP are hosted, in JWK formatting (Optional) + +#. ``oidc_outgoing_proxy`` Specify an outgoing proxy for your network. + This is typically used to allow the necessary outgoing requests from + keystone to the IDP in non routed environments. (Optional) + +#. ``oidc_state_max_number_of_cookies`` can be used to specify the + maximum number of state cookies i.e. the maximum number of parallel + outstanding authentication requests. (Optional) + +#. ``oidc_auth_request_params`` can be used to define extra parameters + that will be sent along with the Authorization Request. (Optional) + +#. ``oidc_default_url`` can be used to define a default URL to be used + in case of 3rd-party-init-SSO when no explicit target_link_uri + has been provided. The user is also redirected to this URL in case + an invalid authorization response was received. (Optional) + +#. ``oidc_claim_delimiter`` can be used to change the delimiter to use + when setting multi-valued claims in the HTTP headers/environment + variables. (Optional) + +Please refer to the `zmartzone/mod_auth_openidc configuration documentation`_ +for more information and a full list of possible configuration options. + +.. _zmartzone/mod_auth_openidc configuration documentation: https://github.com/zmartzone/mod_auth_openidc/blob/master/auth_openidc.conf + +Below is an example keystone_sp for setting up keystone to be a OIDC-based +service provider to an IDP using mod_auth_openidc with CADF notifications on. + + .. code-block:: yaml + + keystone_sp: + apache_mod: 'mod_auth_openidc' + cadf_notifications: true + cadf_notifications_opt_out: + - identity.authenticate.failed + - identity.authenticate.pending + - identity.authenticate.success + trusted_dashboard_list: + - "https://{{ horizon_server_name }}/auth/websso/" + - "https://{{ external_lb_vip_address }}/auth/websso/" + trusted_idp_list: + - name: "oidc-idp" + oidc_provider_metadata_url: https://identity-provider/.well-known/openid-configuration + oidc_client_id: keystone + oidc_client_secret: + oidc_crypto_passphrase: + oidc_redirect_uri: https://{{external_lb_vip_address}}:5000/v3/OS-FEDERATION/identity_providers/oidc-idp/protocols/openid/auth + oidc_auth_request_params: param=some+url+encoded+value¶m2=and+another+one + entity_ids: + - 'https://identity-provider/openid-endpoint/' + federated_identities: + - domain: default + project: fedproject + group: fedgroup + role: _member_ + protocols: + - name: openid + mapping: + name: openid-mapping + rules: + - remote: + - type: OIDC-email + local: + - group: + name: fedgroup + domain: + name: Default + user: name: '{0}' -#. ``cert_duration_years`` designates the valid duration for the SP's - signing certificate (for example, ``/etc/shibboleth/sp-key.pem``). - -#. ``trusted_dashboard_list`` designates the list of trusted URLs that - keystone accepts redirects for Web Single-Sign. This - list contains all URLs that horizon is presented on, - suffixed by ``/auth/websso/``. This is the path for horizon's WebSSO - component. - -#. ``trusted_idp_list`` is a dictionary attribute containing the list - of settings which pertain to each trusted IdP for the SP. - -#. ``trusted_idp_list.name`` is IDP's name. Configure this in - in keystone and list in horizon's login selection. - -#. ``entity_ids`` is a list of reference entity IDs. This specify's the - redirection of the login request to the SP when authenticating to - IdP. - -#. ``metadata_uri`` is the location of the IdP's metadata. This provides - the SP with the signing key and all the IdP's supported endpoints. - -#. ``metadata_file`` is the file name of the local cached version of - the metadata which will be stored in ``/var/cache/shibboleth/``. - -#. ``metadata_reload`` is the number of seconds between metadata - refresh polls. - -#. ``federated_identities`` is a mapping list of domain, project, group, and - users. See - `Configure Identity Service (keystone) mappings`_ - for more information. - -#. ``protocols`` is a list of protocols supported for the IdP and the set - of mappings and attributes for each protocol. This only supports protocols - with the name ``saml2``. - -#. ``mapping`` is the local to remote mapping configuration for federated - users. See `Configure Identity Service (keystone) mappings`_ - for more information. - -.. _Configure Identity Service (keystone) mappings: configure-federation-mapping.html +It should be noted that mod_auth_openidc is automatically configured to use +the existing OSA memcached servers to temporarily persist state data. +This is of particular importance for high availability deployments +with multiple instances of keystone. The OIDC authentication session +state is persisted in memcached to allow different phases of the +authentication flow to be handled by different keystone instances +due to the round-robin behaviour of the loadbalancer.