Configure Elasticsearch for SAML authentication

There are five configuration steps to enable SAML authentication in Elasticsearch:

  1. Enable SSL/TLS for HTTP
  2. Enable the Token Service
  3. Create one or more SAML realms
  4. Configure role mappings
  5. Generate a SAML Metadata file for use by your Identity Provider (optional)

Enable TLS for HTTP

If your Elasticsearch cluster is operating in production mode, then you must configure the HTTP interface to use SSL/TLS before you can enable SAML authentication.

For more information, see Encrypting HTTP client communications.

Enable the token service

The Elasticsearch SAML implementation makes use of the Elasticsearch Token Service. This service is automatically enabled if you configure TLS on the HTTP interface, and can be explicitly configured by including the following in your elasticsearch.yml file:

  1. xpack.security.authc.token.enabled: true

Create a SAML realm

SAML authentication is enabled by configuring a SAML realm within the authentication chain for Elasticsearch.

This realm has a few mandatory settings, and a number of optional settings. The available settings are described in detail in Security settings. For example, SAML realm settings, SAML realm signing settings, SAML realm encryption settings, SAML realm SSL settings. This guide will walk you through the most common settings.

Create a realm by adding the following to your elasticsearch.yml configuration file. Each configuration value is explained below.

  1. xpack.security.authc.realms.saml.saml1:
  2. order: 2
  3. idp.metadata.path: saml/idp-metadata.xml
  4. idp.entity_id: "https://sso.example.com/"
  5. sp.entity_id: "https://kibana.example.com/"
  6. sp.acs: "https://kibana.example.com/api/security/v1/saml"
  7. sp.logout: "https://kibana.example.com/logout"
  8. attributes.principal: "urn:oid:0.9.2342.19200300.100.1.1"
  9. attributes.groups: "urn:oid:1.3.6.1.4.1.5923.1.5.1."

SAML is used when authenticating via Kibana, but it is not an effective means of authenticating directly to the Elasticsearch REST API. For this reason we recommend that you include at least one additional realm such as the native realm in your authentication chain for use by API clients.

The configuration values used in the example above are:

xpack.security.authc.realms.saml.saml1

This defines a new saml authentication realm named “saml1”. See Realms for more explanation of realms.

order

You should define a unique order on each realm in your authentication chain. It is recommended that the SAML realm be at the bottom of your authentication chain (that is, that it has the highest order).

idp.metadata.path

This is the path to the metadata file that you saved for your Identity Provider. The path that you enter here is relative to your config/ directory. Elasticsearch will automatically monitor this file for changes and will reload the configuration whenever it is updated.

idp.entity_id

This is the identifier (SAML EntityID) that your IdP uses. It should match the entityID attribute within the metadata file.

sp.entity_id

This is a unique identifier for your Kibana instance, expressed as a URI. You will use this value when you add Kibana as a service provider within your IdP. We recommend that you use the base URL for your Kibana instance as the entity ID.

sp.acs

The Assertion Consumer Service (ACS) endpoint is the URL within Kibana that accepts authentication messages from the IdP. This ACS endpoint supports the SAML HTTP-POST binding only. It must be a URL that is accessible from the web browser of the user who is attempting to login to Kibana, it does not need to be directly accessible by Elasticsearch or the IdP. The correct value may vary depending on how you have installed Kibana and whether there are any proxies involved, but it will typically be ${kibana-url}/api/security/v1/saml where ${kibana-url} is the base URL for your Kibana instance.

sp.logout

This is the URL within Kibana that accepts logout messages from the IdP. Like the sp.acs URL, it must be accessible from the web browser, but does not need to be directly accessible by Elasticsearch or the IdP. The correct value may vary depending on how you have installed Kibana and whether there are any proxies involved, but it will typically be ${kibana-url}/logout where ${kibana-url} is the base URL for your Kibana instance.

attribute.principal

See Attribute mapping.

attribute.groups

See Attribute mapping.

Attribute mapping

When a user connects to Kibana through your Identity Provider, the Identity Provider will supply a SAML Assertion about the user. The assertion will contain an Authentication Statement indicating that the user has successfully authenticated to the IdP and one or more Attribute Statements that will include Attributes for the user.

These attributes may include such things as:

  • the user’s username
  • the user’s email address
  • the user’s groups or roles

Attributes in SAML are named using a URI such as urn:oid:0.9.2342.19200300.100.1.1 or http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn, and have one or more values associated with them.

These attribute identifiers vary between IdPs, and most IdPs offer ways to customize the URIs and their associated value.

Elasticsearch uses these attributes to infer information about the user who has logged in, and they can be used for role mapping (below).

In order for these attributes to be useful, Elasticsearch and the IdP need to have a common value for the names of the attributes. This is done manually, by configuring the IdP and the SAML realm to use the same URI name for each logical user attribute.

The recommended steps for configuring these SAML attributes are as follows:

  1. Consult your IdP to see what user attributes it can provide. This varies greatly between providers, but you should be able to obtain a list from the documentation, or from your local admin.
  2. Read through the list of user properties that Elasticsearch supports, and decide which of them are useful to you, and can be provided by your IdP. At a minimum, the principal attribute is required.
  3. Configure your IdP to “release” those attributes to your Kibana SAML service provider. This process varies by provider - some will provide a user interface for this, while others may require that you edit configuration files. Usually the IdP (or your local administrator) will have suggestions about what URI to use for each attribute. You can simply accept those suggestions, as the Elasticsearch service is entirely configurable and does not require that any specific URIs are used.
  4. Configure the SAML realm in Elasticsearch to associate the Elasticsearch user properties (see the listing below), to the URIs that you configured in your IdP. In the example above, we have configured the principal and groups attributes.

Special attribute names

In general, Elasticsearch expects that the configured value for an attribute will be a URI such as urn:oid:0.9.2342.19200300.100.1.1, however there are some additional names that can be used:

nameid

This uses the SAML NamedID value instead of a SAML attribute. SAML NameID elements are an optional, but frequently provided, field within a SAML Assertion that the IdP may use to identify the Subject of that Assertion. In some cases the NameID will relate to the user’s login identifier (username) within the IdP, but in many cases they will be internally generated identifiers that have no obvious meaning outside of the IdP.

nameid:persistent

This uses the SAML NameID value, but only if the NameID format is urn:oasis:names:tc:SAML:2.0:nameid-format:persistent. A SAML NameID element has an optional Format attribute that indicates the semantics of the provided name. It is common for IdPs to be configured with “transient” NameIDs that present a new identifier for each session. Since it is rarely useful to use a transient NameID as part of an attribute mapping, the “nameid:persistent” attribute name can be used as a safety mechanism that will cause an error if you attempt to map from a NameID that does not have a persistent value.

friendlyName

A SAML attribute may have a friendlyName in addition to its URI based name. For example the attribute with a name of urn:oid:0.9.2342.19200300.100.1.1 might also have a friendlyName of uid. You may use these friendly names within an attribute mapping, but it is recommended that you use the URI based names, as friendlyNames are neither standardized or mandatory.

The example below configures a realm to use a persistent nameid for the principal, and the attribute with the friendlyName “roles” for the user’s groups.

  1. xpack.security.authc.realms.saml.saml1:
  2. order: 2
  3. idp.metadata.path: saml/idp-metadata.xml
  4. idp.entity_id: "https://sso.example.com/"
  5. sp.entity_id: "https://kibana.example.com/"
  6. sp.acs: "https://kibana.example.com/api/security/v1/saml"
  7. attributes.principal: "nameid:persistent"
  8. attributes.groups: "roles"

Elasticsearch user properties

The Elasticsearch SAML realm can be configured to map SAML attributes to the following properties on the authenticated user:

principal

(Required) This is the username that will be applied to a user that authenticates against this realm. The principal appears in places such as the Elasticsearch audit logs.

groups

(Recommended) If you wish to use your IdP’s concept of groups or roles as the basis for a user’s Elasticsearch privileges, you should map them with this attribute. The groups are passed directly to your role mapping rules

name

(Optional) The user’s full name.

mail

(Optional) The user’s email address.

dn

(Optional) The user’s X.500 Distinguished Name.

Extracting partial values from SAML attributes

There are some occasions where the IdP’s attribute may contain more information than you wish to use within Elasticsearch. A common example of this is one where the IdP works exclusively with email addresses, but you would like the user’s principal to use the local-name part of the email address. For example if their email address was james.wong@staff.example.com, then you would like their principal to simply be james.wong.

This can be achieved using the attribute_patterns setting in the Elasticsearch realm, as demonstrated in the realm configuration below:

  1. xpack.security.authc.realms.saml.saml1:
  2. order: 2
  3. idp.metadata.path: saml/idp-metadata.xml
  4. idp.entity_id: "https://sso.example.com/"
  5. sp.entity_id: "https://kibana.example.com/"
  6. sp.acs: "https://kibana.example.com/api/security/v1/saml"
  7. attributes.principal: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
  8. attribute_patterns.principal: "^([^@]+)@staff\\.example\\.com$"

In this case, the user’s principal is mapped from an email attribute, but a regular expression is applied to the value before it is assigned to the user. If the regular expression matches, then the result of the first group is used as effective value. If the regular expression does not match then the attribute mapping fails.

In this example, the email address must belong to the staff.example.com domain, and then the local-part (anything before the @) is used as the principal. Any users who try to login using a different email domain will fail because the regular expression will not match against their email address, and thus their principal attribute - which is mandatory - will not be populated.

Small mistakes in these regular expressions can have significant security consequences. For example, if we accidentally left off the trailing $ from the example above, then we would match any email address where the domain starts with staff.example.com, and this would accept an email address such as admin@staff.example.com.attacker.net. It is important that you make sure your regular expressions are as precise as possible so that you do not inadvertently open an avenue for user impersonation attacks.

Requesting specific authentication methods

It is sometimes necessary for a SAML SP to be able to impose specific restrictions regarding the authentication that will take place at an IdP, in order to assess the level of confidence that it can place in the corresponding authentication response. The restrictions might have to do with the authentication method (password, client certificates, etc), the user identification method during registration, and other details. Elasticsearch implements SAML 2.0 Authentication Context, which can be used for this purpose as defined in SAML 2.0 Core Specification.

In short, the SAML SP defines a set of Authentication Context Class Reference values, which describe the restrictions to be imposed on the IdP, and sends these in the Authentication Request. The IdP attempts to grant these restrictions. If it cannot grant them, the authentication attempt fails. If the user is successfully authenticated, the Authentication Statement of the SAML Response contains an indication of the restrictions that were satisfied.

You can define the Authentication Context Class Reference values by using the req_authn_context_class_ref option in the SAML realm configuration. See SAML realm settings.

Elasticsearch supports only the exact comparison method for the Authentication Context. When it receives the Authentication Response from the IdP, Elasticsearch examines the value of the Authentication Context Class Reference that is part of the Authentication Statement of the SAML Assertion. If it matches one of the requested values, the authentication is considered successful. Otherwise, the authentication attempt fails.

SAML logout

The SAML protocol supports the concept of Single Logout (SLO). The level of support for SLO varies between Identity Providers. You should consult the documentation for your IdP to determine what Logout services it offers.

By default the Elastic Stack will support SAML SLO if the following are true:

  • Your IdP metadata specifies that the IdP offers a SLO service
  • Your IdP releases a NameID in the subject of the SAML assertion that it issues for your users
  • You configure sp.logout
  • The setting idp.use_single_logout is not false

IdP SLO service

One of the values that Elasticsearch reads from the IdP’s SAML metadata is the <SingleLogoutService>. In order for Single Logout to work with the Elastic stack, Elasticsearch requires that this exist and support a binding of urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect.

The Elastic Stack will send both <LogoutRequest> and <LogoutResponse> messages to this service as appropriate.

The sp.logout setting

The Elasticsearch realm setting sp.logout specifies a URL in Kibana to which the IdP can send both <LogoutRequest> and <LogoutResponse> messages. This service uses the SAML HTTP-Redirect binding.

Elasticsearch will process <LogoutRequest> messages, and perform a global signout that invalidates any existing Elasticsearch security tokens that are associated with the provided SAML session.

If you do not configure a value for sp.logout, Elasticsearch will refuse all <LogoutRequest> messages.

It is common for IdPs to require that LogoutRequest messages be signed, so you may need to configure signing credentials.

The idp.use_single_logout setting

If your IdP provides a <SingleLogoutService> but you do not wish to use it, you can configure idp.use_single_logout: false in your SAML realm, and Elasticsearch will ignore the SLO service that your IdP provides. In this case, when a user logs out of Kibana it will invalidate their Elasticsearch session (security token), but will not perform any logout at the IdP.

Using Kibana without single logout

If your IdP does not support Single Logout, or you choose not to use it, then Kibana will perform a “local logout” only.

This means that Kibana will invalidate the session token it is using to communicate with Elasticsearch, but will not be able to perform any sort of invalidation of the Identity Provider session. In most cases this will mean that Kibana users are still considered to be logged in to the IdP. Consequently, if the user navigates to the Kibana landing page, they will be automatically reauthenticated, and will commence a new Kibana session without needing to enter any credentials.

The possible solutions to this problem are:

  • Ask your IdP administrator or vendor to provide a Single Logout service
  • If your Idp does provide a Single Logout Service, make sure it is included in the IdP metadata file, and do not set idp.use_single_logout to false.
  • Advise your users to close their browser after logging out of Kibana
  • Enable the force_authn setting on your SAML realm. This setting causes the Elastic Stack to request fresh authentication from the IdP every time a user attempts to log into Kibana. This setting defaults to false because it can be a more cumbersome user experience, but it can also be an effective protection to stop users piggy-backing on existing IdP sessions.

Encryption and signing

The Elastic Stack supports generating signed SAML messages (for authentication and/or logout), verifying signed SAML messages from the IdP (for both authentication and logout) and can process encrypted content.

