Integrations · OIDC

Kibana / OpenSearch SSO

Configure OIDC SSO for Kibana (Elasticsearch) and OpenSearch Dashboards using Clavex. Covers both the Elastic stack (8.x) and the OpenSearch community fork. Role mapping from Clavex group or realm_access claims is included.

License note: OIDC SSO for Kibana requires an Elastic Platinum or higher license. For the open-source alternative, use OpenSearch with the Security plugin (free). Both configurations are covered below.

Prerequisites


Step 1 — Register OIDC Client in Clavex

Admin API (curl)
$ curl -X POST https://id.acme.eu/api/v1/organizations/acme/clients \ -H 'Authorization: Bearer $ADMIN_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "client_id": "kibana", "client_name": "Kibana", "grant_types": ["authorization_code", "refresh_token"], "redirect_uris": ["https://kibana.acme.eu/api/security/oidc/callback"], "scopes": ["openid", "profile", "email", "groups"], "token_endpoint_auth_method": "client_secret_post" }'

Step 2a — Elastic Stack (Kibana 8.x)

elasticsearch.yml

elasticsearch.yml
xpack.security.authc.realms.oidc.clavex: order: 1 rp.client_id: "kibana" rp.response_type: "code" rp.redirect_uri: "https://kibana.acme.eu/api/security/oidc/callback" rp.requested_scopes: ["openid", "profile", "email", "groups"] op.issuer: "https://id.acme.eu/acme" op.authorization_endpoint: "https://id.acme.eu/acme/authorize" op.token_endpoint: "https://id.acme.eu/acme/token" op.userinfo_endpoint: "https://id.acme.eu/acme/userinfo" op.jwkset_path: "https://id.acme.eu/acme/jwks" claims.principal: "email" claims.groups: "groups"
bash — store client secret in keystore
$ elasticsearch-keystore add xpack.security.authc.realms.oidc.clavex.rp.client_secret Enter value for xpack.security.authc.realms.oidc.clavex.rp.client_secret: cs_xxxxxxxxxxxxxxxx

kibana.yml

kibana.yml
xpack.security.authc.providers: oidc.clavex: order: 0 realm: "clavex" description: "Sign in with Clavex" icon: "https://id.acme.eu/logos/clavex.svg" hint: "SSO via corporate identity" basic.basic: order: 1

Role mapping (elasticsearch)

bash
$ curl -u elastic:$ES_PASS -X PUT \ https://elasticsearch.acme.eu:9200/_security/role_mapping/clavex-admins \ -H 'Content-Type: application/json' \ -d '{ "roles": ["kibana_admin", "monitoring_user"], "rules": { "field": { "groups": "kibana-admins" } }, "enabled": true }'

Step 2b — OpenSearch Dashboards

Edit opensearch_dashboards.yml:

opensearch_dashboards.yml
opensearch_security.auth.type: "openid" opensearch_security.openid.connect_url: "https://id.acme.eu/acme/.well-known/openid-configuration" opensearch_security.openid.client_id: "kibana" opensearch_security.openid.client_secret: "cs_xxxxxxxxxxxxxxxx" opensearch_security.openid.scope: "openid profile email groups" opensearch_security.openid.base_redirect_url: "https://dashboards.acme.eu" opensearch_security.openid.trust_dynamic_headers: false

Troubleshooting

SymptomCauseFix
Unable to perform OIDC authentication Client secret not in keystore or wrong Re-add with elasticsearch-keystore add; restart Elasticsearch
Users have no role after login Role mapping missing or groups claim not populated Verify role mapping via GET /_security/role_mapping; check groups claim in token
Redirect loop between Kibana and Clavex Kibana session cookie not set (domain/protocol mismatch) Ensure server.publicBaseUrl in kibana.yml matches the browser URL exactly
JWK set fetch fails Elasticsearch can't reach Clavex JWKS URL Use op.jwkset_path with a local file path as fallback: download JWKS and point to file