Configure OpenSearch SSO with Okta
ClusterNest Managed OpenSearch can delegate Dashboards login to Okta over OIDC or SAML. A cluster takes several auth sources side by side, with at most one SAML source and one OIDC source offered on Dashboards.
You'll need your cluster's OpenSearch Dashboards hostname before registering the app. Set dashboards_custom_hostname so you know it upfront, or create the cluster first without an auth source and note the generated opensearch_dashboards_url output before adding it.
- OIDC
- SAML
OIDC
connect_url is your Okta domain's discovery endpoint (or a custom authorization server's, if you used one instead of default).
- Console
- Terraform
- In the Okta admin console, go to Applications > Create App Integration, choose OIDC - Web Application.
- Sign-in redirect URIs:
https://<dashboards-hostname>/auth/openid/login - Assign the app to the users or groups who should have access.
- Sign-in redirect URIs:
- On the app's General tab, note the Client ID and Client secret.
- To get a
groupsclaim into the ID token, go to Security > API > Authorization Servers, pick the server you're using (defaultfor the org authorization server), open the Claims tab, and add a claim namedgroups(Include in: ID Token, Value type: Groups, Filter: matches a regex, e.g..*).
In the ClusterNest console, open the cluster's create/edit form and add an OIDC source under Authentication. Choose a Name (it becomes the text of the Dashboards button, "Login with" followed by this name), tick Offer on OpenSearch Dashboards, then fill in:
- Connect URL:
https://example.okta.com/.well-known/openid-configuration - Client ID / Client Secret: from the app's General tab
- Roles Key:
groups(leave blank if you skipped step 3)
Okta's official provider (okta/okta) creates the app and the groups claim in the same config as the ClusterNest cluster:
terraform {
required_providers {
okta = {
source = "okta/okta"
version = "~> 5.0"
}
clusternest = {
source = "tf.clusternest.com/clusternest/clusternest"
version = ">=1.1.0"
}
}
}
provider "okta" {
org_name = "example"
base_url = "okta.com"
api_token = var.okta_api_token
}
provider "clusternest" {
email = "[email protected]"
password = var.clusternest_app_password
}
locals {
dashboards_hostname = "opensearch-dashboards.example.com"
}
resource "okta_app_oauth" "opensearch" {
label = "OpenSearch Dashboards"
type = "web"
grant_types = ["authorization_code"]
response_types = ["code"]
redirect_uris = ["https://${local.dashboards_hostname}/auth/openid/login"]
}
resource "okta_auth_server_claim" "groups" {
auth_server_id = "default"
name = "groups"
value_type = "GROUPS"
claim_type = "IDENTITY"
value = ".*"
}
resource "clusternest_opensearch" "sso" {
name = "logs"
tier = "standard"
organization_id = 123
auth_sources = [
{
name = "okta"
type = "oidc"
connect_url = "https://example.okta.com/.well-known/openid-configuration"
client_id = okta_app_oauth.opensearch.client_id
client_secret = okta_app_oauth.opensearch.client_secret
roles_key = "groups"
dashboards_login = true
},
]
dashboards_custom_hostname = local.dashboards_hostname
}
okta_app_oauth.opensearch.client_secret is computed once the app is created - it lands in plain text in the state file, same as any Terraform-managed secret. Drop the okta_auth_server_claim resource and roles_key if you don't need role mapping, and assign the app to users/groups separately with okta_app_group_assignment or okta_app_user.
SAML
idp_metadata_url and idp_entity_id come straight from Okta's own setup instructions. Drop roles_key if you don't need role mapping (it defaults to an ADFS-style claim URI Okta never emits).
- Console
- Terraform
- In the Okta admin console, go to Applications > Create App Integration, choose SAML 2.0.
- On the Configure SAML step:
- Single sign-on URL:
https://<dashboards-hostname>/_opendistro/_security/saml/acs(leave "Use this for Recipient URL and Destination URL" checked) - Audience URI (SP Entity ID): the value you'll use as
sp_entity_idbelow - Name ID format: EmailAddress
- Under Attribute Statements or Group Attribute Statements, add an attribute (e.g.
groups, matching a regex) if you want role mapping.
- Single sign-on URL:
- Assign the app to the relevant users/groups, then open its Sign On tab and click View SAML setup instructions - it lists the Identity Provider metadata URL and the Identity Provider Issuer.
In the ClusterNest console, open the cluster's create/edit form and add a SAML source under Authentication. Choose a Name (it becomes the text of the Dashboards button, "Login with" followed by this name), then fill in:
- IDP Metadata URL:
https://example.okta.com/app/exkabc123/sso/saml/metadata - IDP Entity ID:
http://www.okta.com/exkabc123 - SP Entity ID:
opensearch-dashboards - Roles Key:
groups(leave blank if you skipped the attribute statement)
okta_app_saml exposes the resulting metadata URL and entity ID as computed attributes, so they can be wired directly into the clusternest_opensearch resource:
terraform {
required_providers {
okta = {
source = "okta/okta"
version = "~> 5.0"
}
clusternest = {
source = "tf.clusternest.com/clusternest/clusternest"
version = ">=1.1.0"
}
}
}
provider "okta" {
org_name = "example"
base_url = "okta.com"
api_token = var.okta_api_token
}
provider "clusternest" {
email = "[email protected]"
password = var.clusternest_app_password
}
locals {
dashboards_hostname = "opensearch-dashboards.example.com"
}
resource "okta_app_saml" "opensearch" {
label = "OpenSearch Dashboards"
sso_url = "https://${local.dashboards_hostname}/_opendistro/_security/saml/acs"
recipient = "https://${local.dashboards_hostname}/_opendistro/_security/saml/acs"
destination = "https://${local.dashboards_hostname}/_opendistro/_security/saml/acs"
audience = "opensearch-dashboards"
subject_name_id_template = "$${user.email}"
subject_name_id_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
attribute_statements {
type = "GROUP"
name = "groups"
filter_type = "REGEX"
filter_value = ".*"
}
}
resource "clusternest_opensearch" "sso" {
name = "logs"
tier = "standard"
organization_id = 123
auth_sources = [
{
name = "okta"
type = "saml"
idp_metadata_url = okta_app_saml.opensearch.metadata_url
idp_entity_id = okta_app_saml.opensearch.entity_url
sp_entity_id = "opensearch-dashboards"
roles_key = "groups"
},
]
dashboards_custom_hostname = local.dashboards_hostname
}
Drop the attribute_statements block and roles_key if you don't need role mapping.
See the Terraform resource reference for the full field list.