Configure keystone as a federated Service Provider

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 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 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 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:

  1. 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)

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  1. name is the name of the IDP used within Keystone and is the name shown by default in Horizon within the IDP dropdown.

  2. display_name an alternative name for your IDP to be displayed on Horizon, should your name attribute not be user friendly. (Optional)

  3. 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)

  4. 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.

  5. federated_identities is a mapping list of domain, project, group, and users. See Configure Identity Service (keystone) mappings for more information. (Optional)

  6. 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.

  7. mapping is the local to remote mapping configuration for federated users. See Configure Identity Service (keystone) mappings for more information.

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.

  1. cert_duration_years designates the valid duration for the SP’s signing certificate (for example, /etc/shibboleth/sp-key.pem).

  2. 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.

  3. metadata_file is the file name of the local cached version of the metadata which will be stored in /var/cache/shibboleth/.

  4. metadata_reload is the number of seconds between metadata refresh polls.

  5. 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.

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:

  • sp-cert.pem, sp-key.pem: The os-keystone-install.yml playbook

    uses these files generated on the first keystone container to replicate them to the other keystone containers. The SP and the IdP use these files as signing credentials in communications.

  • shibboleth2.xml: The os-keystone-install.yml playbook writes the file’s contents, basing on the structure of the configuration of the keystone_sp attribute in the /etc/openstack_deploy/user_variables.yml file. It contains the list of trusted IdP’s, the entityID by which the SP is known, and other facilitating configurations.

  • attribute-map.xml: The os-keystone-install.yml playbook writes the file’s contents, basing on the structure of the configuration of the keystone_sp attribute in the /etc/openstack_deploy/user_variables.yml file. It contains the default attribute mappings that work for any basic Shibboleth-type IDP setup, but also contains any additional attribute mappings set out in the structure of the keystone_sp attribute.

  • shibd.logger: This file is left alone by OpenStack-Ansible. It is useful when troubleshooting issues with federated authentication, or when discovering what attributes published by an IdP are not currently being understood by your SP’s attribute map. To enable debug logging, change log4j.rootCategory=INFO to log4j.rootCategory=DEBUG at the top of the file. The log file is output to /var/log/shibboleth/shibd.log.

Service provider configuration for keystone-to-keystone (k2k) with Shibboleth

Please set the following attributes:

  1. keystone_public_endpoint is automatically set by default to the public endpoint’s URI. This performs redirections and ensures token references refer to the public endpoint.

  2. horizon_keystone_endpoint is automatically set by default to the public v3 API endpoint URL for keystone. Web-based single sign-on for horizon requires the use of the keystone v3 API. The value for this must use the same DNS name or IP address registered in the SSL certificate used for the endpoint.

  3. It is a requirement to have a HTTPS public endpoint for the keystone endpoint if the IdP is ADFS. Keystone or an SSL offloading load balancer provides the endpoint.

  4. Set keystone_service_publicuri_proto to https. This ensures keystone publishes https in its references and ensures that Shibboleth is configured to know that it expects SSL URL’s in the assertions (otherwise it will invalidate the assertions).

  5. Most professional IDPs such as ADFS and Google require that a trusted SP have a trusted certificate that is not self-signed.

  6. Ensure the endpoint URI and the certificate match when using SSL for the keystone endpoint. For example, if the certificate does not have the IP address of the endpoint, then the endpoint must be published with the appropriate name registered on the certificate. When using a DNS name for the keystone endpoint, both keystone_public_endpoint and horizon_keystone_endpoint must be set to use the DNS name.

  7. horizon_endpoint_type must be set to publicURL to ensure that horizon uses the public endpoint for all its references and queries.

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.

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: "keystone-idp"
      entity_ids:
         - '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
          project: fedproject
          group: fedgroup
          role: member
      protocols:
        - name: saml2
          mapping:
            name: keystone-idp-mapping
            rules:
              - remote:
                  - type: openstack_user
                local:
                  - group:
                      name: fedgroup
                      domain:
                        name: Default
                    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.

  1. oidc_provider_metadata_url URL where OpenID Connect Provider metadata can be found.

  2. oidc_client_id is the Client identifier used in calls to the statically configured OpenID Connect Provider.

  3. oidc_client_secret is the Client secret used in calls to the statically configured OpenID Connect Provider.

  4. 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.

  5. oidc_redirect_path is the path component of 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.

  6. oidc_claim_prefix is the prefix to use when setting claims in the HTTP headers/environment variables. Defaults to ‘OIDC-‘.

  7. oidc_resp_type is the response type (or OpenID Connect Flow) used. Defaults to ‘id_token’.

  8. oidc_scope can be used to change the OpenID Connect scope(s) that are requested from the IDP. Defaults to ‘openid email profile’.

  9. oidc_auth_verify_jwks_uri is the URL on which the signing keys for this OP are hosted, in JWK formatting (Optional)

  10. 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)

  11. 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)

  12. oidc_auth_request_params can be used to define extra parameters that will be sent along with the Authorization Request. (Optional)

  13. 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)

  14. 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.

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.

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: <SECRET>
      oidc_crypto_passphrase: <RANDOM STRING>
      oidc_redirect_path: /oidc_redirect
      oidc_auth_request_params: param=some+url+encoded+value&param2=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}'

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.