keystone saml mellon #4


The main goal of this charm is to generate the necessary configuration for use in the Keystone charm related to Service Provider config generation, trust establishment between a remote idP and SP via certificates and signaling Keystone service restart. Keystone has a concept of a federated backend which serves multiple purposes including being a backend part of a Service Provider in an authentication scenario where SAML is used. Unless ECP is used on a keystone client side, SAML-related exchange is performed in an Apache authentication module (Mellon in case of this charm) and SAML assertions are converted to WSGI environment variables passed down to a particular mod_wsgi interpreter running Keystone code. Keystone has an authentication plug-in called "mapped" which does the rest of the work of resolving symbolic attributes and using them in mappings defined by an operator or validating the existence of referenced IDs.


This subordinate charm provides a way to integrate a SAML-based identity
provider with Keystone using Mellon Apache web server authentication
module (mod_auth_mellon) and lasso as its dependency. Mellon acts as a
Service Provider in this case and provides SAML token attributes as WSGI
environment variables to Keystone which does not itself participate in
SAML exchanges - it merely interprets results of such exchanges
and maps assertion-derived attributes to entities (such as groups,
roles, projects and domains) in a local Keystone SQL database.

In general, any identity provider that conforms to SAML 2.0 will be
possible to integrate using this charm.

The following documentation is useful to better understand the charm


Use this charm with the Keystone charm, running with preferred-api-version=3:

juju deploy keystone
juju config keystone preferred-api-version=3 # other settings
juju deploy openstack-dashboard # settings
juju deploy keystone-saml-mellon
juju add-relation keystone keystone-saml-mellon
juju add-relation keystone openstack-dashboard

In a bundle:

    # ...
        charm: cs:~dmitriis/keystone-saml-mellon
        num_units: 0
          idp-name: 'myidp'
          protocol-name: 'saml2'
          user-facing-name: "myidp via saml2'
          idp-metadata: "./FederationMetadata.xml"
          sp-signing-keyinfo: "./sp-keyinfo.xml"
          sp-private-key: "./mellon.pem"
      # ...
      - [ keystone, keystone-saml-mellon ]
      - [ openstack-dashboard, keystone-saml-mellon ]
      - [ "openstack-dashboard:websso-trusted-dashboard", "keystone:websso-trusted-dashboard" ]


In order to use this charm, there are several prerequisites that need to be
taken into account which require certain infrastructure to be set up out of
band, namely:

  • PKI;
  • DNS;
  • NTP;
  • idP.

On the Keystone charm side, this means that ssl_ca, ssl_cert, ssl_key,
use-https and os-public-hostname must be set.

Several key pairs can be used in a generic SAML exchange along with
certificates containing public keys. Besides the pairs used for message-level
signing and encryption there are also TLS certificates used for transport
layer encryption when a browser connects to a protected URL on the SP side or
when it gets redirected to an idP endpoint for authentication. In summary:

  • Service Provider (Keystone) TLS termination certificates, keys and CA;
  • Service Provider signing and encryption private keys and associated
    public keys (SAML-level);
  • Identity Provider TLS termination certificates, keys and CA;
  • Identity Provider signing and encryption private keys and associated public
    keys (SAML-level).

For a successful authentication to happen the following needs to hold:

  • A user agent (browser) needs to
  • trust an issuer (CA) of TLS certificates of an SP used for HTTPS;
  • trust an issuer (CA) TLS certificates of an idP used for HTTPS;
  • be able to resolve domain names present in subject or subjAltName fields.
  • An SP needs to:
  • be able to verify signed SAML messages sent by an idP via
    public keys contained in certificates provided in the idP's metadata XML
    and, if SAML-level encryption is enabled, decrypt those messages;
  • An idP needs to:
  • be able to verify signed SAML messages sent by an SP via
    public keys contained in certificates provided in the SP's metadata XML
    and, if SAML-level encryption is enabled, decrypt those messages.

Note that this does not mean that any actual checks are performed for
certificates related to SAML - only key material is used and there does
NOT have to be any PKI actually in-place, not even expiration times are
checked as per Mellon documentation. In that sense trust is very explicitly
defined by out of band mutual synchronization of SP and idP metadata files.
See SAML V2.0 Metadata Interoperability Profile (2.6.1) key processing
section for a normative reference.

