SSO and RBAC for Elasticsearch (Kibana)


This page documents the steps for:

  • using an external Identity Provider for user authentication to Kibana (single sign-on, aka SSO)
  • providing differentiated access to Kibana based on the assigned role to the authenticated user (role-based access control, aka RBAC)

We will use Okta as our IdP, SAML for authentication, and Okta Directory for User Groups (equivalent to LDAP or Active Directory). We will use Elasticsearch’s support for SAML for SSO. We will use Elasticsearch’s support for roles and role mappings at a group level to implement RBAC.

I have tested the steps below with a cloud-based trial Elastic deployment and a trial version of Okta.

Note:

  • SSO requires a paid license to Elastic (Platinum and above).
  • However, RBAC is part of the free license

Scope

This document targets user authentication for Elasticsearch with SAML. We will have a separate document for client-program authentication using OIDC.

We will use Kibana-specific roles for validation, but we can use similar roles to control access to Elasticsearch data (indices) as well.

Roles can also be specified for document- and field-level security, if that is what we want to accomplish. I have earlier validated field-level security in Elasticsearch.

Findings

I was successful in using Okta for SSO to my Kibana deployment. I was also successful in using two different user groups with varying levels of access.

Elasticsearch requires role mappings for any groups obtained during authentication. i.e., Elasticsearch needs to know ahead of time what capabilities the user or the group has within Elastsicsearch. This is necessary complexity, but can be minimized by using built-in roles within Elasticsearch.

Next, we list out the steps required to validate SSO and RBAC.

Steps: High Level

On Okta, create two groups with one user each.

On Okta, create an application for Elasticsearch. On Elasticsearch, specify a SAML realm and provider.

On Elasticsearch, create role mappings for the two groups. One is an admin group, another is a read-only group.

Use Okta to log in to Kibana as admin user. Verify that the user can create a dashboard.

Use Okta to log in to Kibana as read-only user. Verify that the user cannot create a dashboard, but can view a dashboard.

Steps in Detail

Elasticsearch: Phase 1

On Elasticsearch Cloud, create a new Elasticsearch deployment.

When the deployment is ready, go to “Manage” and then “Edit”, click on “Manage user settings and extensions”.

Add the following configuration:

xpack.security.authc.realms.saml.saml1:
  order: 2
  attributes.principal: "nameid"
  attributes.groups: "groups"
  # can be empty for now, will replace with your Okta metadata URL
  idp.metadata.path: "https://trial-7706346.okta.com/app/exkqmymdkwn2fxGI7697/sso/saml/metadata"
  # can be empty for now, will replace with your Okta entity ID
  idp.entity_id: "http://www.okta.com/exkqmymdkwn2fxGI7697"
  # can be empty for now, will replace with your Kibana deployment URL
  # note: "kb" indicates Kibana, we will use SAML to authenticate Okta users to Kibana
  sp.entity_id: "https://es-acl.kb.us-central1.gcp.cloud.es.io/"
  # replace with your Kibana ACS URL
  sp.acs: "https://es-acl.kb.us-central1.gcp.cloud.es.io/api/security/saml/callback"
  # replace with your Kibana logout URL
  sp.logout: "https://es-acl.kb.us-central1.gcp.cloud.es.io/logout"

Enable self-monitoring on the deployment. Under the “Manage” tab, click on “Monitoring” > “Logs and metrics”. Add a deployment, shipping data to the same instance.

Okta

Create two groups on Okta, one with admin access and one with read-only access. Add a unique email address to each group.

(Note the KB* groups I have created)

Create an application in Okta for Elasticsearch, with SAML authentication.

For “Single Sign On URL”, note the Kibana endpoint URL from the Elasticsearch deployment. The URL will be <kibana-endpoint-url>/api/v1/saml.

For “Audience URI (SP Entity ID)”, it is the Kibana endpoint URL from the Elasticsearch deployment. Be sure to include the trailing slash.

Set name ID format to “email address”.

Creating a SAML app integration in Okta

Under “Group Attribute Statements”, set the name “groups” to start with “KB”.

This is important! This will allow our group information to be passed to Kibana.

