816 lines
35 KiB
Plaintext
816 lines
35 KiB
Plaintext
[[saml-guide]]
|
|
|
|
== Configuring SAML Single-Sign-On on the Elastic Stack
|
|
|
|
The Elastic Stack supports SAML single-sign-on (SSO) into {kib}, using {es} as
|
|
a backend service. In SAML terminology, the Elastic Stack is operating as a
|
|
_Service Provider_.
|
|
|
|
The other component that is needed to enable SAML single-sign-on is the
|
|
_Identity Provider_, which is a service that handles your credentials and
|
|
performs that actual authentication of users.
|
|
|
|
If you are interested in configuring SSO into {kib}, then you will need to
|
|
provide {es} with information about your _Identity Provider_, and you will need
|
|
to register the Elastic Stack as a known _Service Provider_ within that
|
|
Identity Provider. There are also a few configuration changes that are
|
|
required in {kib} to activate the SAML authentication provider.
|
|
|
|
NOTE: The SAML support in {kib} is designed on the expectation that it will be
|
|
the primary (or sole) authentication method for users of that {kib} instance.
|
|
Once you enable SAML authentication in {kib} it will affect all users who try
|
|
to login. The <<saml-kibana>> section provides more detail about how this works.
|
|
|
|
=== The Identity Provider
|
|
|
|
The Elastic Stack supports the SAML 2.0 _Web Browser SSO_ and the SAML
|
|
2.0 _Single Logout_ profiles and can integrate with any Identity Provider (IdP)
|
|
that supports at least the SAML 2.0 _Web Browser SSO Profile_.
|
|
It has been tested with a number of popular IdP implementations.
|
|
|
|
This guide assumes that you have an existing IdP and wish to add {kib} as a
|
|
Service Provider.
|
|
|
|
The Elastic Stack uses a standard SAML _metadata_ document, in XML format that
|
|
defines the capabilities and features of your IdP. You should be able to
|
|
download or generate such a document within your IdP administration interface.
|
|
|
|
Download the IdP metadata document and store it within the `config` directory on
|
|
each {es} node. For the purposes of this guide, we will assume that you are
|
|
storing it as `config/saml/idp-metadata.xml`.
|
|
|
|
The IdP will have been assigned an identifier (_EntityID_ in SAML terminology)
|
|
which is most commonly expressed in _Uniform Resource Identifier_ (URI) form.
|
|
Your admin interface may tell you what this is, or you might need to
|
|
read the metadata document to find it - look for the `entityID` attribute on the
|
|
`EntityDescriptor` element.
|
|
|
|
Most IdPs will provide an appropriate metadata file with all the features that
|
|
the Elastic Stack requires, and should only require the configuration steps
|
|
described below. For completeness sake, the minimum requirements that the Elastic
|
|
Stack has for the IdP's metadata are:
|
|
|
|
- An `<EntityDescriptor>` with an `entityID` that matches the {es}
|
|
<<saml-create-realm, configuration>>
|
|
- An `<IDPSSODescriptor>` that supports the SAML 2.0 protocol
|
|
(`urn:oasis:names:tc:SAML:2.0:protocol`).
|
|
- At least one `<KeyDescriptor>` that is configured for _signing_ (that is, it
|
|
has `use="signing"` or leaves the `use` unspecified)
|
|
- A `<SingleSignOnService>` with binding of HTTP-Redirect
|
|
(`urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect`)
|
|
- If you wish to support <<saml-logout, Single Logout>>, a `<SingleLogoutService>`
|
|
with binding of HTTP-Redirect
|
|
(`urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect`)
|
|
|
|
The Elastic Stack requires that all messages from the IdP are signed.
|
|
For authentication `<Response>` messages, the signature may be applied to either
|
|
the response itself, or to the individual assertions.
|
|
For `<LogoutRequest>` messages, the message itself must be signed, and the
|
|
signature should be provided as a URL parameter, as required by the HTTP-Redirect
|
|
binding.
|
|
|
|
=== Configure {es} for SAML Authentication
|
|
|
|
There are five configuration steps to enable SAML authentication in {es}:
|
|
|
|
. Enable SSL/TLS for HTTP
|
|
. Enable the Token Service
|
|
. Create one or more SAML realms
|
|
. Configure role mappings
|
|
. Generate a SAML Metadata file for use by your Identity Provider _(optional)_
|
|
|
|
==== Enable TLS for HTTP
|
|
|
|
If your {es} cluster is operating in production mode, then you must
|
|
configure the HTTP interface to use SSL/TLS before you can enable SAML
|
|
authentication.
|
|
|
|
See <<enable-ssl>> for instructions on how to do this.
|
|
|
|
==== Enable the Token Service
|
|
|
|
The {es} SAML implementation makes use of the {es} 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:
|
|
|
|
[source, yaml]
|
|
------------------------------------------------------------
|
|
xpack.security.authc.token.enabled: true
|
|
------------------------------------------------------------
|
|
|
|
[[saml-create-realm]]
|
|
==== Create a SAML Realm
|
|
|
|
SAML authentication is enabled by configuring a SAML realm within the
|
|
authentication chain for {es}.
|
|
|
|
This realm has a few mandatory settings, and a number of optional settings.
|
|
The available settings are described in detail in the
|
|
<<saml-settings, SAML realm documentation>>, 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.
|
|
|
|
[source, yaml]
|
|
------------------------------------------------------------
|
|
xpack.security.authc.realms.saml1:
|
|
type: saml
|
|
order: 2
|
|
idp.metadata.path: saml/idp-metadata.xml
|
|
idp.entity_id: "https://sso.example.com/"
|
|
sp.entity_id: "https://kibana.example.com/"
|
|
sp.acs: "https://kibana.example.com/api/security/v1/saml"
|
|
sp.logout: "https://kibana.example.com/logout"
|
|
attributes.principal: "urn:oid:0.9.2342.19200300.100.1.1"
|
|
attributes.groups: "urn:oid:1.3.6.1.4.1.5923.1.5.1."
|
|
------------------------------------------------------------
|
|
|
|
IMPORTANT: SAML is used when authenticating via {kib}, but it is not an
|
|
effective means of authenticating directly to the {es} REST API. For this reason
|
|
we recommend that you include at least one additional realm such as the
|
|
<<native-realm, 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::
|
|
This defines a new authentication realm named "saml1".
|
|
See <<how-authc-works>> for more explanation of realms.
|
|
|
|
type:: The `type` must be `saml`
|
|
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.
|
|
{security} 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 {kib} instance, expressed as a URI.
|
|
You will use this value when you add {kib} as a service provider within your IdP.
|
|
We recommend that you use the base URL for your {kib} instance as the entity ID.
|
|
|
|
sp.acs::
|
|
The _Assertion Consumer Service_ (ACS) endpoint is the URL within {kib} 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 {kib}, it does not need to be directly accessible by {es}
|
|
or the IdP.
|
|
The correct value may vary depending on how you have installed {kib} 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 {kib} instance.
|
|
|
|
sp.logout::
|
|
This is the URL within {kib} 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 {es} or the IdP. The correct value may
|
|
vary depending on how you have installed {kib} and whether there are any
|
|
proxies involved, but it will typically be `${kibana-url}/logout` where
|
|
_${kibana-url}_ is the base URL for your {kib} instance.
|
|
|
|
attribute.principal:: See <<saml-attribute-mapping>>.
|
|
attribute.groups:: See <<saml-attribute-mapping>>.
|
|
|
|
[[saml-attribute-mapping]]
|
|
==== Attribute Mapping
|
|
|
|
When a user connects to {kib} 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 ore 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
|
|
customise the URIs and their associated value.
|
|
|
|
{es} 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, {es} and the IdP need to have a
|
|
common via for the names of the attributes. This is done manually, by
|
|
configuring the IdP and the {security} SAML realm to use the same URI name for
|
|
each logical user attribute.
|
|
|
|
The recommended steps for configuring these SAML attributes are as follows:
|
|
|
|
. 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.
|
|
|
|
. Read through the list of <<saml-user-properties, user properties>> that {es}
|
|
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.
|
|
|
|
. Configure your IdP to "release" those attributes to your {kib} 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
|
|
{es} service is entirely configurable and does not require that any specific
|
|
URIs are used.
|
|
|
|
. Configure the SAML realm in {es} to associate the {es} user properties (see
|
|
<<saml-user-properties, 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, {es} 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) wihin 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.
|
|
|
|
[source, yaml]
|
|
------------------------------------------------------------
|
|
xpack.security.authc.realms.saml1:
|
|
type: saml
|
|
order: 2
|
|
idp.metadata.path: saml/idp-metadata.xml
|
|
idp.entity_id: "https://sso.example.com/"
|
|
sp.entity_id: "https://kibana.example.com/"
|
|
sp.acs: "https://kibana.example.com/api/security/v1/saml"
|
|
attributes.principal: "nameid:persistent"
|
|
attributes.groups: "roles"
|
|
------------------------------------------------------------
|
|
|
|
[[saml-user-properties]]
|
|
===== {es} User Properties
|
|
|
|
The {es} 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 {es} audit logs.
|
|
|
|
groups:: _(Recommended)_
|
|
If you wish to use your IdP's concept of groups or roles as the basis for a
|
|
user's {es} privileges, you should map them with this attribute.
|
|
The `groups` are passed directly to your
|
|
<<saml-role-mapping, 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 {es}. 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 {es}
|
|
realm, as demonstrated in the realm configuration below:
|
|
|
|
[source, yaml]
|
|
------------------------------------------------------------
|
|
xpack.security.authc.realms.saml1:
|
|
type: saml
|
|
order: 2
|
|
idp.metadata.path: saml/idp-metadata.xml
|
|
idp.entity_id: "https://sso.example.com/"
|
|
sp.entity_id: "https://kibana.example.com/"
|
|
sp.acs: "https://kibana.example.com/api/security/v1/saml"
|
|
attributes.principal: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
|
|
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.
|
|
|
|
IMPORTANT: 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.
|
|
|
|
[[saml-logout]]
|
|
==== 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
|
|
- You configure `sp.logout`
|
|
- The setting `idp.use_single_logout` is not `false`
|
|
|
|
===== IdP SLO Service
|
|
|
|
One of the values that {es} reads from the IdP's SAML metadata is the
|
|
`<SingleLogoutService>`. In order for Single Logout to work with the Elastic
|
|
stack, {es} 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 {es} realm setting `sp.logout` specifies a URL in {kib} to which the IdP can
|
|
send both `<LogoutRequest>` and `<LogoutResponse>` messages. This service uses
|
|
the SAML HTTP-Redirect binding.
|
|
|
|
{es} will process `<LogoutRequest>` messages, and perform a global signout that
|
|
invalidates any existing {es} security tokens that are associated with the
|
|
provided SAML session.
|
|
|
|
If you do not configure a value for `sp.logout`, {es} will refuse all
|
|
`<LogoutRequest>` messages.
|
|
|
|
NOTE: It is common for IdPs to require that `LogoutRequest` messages be signed,
|
|
so you may need to configure <<saml-enc-sign,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 {es}
|
|
will ignore the SLO service that your IdP provides. In this case, when a user
|
|
logs out of {kib} it will invalidate their {es} session (security token), but
|
|
will not perform any logout at the IdP.
|
|
|
|
===== Using {kib} without Single Logout
|
|
|
|
If your IdP does not support Single Logout, or you choose not to use it, then
|
|
{kib} will perform a "local logout" only.
|
|
|
|
This means that {kib} will invalidate the session token it is using to
|
|
communicate with {es}, but will not be able to perform any sort of invalidation
|
|
of the Identity Provider session. In most cases this will mean that {kib} users
|
|
are still considered to be logged in to the IdP. Consequently, if the user
|
|
navigates to the {kib} landing page, they will be automatically reauthenticated,
|
|
and will commence a new {kib} 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 {kib}
|
|
- 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 {kib}.
|
|
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.
|
|
|
|
|
|
[[saml-enc-sign]]
|
|
==== 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 {es} 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 `certutil` tool that ships with X-Pack.
|
|
|
|
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.
|
|
|
|
{es} 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 {ref}/certutil.html[`certutil`] tool, you can generate a signing
|
|
certificate with the following command:
|
|
|
|
[source, sh]
|
|
--------------------------------------------------
|
|
bin/x-pack/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 {es} for Signing
|
|
|
|
By default, {security} 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 encypted. This is a
|
|
{ref}/secure-settings.html[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 encypted. This is a
|
|
{ref}/secure-settings.html[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 {es} for Encrypted Messages
|
|
|
|
{security} supports a single key for message decryption. If a key is
|
|
configured, then {security} will attempt to use it to decrypt
|
|
`EncryptedAssertion` and `EncryptedAttribute` elements in Authentication
|
|
responses, and `EncryptedID` elements in Logout requests.
|
|
|
|
{security} will reject 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, {security} will process 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 encypted. This is a
|
|
{ref}/secure-settings.html[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 encypted. This is a
|
|
{ref}/secure-settings.html[secure setting] that must be set with the
|
|
`elasticsearch-keystore` tool.
|
|
|
|
=== Generating SP metadata
|
|
|
|
Some Identity Providers support importing a metadata file from the Service
|
|
Provider. This will automatically configure many of the integration options
|
|
between the IdP and the SP.
|
|
|
|
The Elastic Stack supports generating such a metadata file using the
|
|
`bin/x-pack/saml-metadata` command in your {es} directory.
|
|
|
|
The {ref}/saml-metadata.html[documentation for the saml-metadata utility]
|
|
describes how to run it, and the available command line options.
|
|
|
|
[[saml-role-mapping]]
|
|
=== Configuring Role Mappings
|
|
|
|
When a user authenticates using SAML, they are identified to the Elastic Stack,
|
|
but this does not automatically grant them access to perform any actions or
|
|
access any data.
|
|
|
|
Your SAML users cannot do anything until they are mapped to X-Pack Security
|
|
roles. This mapping is performed through the
|
|
{ref}/security-api-role-mapping.html[role-mapping API]
|
|
|
|
This is an example of a simple role mapping that grants the `kibana_user` role
|
|
to any user who authenticates against the `saml1` realm:
|
|
|
|
[source,js]
|
|
--------------------------------------------------
|
|
PUT /_xpack/security/role_mapping/saml-kibana
|
|
{
|
|
"roles": [ "kibana_user" ],
|
|
"enabled": true,
|
|
"rules": {
|
|
"field": { "realm.name": "saml1" }
|
|
}
|
|
}
|
|
--------------------------------------------------
|
|
// CONSOLE
|
|
// TEST
|
|
|
|
|
|
The attributes that are mapped via the realm configuration are used to process
|
|
role mapping rules, and these rules determine which roles a user is granted.
|
|
|
|
The <<mapping-roles-rule-field, user fields>> that are provided to the role
|
|
mapping are derived from the SAML attributes as follows:
|
|
|
|
- `username`: The `principal` attribute
|
|
- `dn`: The `dn` attribute
|
|
- `groups`: The `groups` attribute
|
|
- `metadata`: See <<saml-user-metadata>>
|
|
|
|
If your IdP has the ability to provide groups or roles to Service Providers,
|
|
then you should map this SAML attribute to the `attributes.groups` setting in
|
|
the {es} realm, and then make use of it in a role mapping as per the example
|
|
below.
|
|
|
|
This mapping grants the {es} `finance_data` role, to any users who authenticate
|
|
via the `saml1` realm with the `finance-team` group.
|
|
|
|
[source,js]
|
|
--------------------------------------------------
|
|
PUT /_xpack/security/role_mapping/saml-finance
|
|
{
|
|
"roles": [ "finance_data" ],
|
|
"enabled": true,
|
|
"rules": { "all": [
|
|
{ "field": { "realm.name": "saml1" } },
|
|
{ "field": { "groups": "finance-team" } }
|
|
] }
|
|
}
|
|
--------------------------------------------------
|
|
// CONSOLE
|
|
// TEST
|
|
|
|
[[saml-user-metadata]]
|
|
=== User Metadata
|
|
|
|
By default users who authenticate via SAML will have some additional metadata
|
|
fields.
|
|
|
|
- `saml_nameid` will be set to the value of the `NameID` element in the SAML
|
|
authentication response
|
|
- `saml_nameid_format` will be set to the full URI of the NameID's `format`
|
|
attribute
|
|
- Every SAML Attribute that is provided in the authentication response
|
|
(regardless of whether it is mapped to an {es} user property), will be added
|
|
as the metadata field `saml(name)` where "name" is the full URI name of the
|
|
attribute. For example `saml(urn:oid:0.9.2342.19200300.100.1.3)`.
|
|
- For every SAML Attribute that has a _friendlyName_, will also be added as the
|
|
metadata field `saml_friendlyName` where "name" is the full URI name of the
|
|
attribute. For example `saml_mail`.
|
|
|
|
This behaviour can be disabled by adding `populate_user_metadata: false` to as
|
|
a setting in the saml realm.
|
|
|
|
[[saml-kibana]]
|
|
=== Configuring {kib}
|
|
|
|
SAML authentication in {kib} requires a small number of additional settings
|
|
in addition to the standard {kib} security configuration. The
|
|
{kibana-ref}/using-kibana-with-security.html[{kib} security documentation]
|
|
provides details on the available configuration options that you can apply.
|
|
|
|
In particular, since your {es} nodes have been configured to use TLS on the HTTP
|
|
interface, you must configure {kib} to use a `https` URL to connect to {es}, and
|
|
you may need to configure `elasticsearch.ssl.certificateAuthorities` to trust
|
|
the certificates that {es} has been configured to use.
|
|
|
|
SAML authentication in {kib} is also subject to the
|
|
`xpack.security.sessionTimeout` setting that is described in the {kib} security
|
|
documentation, and you may wish to adjst this timeout to meet your local needs.
|
|
|
|
The two additional settings that are required for SAML support are shown below:
|
|
|
|
[source, yaml]
|
|
------------------------------------------------------------
|
|
xpack.security.authProviders: [saml]
|
|
server.xsrf.whitelist: [/api/security/v1/saml]
|
|
------------------------------------------------------------
|
|
|
|
The configuration values used in the example above are:
|
|
|
|
`xpack.security.authProviders`::
|
|
Set this to `[ saml ]` to instruct {kib} to use SAML SSO as the authentication
|
|
method.
|
|
|
|
`server.xsrf.whitelist`::
|
|
{kib} has in-built protection against _Cross Site Request Forgery_ attacks which
|
|
are designed to prevent the {kib} server from processing requests that
|
|
originated from outside the {kib} application.
|
|
In order to support SAML authentication messages that originate from your
|
|
Identity Provider, we need to explicitly _whitelist_ the SAML authentication URL
|
|
within {kib}, so that the {kib} server will not reject these external messages.
|
|
|
|
If your {kib} instance is behind a proxy, you may also need to add configuration
|
|
to tell {kib} how to form its public URL. This is needed because all SAML
|
|
messages are exchanged via the user's web browser, so {kib} needs to know what
|
|
URLs are used within the browser. In this case, the following settings should be
|
|
added to your `kibana.yml` configuration file:
|
|
|
|
[source, yaml]
|
|
------------------------------------------------------------
|
|
xpack.security.public:
|
|
protocol: https
|
|
hostname: kibana.proxy.com
|
|
port: 443
|
|
------------------------------------------------------------
|
|
|
|
`xpack.security.public.protocol`::
|
|
This is the protocol that the user's web browser uses to connect to the proxy.
|
|
Must be one of `http` or `https`. It is strongly recommended that you use the
|
|
`https` protocol for all access to {kib}.
|
|
|
|
`xpack.security.public.hostname`::
|
|
The fully qualified hostname that your users use to connect to the proxy server.
|
|
|
|
`xpack.security.public.port`::
|
|
The port number that your users use to connect to the proxy server (e.g. `80`
|
|
for `http` or `443` for `https`).
|
|
|
|
These values must be aligned with the URLs used in the {es} configuration for
|
|
`sp.acs` and `sp.logout`.
|
|
|
|
==== Supporting SAML and Basic authentication in {kib}
|
|
|
|
The SAML support in {kib} is designed on the expectation that it will be the
|
|
primary (or sole) authentication method for users of that {kib} instance.
|
|
However, it is possible to support both SAML and Basic authentication within a
|
|
single {kib} instance by setting `xpack.security.authProviders` as per the
|
|
example below:
|
|
|
|
[source, yaml]
|
|
------------------------------------------------------------
|
|
xpack.security.authProviders: [saml, basic]
|
|
------------------------------------------------------------
|
|
|
|
The order is important - this will _initiate_ SAML authentication for
|
|
unauthenticated users, but will _accept_ basic authentication.
|
|
|
|
If {kib} is configured in this way, then users who wish to login with a
|
|
username and password, can do so by directly accessing the `/login` page in
|
|
{kib}. This login will not use SAML credentials, and will rely on one of the
|
|
other security realms within {es}. Only users who have a username and password
|
|
for a configured {es} authentication realm will be able to login via this page.
|
|
|
|
Alternatively, when the `basic` authentication provider is enabled, you can
|
|
place a reverse proxy in front of {kib}, and configure it to send a basic
|
|
authentication header (`Authorization: Basic ....`) for each request.
|
|
If this header is present and valid, {kib} will not initiate the SAML
|
|
authentication process.
|
|
|
|
==== Operating multiple {kib} instances
|
|
|
|
If you wish to have multiple {kib} instances that authenticate against the same
|
|
{es} cluster, then each {kib} instance that is configured for SAML authentication,
|
|
requires its own SAML realm.
|
|
|
|
Each SAML realm must have its own unique Entity ID (`sp.entity_id`), and its own
|
|
_Assertion Consumer Service_ (`sp.acs`). Each {kib} instance will be mapped to
|
|
the correct realm by looking up the matching `sp.acs` value.
|
|
|
|
These realms may use the same Identity Provider, but are not required to.
|
|
|
|
The following is example of having 3 difference {kib} instances, 2 of which
|
|
use the same internal IdP, and another which uses a different IdP.
|
|
|
|
[source, yaml]
|
|
------------------------------------------------------------
|
|
xpack.security.authc.realms.saml_finance:
|
|
type: saml
|
|
order: 2
|
|
idp.metadata.path: saml/idp-metadata.xml
|
|
idp.entity_id: "https://sso.example.com/"
|
|
sp.entity_id: "https://kibana.finance.example.com/"
|
|
sp.acs: "https://kibana.finance.example.com/api/security/v1/saml"
|
|
sp.logout: "https://kibana.finance.example.com/logout"
|
|
attributes.principal: "urn:oid:0.9.2342.19200300.100.1.1"
|
|
attributes.groups: "urn:oid:1.3.6.1.4.1.5923.1.5.1."
|
|
xpack.security.authc.realms.saml_sales:
|
|
type: saml
|
|
order: 3
|
|
idp.metadata.path: saml/idp-metadata.xml
|
|
idp.entity_id: "https://sso.example.com/"
|
|
sp.entity_id: "https://kibana.sales.example.com/"
|
|
sp.acs: "https://kibana.sales.example.com/api/security/v1/saml"
|
|
sp.logout: "https://kibana.sales.example.com/logout"
|
|
attributes.principal: "urn:oid:0.9.2342.19200300.100.1.1"
|
|
attributes.groups: "urn:oid:1.3.6.1.4.1.5923.1.5.1."
|
|
xpack.security.authc.realms.saml_eng:
|
|
type: saml
|
|
order: 4
|
|
idp.metadata.path: saml/idp-external.xml
|
|
idp.entity_id: "https://engineering.sso.example.net/"
|
|
sp.entity_id: "https://kibana.engineering.example.com/"
|
|
sp.acs: "https://kibana.engineering.example.com/api/security/v1/saml"
|
|
sp.logout: "https://kibana.engineering.example.com/logout"
|
|
attributes.principal: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"
|
|
------------------------------------------------------------
|
|
|
|
It is possible to have one or more {kib} instances that use SAML, while other
|
|
instances use basic authentication against another realm type (e.g.
|
|
<<native-realm, Native>> or <<ldap-realm, LDAP>>).
|
|
|