However, this does not mean that no PKI will be in place - TLS certificates
used for HTTPS connectivity have to be verifiable by the entities that use
them. With Redirect or POST binding this is mainly about user agent being
able to validate SP or idP certificates - there is no direct communication
between the two outside the metadata synchronization step which is performed
by an operator out of band.

Additionally, for successful certificate verification clocks of all parties
need to be properly synchronized which is why it is important for NTP agents
to be able to reach proper NTP servers on SP and idP.

Post-deployment Configuration

There are several post-deployment steps that have to be performed in order to
start using federated identity functionality in Keystone. They depend on the
chosen config values and also on an IDP configuration as it may put different
NameID values and attributes into SAML tokens. Token attributes are parsed by
mod_auth_mellon and are placed into WSGI environment which are used by
Keystone and they have the following format: "MELLON_"
(one attribute can have multiple values in SAML). Both NameID and attribute
values can be used in mappings to map SAML token content to existing and, in
case of projects, potentially non-existing entities in Keystone database.

In order to take the above into account several objects need to be created:

  • a domain used for federated users;
  • (optional) a project to be used by federated users;
  • one or more groups to place federated users into;
  • role assignments for the groups above;
  • an identity provider object;
  • a mapping of NameID and SAML token attributes to Keystone entities;
  • a federation protocol object.
    cat > rules.json <<EOF
            "local": [
                    "user": {
                        "name": "{0}"
                    "group": {
                        "domain": {
                            "name": "federated_domain"
                        "name": "federated_users"
                    "projects": [
                        "name": "{0}",
                        "roles": [
                                         "name": "Member"
            "remote": [
                    "type": "MELLON_NAME_ID"
                    "type": "MELLON_groups",
                    "any_one_of": ["openstack-users"]
    openstack domain create federated_domain
    openstack project create federated_project --domain federated_domain
    openstack group create federated_users --domain federated_domain
    # created group id: 0427a780b34441488f064526a9890edd
    openstack role add --group 0427a780b34441488f064526a9890edd --domain federated_domain Member
    openstack identity provider create --remote-id https://adfs.intranet.test/adfs/services/trust myidp
    openstack mapping create --rules rules.json myidp_mapping
    openstack federation protocol create mapped --mapping myidp_mapping --identity-provider myidp
    # list related projects
    openstack federation project list


Please report bugs on Launchpad.

For general questions please refer to the OpenStack Charm Guide.


(string) A user-facing name to be used for the identity provider and protocol combination. Used in the OpenStack dashboard.
myidp via mapped
(boolean) This option is used to control the checking of client IP address against the address returned by the IdP in Address attribute of the SubjectConfirmationData node. Can be useful if your SP is behind a reverse proxy or any kind of strange network topology making IP address of client different for the IdP and the SP. Default is on. This can be used for testing with something like testshib if you are behind a NAT.
(boolean) Enable verbose logging
(string) Protocol name to use for URL and generation. Must match the one that will be configured via OS-FEDERATION API.
(boolean) (optional) Specifies whether SAML assertion encryption should be used. In many cases this option is not needed as TLS is used to encrypt data at the transport level. This option results in Service Provider metadata rendered with the same KeyInfo used for both signing and encryption. In practice, this means that the private key specified in sp-private-key will be used for both signing SAML messages to an idP and decryption of messages sent by idP. idP has to receive the SP metadata file with a public key (or a cert) present with use="encryption" specified.
(boolean) Openstack mostly defaults to using public endpoints for internal communication between services. If set to True this option will configure services to use internal endpoints where possible.
(string) Identity provider name to use for URL generation. Must match the one that will be configured via OS-FEDERATION API.
(boolean) Enable debug logging
(string) NameIDFormat entries to be used in Service Provider metadata file and in SAML requests (comma-separated). Different NameID formats could be used like transient, persistent, X509SubjectName, emailAddress, unspecified and so on.
(boolean) Setting this to True will allow supporting services to log to syslog.