(Specifying Group Attribute statements in Okta)

You can leave the rest of the fields to their defaults, and complete the setup.

Next, under “Sign On” tab, note the value for “metadata URL”. This will be our idp.metadata.path from the Elasticsearch configuration next.

Click on “More details” and note the value of “issuer”. This will be our idp.entity_id from the Elasticsearch configuration next.

Assign the groups we created earlier to the application.

Elasticsearch: Phase 2

Now go back to the Elasticsearch deployment, and click on “Manage” and then “Edit”, click on “Manage user settings and extensions”.

Set idp.metadata.path from “metadata URL” we copied earlier from the Okta application.

Set idp.entity_id from “Issuer” we copied earlier from the Okta application.

As before, be sure to click “Back”, then go to the bottom of the page and click “Save” to apply the configuration. Otherwise, the changes will be lost.

Now, we will enable Okta login for Kibana. After the deployment is ready, go to the Elasticsearch deployment, and click on “Manage” and under “Kibana”, click on “Edit user settings”.

Add the following configuration:

xpack.security.authc.providers:
  saml.saml1:
    order: 0
    realm: "saml1"
    description: "Log in with Okta"
    icon: "https://www.okta.com/themes/custom/okta_www_theme/images/logo.svg"
  basic.basic1:
    order: 1

Again, click “Save” to apply the configuration and wait for the deployment to restart.

Final Step: SSO and RBAC

On the Elasticsearch deployment, go to Content > “Index Management”. Click on the console and paste the following to map our Okta users to two built-in ES roles.

PUT /_security/role_mapping/saml-owner-superuser
{
  "roles": [ "kibana_admin" ],
  "enabled": true,
  "rules": { "all": [
    	{ "field": { "realm.name": "saml1" } },
     { "field": { "groups": "KBAdminUsers" } }
  ] }
}


PUT /_security/role_mapping/saml-owner-readonly
{
  "roles": [ "viewer" ],
  "enabled": true,
  "rules": { "all": [
    	{ "field": { "realm.name": "saml1" } },
 	{ "field": { "groups": "KBReadonlyUsers" } }
  ] }
}

Alternatively, this can also be done on the UI under “Stack Management”, then “Role Mappings”.

(Note the mapping to viewer and kibana_admin roles)

At this point, any authenticated Okta user that belongs to the KBAdminUsers Okta group will have write access to Kibana and can create dashboards etc. Similarly, a Okta user in the KBReadOnlyUsers Okta group can only view Kibana dashboards.

Troubleshooting

In case of Okta authentication issues, go to the Okta application, and click on “View logs”. It will show which step failed. In case it says “SUCCESS”, but you see an error in Kibana, it is likely that the sp.acs URL is incorrect.

On Elasticsearch, use this link for troubleshooting SAML errors.

Additional logging as follows can also help on the side of Elasticsearch:

PUT /_cluster/settings
{
  "persistent": {
    "logger.org.elasticsearch.xpack.security.authc": "debug"
  }
}

Reference

This document was my reference for this integration.

For document- and field-level security, see this ES official document.

Appendix: Logs

Successful login for an admin user. Note that the Okta group KBAdminUsers was mapped to the Elastic role kibana_admin.

Authentication of [] using realm [saml/saml1] with token [SamlToken] was [AuthenticationResult{status=SUCCESS, value=User[username=deepak.nagaraj@example.com,roles=[kibana_admin],fullName=null,email=null,metadata={saml(groups)=[KBAdminUsers], saml_nameid=deepak.nagaraj@example.com, saml_nameid_format=urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress}], message=null, exception=null}]

Successful login for a “read-only” user. Note that the Okta group KBReadOnlyUsers was mapped to the Elastic role viewer.

Authentication of [] using realm [saml/saml1] with token [SamlToken] was [AuthenticationResult{status=SUCCESS, value=User[username=n.deepak@gmail.com,roles=[viewer],fullName=null,email=null,metadata={saml(groups)=[KBReadOnlyUsers], saml_nameid=n.deepak@gmail.com, saml_nameid_format=urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress}], message=null, exception=null}]

(Auth logs for admin and read-only users)

See also