Skip to content

Instantly share code, notes, and snippets.

@paulgrav
Last active September 10, 2023 08:54
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulgrav/31909667f96614a645b1ceec5b9b06b0 to your computer and use it in GitHub Desktop.
Save paulgrav/31909667f96614a645b1ceec5b9b06b0 to your computer and use it in GitHub Desktop.
Setting up Azure AD OpenID Connect with Kibana

Enabled Azure AD with Kibana

1. Configure Elasticsearch

As a pre-requisite we need to register a new app in Azure AD, note down some properties, and generate a Client Secret.

  1. Register an app in Azure Active Directory.
  2. Note its Application (client) ID
  3. Note the Directory (tenant) ID
  4. Generate a New Client Secret.

elasticsearch.yml

xpack:
  security:
    authc:
      realms:
        oidc:
          cloud-oidc:
            order: 2
            rp.client_id: "<CLIENT_ID>"
            rp.response_type: code
            rp.redirect_uri: "https://<KIBANA_HOST>/api/security/v1/oidc"
            op.issuer: "<OP_ISSUER>"
            op.authorization_endpoint: "<OP_AUTH>"
            op.token_endpoint: "<OP_TOKEN>"
            op.jwkset_path: "<OP_JWKSET_PATH>"
            op.userinfo_endpoint: "<OP_USERINFO>"
            op.endsession_endpoint: "<OP_ENDSESSION>"
            rp.post_logout_redirect_uri: "<KIBANA_HOST>/logged_out"
            claims.principal: sub

Many of the missing values can be found in your tenant’s .well-known/openid-configuration endpoint. You can use your tenant ID to call it.

curl https://login.microsoftonline.com/<TENANT_ID>/v2.0/.well-known/openid-configuration | jq
{
  "authorization_endpoint": "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/authorize",
  "token_endpoint": "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token",
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "private_key_jwt",
    "client_secret_basic"
  ],
  "jwks_uri": "https://login.microsoftonline.com/<TENANT_ID>/discovery/v2.0/keys",
  "response_modes_supported": [
    "query",
    "fragment",
    "form_post"
  ],
  "subject_types_supported": [
    "pairwise"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "http_logout_supported": true,
  "frontchannel_logout_supported": true,
  "end_session_endpoint": "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/logout",
  "response_types_supported": [
    "code",
    "id_token",
    "code id_token",
    "id_token token"
  ],
  "scopes_supported": [
    "openid",
    "profile",
    "email",
    "offline_access"
  ],
  "issuer": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
  "claims_supported": [
    "sub",
    "iss",
    "cloud_instance_name",
    "cloud_instance_host_name",
    "cloud_graph_host_name",
    "msgraph_host",
    "aud",
    "exp",
    "iat",
    "auth_time",
    "acr",
    "nonce",
    "preferred_username",
    "name",
    "tid",
    "ver",
    "at_hash",
    "c_hash",
    "email"
  ],
  "request_uri_parameter_supported": false,
  "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo",
  "tenant_region_scope": "EU",
  "cloud_instance_name": "microsoftonline.com",
  "cloud_graph_host_name": "graph.windows.net",
  "msgraph_host": "graph.microsoft.com",
  "rbac_url": "https://pas.windows.net"
}

2. Configure Kibana

Kibana needs to be told about its new auth provider, it’s Open ID Connect realm, and to whitelist calls to /api/security/v1/oidc

kibana.yml

xpack.security.authProviders: [oidc, basic]
xpack.security.authc.oidc.realm: "cloud-oidc" 
server.xsrf.whitelist: [/api/security/v1/oidc]

3. Create Kibana role mapping

Send the following request to your Elasticsearch instance.

PUT /_security/role_mapping/oidc-kibana
{
  "roles": [ "kibana_user" ],
  "enabled": true,
  "rules": {
    "field": { "realm.name": "cloud-oidc" }
  }
}

This will map everyone authenticating from OIDC to the kibana_user role. If this isn’t suitable then you will need to use a claim.groups in the elasticsearch.yml to be able to achieved more fine-grain control.

Notes

It’s critical that your OIDC realm be called cloud-oidc otherwise nothing works.

@fr34kyn01535
Copy link

fr34kyn01535 commented Apr 28, 2020

You forgot to mention to add the Azure Application Client Secret to the Elasticsearch config with elastistack-keystore add xpack.security.authc.realms.oidc.cloud-oidc.rp.client_secret..

@alphakilo7
Copy link

Hi. I would like to know if it is required to purchase Gold/Platinum (Xpack) license for this process or can be done with Basic license only.

@paulgrav
Copy link
Author

paulgrav commented Nov 6, 2020

I think it’s Gold and above.

@alphakilo7
Copy link

alphakilo7 commented Nov 6, 2020

Okay. Thank you. Can you suggest any free way for authenticating Kibana using SSO, something like Keycloak.

@paulgrav
Copy link
Author

paulgrav commented Nov 6, 2020

I don’t know your use case but this is what I did at home:

User ----[https]-----> Cloudflare Gateway using Github IdP ------[https]---->Traefik----[http]----->kibana

I configure Cloudflare to only auth users with my domain in their Github email address. Traefik ingress handles the provisioning of letsencrypt cert. My origin (Traefik) secured by only allowing a client cert configured on Cloudflare.

@alphakilo7
Copy link

That sound interesting! Is there any documentation or references available for this process? That would be a lot of help.
My use case: I have Elastic stack running. Kibana is currently secured with basic auth/native realm. I want to implement SSO using Github or Google or my Kibana.

@paulgrav
Copy link
Author

paulgrav commented Nov 6, 2020

There weren’t any blog posts that I followed. I should perhaps write that up myself.

@alphakilo7
Copy link

That is really great! I would really encourage you to document this. The Keycloak + Kibana is not documented at all. I tried hard to find if it is possible, but was disappointed at last. If you ever create such blog or a documentation, it will help a lot of people. (and of course me! 😉)

@codercotton
Copy link

codercotton commented Jun 7, 2021

You forgot to mention to add the Azure Application Client Secret to the Elasticsearch config with elastistack-keystore add xpack.security.authc.realms.oidc.cloud-oidc.rp.client_secret..

How can this be accomplished? The pod fails to start if the client_secret isn't in the keystore, and using this command in the initContainer doesn't seem to work.

Edit: I got it going via the initContainer like so:

        initContainers:
        - name: keystore
          securityContext:
            privileged: true
          command: 
            - sh
            - -c
            - |
              rm -rfv config/elasticsearch.keystore
              yes | bin/elasticsearch-keystore create
              echo -n '{{ .Values.client_secret }}' | bin/elasticsearch-keystore add --stdin xpack.security.authc.realms.oidc.oidc1.rp.client_secret

@codercotton
Copy link

codercotton commented Jun 11, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment