SAML troubleshooting

If you encounter any problems while using SAML, please check the following steps to pinpoint the problem.

Check the sp.entity_id

Most IdPs allow you to configure multiple authentication methods for different client applications. For example, in Okta these are called “Applications”, in Keycloak they are called “Clients”. Each of these applications has their entity ID. Make sure to configure the sp.entity_id to match your settings.

Keycloak example:

Okta example:

Search Guard configuration:

saml:
   ...
   http_authenticator:
      type: 'saml'
      challenge: true
      config:
        ...
        sp:
          entity_id: kibana-saml

Check the SAML Assertion Consumer Service URL

After a successful login, your IdP sends a SAML Response via HTTP POST to the so-called “Assertion Consumer Service URL” of Kibana.

The endpoint Search Guard Kibana plugin provides is:

/searchguard/saml/acs

Make sure that you have configured this endpoint correctly in your IdP. Some IdPs also require you to whitelist all endpoints it will send requests to. Make sure the ACS endpoint is listed.

Okta example:

Kibana also requires you to whitelist this endpoint. Make sure you have the following entry in your kibana.yml:

server.xsrf.whitelist: [/searchguard/saml/acs]

Make sure all documents are signed

Some IdPs do not sign the SAML documents by default. Make sure the IdP signs all documents.

Keycloak example:

Role settings

How to include user roles in the SAML response is highly dependant on the IdP. For example, in Keycloak this is configured in the Mappers section of your client. With Okta you have to set group attribute statements. Make sure this is configured correctly, and the role_key in the SAML configuration matches the role name in the SAML response.

Keycloak example:

Okta example:

Search Guard configuration:

saml:
   ...
   http_authenticator:
      type: 'saml'
      challenge: true
      config:
        ...
        roles_key: Role

Inspecting the SAML Response

If you are not sure how the SAML Response of your IdP looks like and where it places the username and roles, you can enable the token debug mode in the log4j2.properties like:

logger.token.name = com.floragunn.dlic.auth.http.saml.Token
logger.token.level = debug

This will print out the SAML response in the Elasticsearch log file so you can inspect and debug it. Setting this logger to `debug will generate a lot of statements, so it’s not recommended to do it in production. Log levels can also be changed at run time, please see the Elasticsearch official documentation on how to do that.

Another way of inspecting the SAML Response is to montitor the network traffic while logging in to Kibana. The IdP will HTTP POST the base64-encoded SAML Response to:

/searchguard/saml/acs

Inspect the payload of this POST request and use a tool like https://www.base64decode.org/ to decode it.

Checking the role mapping: NamedID and Roles

Search Guard uses the normal role mapping to map a user or a backed role to one or more Search Guard roles.

For the username Search Guard uses the NameID attribute of the SAML Response by default. For some IdPs, this attribute does not contain the expected username, but some internal user id. Please check the content of the SAML Response to locate the element you want to use as username, and configure it by setting the subject_key in the SAML configuration:

saml:
   ...
   http_authenticator:
      type: 'saml'
      challenge: true
      config:
        ...
        subject_key: preferred_username

For checking that the correct roles are contained in the SAML Response, inspect the contents as well and set the correct attribute name like:

saml:
   ...
   http_authenticator:
      type: 'saml'
      challenge: true
      config:
        ...
        roles_key: Role

Inspecting the JWT token

Search Guard trades the heavyweight SAML response for a more lightweight JSON web token. The username and roles in the JWT are ultimately mapped to Search Guard roles. If there is a problem with the mapping, you can enable the token debug mode in the log4j2.properties like:

logger.token.name = com.floragunn.dlic.auth.http.saml.Token
logger.token.level = debug

This will print the JWT in the logfile. You can then decode the JWT and inspect its content, for example by using https://jwt.io/.