You can configure Elasticsearch for signing, encryption or both, with the same or separate keys used for each of those.

The Elastic Stack uses X.509 certificates with RSA private keys for SAML cryptography. These keys can be generated using any standard SSL tool, including the elasticsearch-certutil tool.

Your IdP may require that the Elastic Stack have a cryptographic key for signing SAML messages, and that you provide the corresponding signing certificate within the Service Provider configuration (either within the Elastic Stack SAML metadata file or manually configured within the IdP administration interface). While most IdPs do not expected authentication requests to be signed, it is commonly the case that signatures are required for logout requests. Your IdP will validate these signatures against the signing certificate that has been configured for the Elastic Stack Service Provider.

Encryption certificates are rarely needed, but the Elastic Stack supports them for cases where IdPs or local policies mandate their use.

Generating certificates and keys

Elasticsearch supports certificates and keys in either PEM, PKCS#12 or JKS format. Some Identity Providers are more restrictive in the formats they support, and will require you to provide the certificates as a file in a particular format. You should consult the documentation for your IdP to determine what formats they support. Since PEM format is the most commonly supported format, the examples below will generate certificates in that format.

Using the elasticsearch-certutil tool, you can generate a signing certificate with the following command:

  1. bin/elasticsearch-certutil cert -pem -days 1100 -name saml-sign -out saml-sign.zip

This will

  • generate a certificate and key pair (the cert subcommand)
  • create the files in PEM format (-pem option)
  • generate a certificate that is valid for 3 years (-days 1100)
  • name the certificate saml-sign (-name option)
  • save the certificate and key in the saml-sign.zip file (-out option)

The generated zip archive will contain 3 files:

  • saml-sign.crt, the public certificate to be used for signing
  • saml-sign.key, the private key for the certificate
  • ca.crt, a CA certificate that is not need, and can be ignored.

Encryption certificates can be generated with the same process.

Configuring Elasticsearch for signing

By default, Elasticsearch will sign all outgoing SAML messages if a signing key has been configured.

If you wish to use PEM formatted keys and certificates for signing, then you should configure the following settings on the SAML realm:

signing.certificate

The path to the PEM formatted certificate file. e.g. saml/saml-sign.crt

signing.key

The path to the PEM formatted key file. e.g. saml/saml-sign.key

signing.secure_key_passphrase

The passphrase for the key, if the file is encrypted. This is a secure setting that must be set with the elasticsearch-keystore tool.

If you wish to use PKCS#12 formatted files or a Java Keystore for signing, then you should configure the following settings on the SAML realm:

signing.keystore.path

The path to the PKCS#12 or JKS keystore. e.g. saml/saml-sign.p12

signing.keystore.alias

The alias of the key within the keystore. e.g. signing-key

signing.keystore.secure_password

The passphrase for the keystore, if the file is encrypted. This is a secure setting that must be set with the elasticsearch-keystore tool.

If you wish to sign some, but not all outgoing SAML messages, then you should configure the following setting on the SAML realm:

signing.saml_messages

A list of message types to sign. A message type is identified by the local name of the XML element used for the message. Supported values are: AuthnRequest, LogoutRequest and LogoutResponse.

Configuring Elasticsearch for encrypted messages

The Elasticsearch security features support a single key for message decryption. If a key is configured, then Elasticsearch attempts to use it to decrypt EncryptedAssertion and EncryptedAttribute elements in Authentication responses, and EncryptedID elements in Logout requests.

Elasticsearch rejects any SAML message that contains an EncryptedAssertion that cannot be decrypted.

If an Assertion contains both encrypted and plain-text attributes, then failure to decrypt the encrypted attributes will not cause an automatic rejection. Rather, Elasticsearch processes the available plain-text attributes (and any EncryptedAttributes that could be decrypted).

If you wish to use PEM formatted keys and certificates for SAML encryption, then you should configure the following settings on the SAML realm:

encryption.certificate

The path to the PEM formatted certificate file. e.g. saml/saml-crypt.crt

encryption.key

The path to the PEM formatted key file. e.g. saml/saml-crypt.key

encryption.secure_key_passphrase

The passphrase for the key, if the file is encrypted. This is a secure setting that must be set with the elasticsearch-keystore tool.

If you wish to use PKCS#12 formatted files or a Java Keystore for SAML encryption, then you should configure the following settings on the SAML realm:

encryption.keystore.path

The path to the PKCS#12 or JKS keystore. e.g. saml/saml-crypt.p12

encryption.keystore.alias

The alias of the key within the keystore. e.g. encryption-key

encryption.keystore.secure_password

The passphrase for the keystore, if the file is encrypted. This is a secure setting that must be set with the elasticsearch-keystore tool.