# OpenID Keycloak working with OpenSearch 2.11.1 but not passing roles

**URL:** <https://forum.opensearch.org/t/openid-keycloak-working-with-opensearch-2-11-1-but-not-passing-roles/17285>\
**Category:** Security\
**Tags:** discuss, troubleshoot, configure\
**Created:** [December 29, 2023, 7:07pm UTC](https://forum.opensearch.org/t/openid-keycloak-working-with-opensearch-2-11-1-but-not-passing-roles/17285 "2023-12-29T19:07:21Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ActiveSync](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/activesync/32/6710_2.png) [@ActiveSync](https://forum.opensearch.org/u/ActiveSync)\
**Post date:** [December 29, 2023, 7:07pm UTC](https://forum.opensearch.org/t/openid-keycloak-working-with-opensearch-2-11-1-but-not-passing-roles/17285/1 "2023-12-29T19:07:21Z")

</div>

**Opensearch version** : 2.11.1  
**Keycloak version** : 21.1.2

I’m using opensearch on VM via ansible (copy\_custom\_security\_configs: **false** ), Dashboard via helm (behind ingress-nginx k8s).  
Authorization via openid keycloak work, but not passing roles(?).  
What did I miss?

**Configuration Security Opensearch** :

```auto
{
    "config": {
        "dynamic": {
            "filtered_alias_mode": "warn",
            "disable_rest_auth": false,
            "disable_intertransport_auth": false,
            "respect_request_indices_options": false,
            "kibana": {
                "multitenancy_enabled": true,
                "private_tenant_enabled": true,
                "default_tenant": "",
                "server_username": "kibanaserver",
                "index": ".kibana"
            },
            "http": {
                "anonymous_auth_enabled": false,
                "xff": {
                    "enabled": true,
                    "internalProxies": ".*",
                    "remoteIpHeader": "x-forwarded-for"
                }
            },
            "authc": {
                "openid_auth_domain": {
                    "http_enabled": true,
                    "transport_enabled": true,
                    "order": 1,
                    "http_authenticator": {
                        "challenge": false,
                        "type": "openid",
                        "config": {
                            "enable_ssl": true,
                            "verify_hostnames": true,
                            "pemtrustedcas_filepath": "/usr/share/opensearch/config/root-ca-keycloak.pem",
                            "subject_key": "preferred_username",
                            "roles_key": "roleopen",
                            "openid_connect_url": "https://{{ keycloak_url }}/realms/{{ realm }}/.well-known/openid-configuration",
                            "kibana_url": "https://{{ dashboard-k8s }}"
                        }
                    },
                    "authentication_backend": {
                        "type": "noop",
                        "config": {}
                    },
                    "description": "Authenticate via OpenID"
                },
                "basic_internal_auth_domain": {
                    "http_enabled": true,
                    "transport_enabled": false,
                    "order": 0,
                    "http_authenticator": {
                        "challenge": false,
                        "type": "basic",
                        "config": {}
                    },
                    "authentication_backend": {
                        "type": "internal",
                        "config": {}
                    },
                    "description": "Authenticate via HTTP Basic against internal users database"
            },
            "authz": {},
            "auth_failure_listeners": {},
            "do_not_fail_on_forbidden": false,
            "multi_rolespan_enabled": true,
            "hosts_resolver_mode": "ip-only",
            "do_not_fail_on_forbidden_empty": false
        }
    }
}

```

> **opensearch.yml**
>
> ```auto
> cluster.name: "development-cluster"
> node.name: "os1"
> network.host: "10.0.0.14"
> http.port: 9200
> discovery.type: single-node
> bootstrap.memory_lock: true
> plugins.security.allow_default_init_securityindex: true
> plugins.security.audit.type: internal_opensearch
> plugins.security.enable_snapshot_restore_privilege: true
> plugins.security.check_snapshot_restore_write_privileges: true
> plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]
> plugins.security.unsupported.restapi.allow_securityconfig_modification: true
> plugins.security.ssl.transport.pemcert_filepath: os1.pem
> plugins.security.ssl.transport.pemkey_filepath: os1.key
> plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
> plugins.security.ssl.transport.enforce_hostname_verification: false
> plugins.security.ssl.transport.resolve_hostname: false
> plugins.security.ssl.http.enabled: true
> plugins.security.ssl.http.pemcert_filepath: os1_http.pem
> plugins.security.ssl.http.pemkey_filepath: os1_http.key
> plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
> plugins.security.nodes_dn:
> - CN=os1.{{ opensearch }},OU=Ops,O={{ opensearch }}\,
> Inc.,DC={{ opensearch }}
> plugins.security.authcz.admin_dn:
> - CN=admin.{{ opensearch }},OU=Ops,O={{ opensearch }}\,
> Inc.,DC=mydomain
> ## END opensearch Security Node & Admin certificates configuration ##
> 
> ```

> **Values helm chart dashboard**
>
> ```auto
> opensearchHosts: "https://{{ opensearch }}:9200"
> replicaCount: 1
> 
> image:
> repository: "opensearchproject/opensearch-dashboards"
> tag: "2.4.0"
> pullPolicy: "IfNotPresent"
> 
> startupProbe:
> tcpSocket:
> port: 5601
> periodSeconds: 10
> timeoutSeconds: 5
> failureThreshold: 20
> successThreshold: 1
> initialDelaySeconds: 10
> 
> livenessProbe:
> tcpSocket:
> port: 5601
> periodSeconds: 20
> timeoutSeconds: 5
> failureThreshold: 10
> successThreshold: 1
> initialDelaySeconds: 10
> 
> readinessProbe:
> tcpSocket:
> port: 5601
> periodSeconds: 20
> timeoutSeconds: 5
> failureThreshold: 10
> successThreshold: 1
> initialDelaySeconds: 10
> 
> imagePullSecrets: []
> nameOverride: "opensearch-dashboard"
> fullnameOverride: "opensearch-dashboard-web"
> 
> serviceAccount:
> create: true
> annotations: {}
> name: "opensearch-dashboard"
> 
> rbac:
> create: true
> 
> secretMounts: []
> 
> podAnnotations: {}
> 
> dashboardAnnotations: {}
> 
> extraEnvs: []
> 
> envFrom: []
> 
> extraVolumes: []
> 
> extraVolumeMounts: []
> 
> extraInitContainers: ""
> 
> extraContainers: ""
> 
> podSecurityContext: {}
> 
> securityContext:
> capabilities:
> drop:
> - ALL
> # readOnlyRootFilesystem: true
> runAsNonRoot: true
> runAsUser: 1000
> 
> config:
> opensearch_dashboards.yml: |
> server.host: "{{ .Values.serverHost }}"
> # Enable OpenID authentication
> opensearch.requestHeadersAllowlist: ["securitytenant","Authorization","x-forwarded-for"]
> opensearch.ssl.verificationMode: none
> opensearch_security.cookie.secure: false
> *# opensearch_security.auth.type: openid*
> opensearch_security.openid.base_redirect_url: "{{ dashboard-k8s }}"
> opensearch_security.openid.client_id: "{{ client_id }}"
> opensearch_security.openid.scope: "email profile roleopen groups"
> opensearch_security.openid.client_secret: "secret"
> opensearch_security.openid.connect_url: "https://{{ keycloak_url }}/realms/{{ realm }}/.well-known/openid-configuration"
> opensearch_security.openid.header: "Authorization"
> opensearch_security.openid.verify_hostnames: false
> *# opensearch.ssl.certificate: /path/to/your/client.crt*
> * # opensearch.ssl.key: /path/to/your/client.key*
> * # opensearch.ssl.certificateAuthorities: ["/path/to/your/CA.pem"]*
> opensearch_security.auth.type: ["basicauth","openid"]
> opensearch_security.auth.multiple_auth_enabled: true
> 
> opensearchDashboardsYml:
> defaultMode:
> # value should be 0-0777
> 
> priorityClassName: ""
> 
> opensearchAccount:
> secret: "opensearchsecretconn"
> keyPassphrase:
> enabled: false
> 
> labels: {}
> 
> hostAliases: []
> 
> serverHost: "0.0.0.0"
> 
> service:
> type: ClusterIP
> port: 5601
> loadBalancerIP: "10.4.0.25"
> nodePort: ""
> labels: {}
> annotations: {}
> loadBalancerSourceRanges: []
> # 0.0.0.0/0
> httpPortName: http
> 
> ingress:
> enabled: **true**
> # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
> # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
> ingressClassName: opensearch-dashboard-web
> annotations:
> meta.helm.sh/release-name: opensearch
> meta.helm.sh/release-namespace: opensearch-stage
> nginx.org/location-snippets: |
> add_header X-Robots-Tag "noindex, nofollow" always;
> labels: 
> app.kubernetes.io/instance: opensearch-stage
> app.kubernetes.io/managed-by: Helm
> app.kubernetes.io/name: opensearch
> helm.sh/chart: opensearch-2.11.1
> hosts:
> - host: {{ dashboard-k8s }}
> paths:
> - path: /
> backend:
> serviceName: ""
> servicePort: ""
> tls:
> - secretName: k8s-secret
> hosts:
> - {{ dashboard-k8s }}
> 
> ingressClass:
> enabled: true
> controller: k8s.io/ingress-nginx
> annotations: {}
> labels:
> app.kubernetes.io/component: controller
> 
> resources:
> requests:
> cpu: "100m"
> memory: "512M"
> limits:
> cpu: "1000m"
> memory: "2048M"
> 
> autoscaling:
> enabled: false
> minReplicas: 1
> maxReplicas: 10
> targetCPUUtilizationPercentage: 80
> 
> updateStrategy:
> type: "Recreate"
> 
> nodeSelector: {}
> 
> tolerations: []
> 
> affinity: {}
> 
> extraObjects: []
> lifecycle: {}
> plugins:
> enabled: false
> installList: []
> 
> ```

Opensearch dashboard backend role:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/e/ee39b3b21fccce1c4c4c5d950a31dd79ba579efe.png)

Authorization via openid OK, but not passing roles from Keycloak:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/6/6140e4f94aed413aac67204a5171ac00f0b65831.png)

In opensearch logs:

```auto
[2023-12-29T18:32:42,077][WARN][o.o.s.h.HTTPBasicAuthenticator] [os1] No 'Basic Authorization' header, send 401 and 'WWW-Authenticate Basic'
[2023-12-29T18:32:42,077][WARN][c.a.d.a.h.j.AbstractHTTPJwtAuthenticator] [os1] Failed to get roles from JWT claims with roles_key 'roleopen'. Check 
if this key is correct and available in the JWT payload.

```

In Opensearch Dashboard Pod:

```auto
{"type":"log","@timestamp":"2023-12-29T18:32:39Z","tags":["error","opensearch","data"],"pid":1,"message":"[security_exception]: no permissions for [indices:data/read/get] and User [name=someuser, backend_roles=[], requestedTenant=null]"}

```

Keycloak configuration Client, Tab **Settings** :

> **Access settings**
>
> ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/4/49724fdf0092ba81aea2d97b1b9f559c157421fe.png)

> **Capability config**
>
> ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/0/0af49e2ca814c8a3f0a5735cf606e5fc662a556c.png)

Keycloak configuration Client, Tab **Keys** :

> **JWKS URL configs**
>
> Use JWKS URL=off

Keycloak configuration Client, Tab **Credentials** :

> **Client Authenticator**
>
> Client Id and secret with some client secret

> **Registration access token**
>
> null

Keycloak configuration Client, Tab **Roles** :

> **Role name**
>
> roles

Keycloak configuration Client, Tab **Client scopes** :

> **Assigned client scope**
>
> ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/6/681dddf0a590c3cb5ae7939319cb1ab722713730.png)

**Keycloak configuration Client scopes**

> **roleopen**
>
> Tab Settings:
> 
> ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/3/3f192db802ab965d0578c1d05b0d4a07cd4b8b38.png)  
> Tab Mappers  
> ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/4/4a5a42b78334575749aee2090fa50c8da5403c7f.png)
> 
> > **realm roles**
> >
> > ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/9/96a3f34bd971e2dae4a096e7008274b3082a01db.png)
> 
> > **client roles**
> >
> > ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/9/9e8bae9cc6dd9bf49eb1a0a86622bba08f4565b8.png)

---

<div class="post-metadata">

**Author:** ![Mantas](https://avatars.discourse-cdn.com/v4/letter/m/7bcc69/32.png) [@Mantas](https://forum.opensearch.org/u/Mantas)\
**Post date:** [January 2, 2024, 11:11am UTC](https://forum.opensearch.org/t/openid-keycloak-working-with-opensearch-2-11-1-but-not-passing-roles/17285/2 "2024-01-02T11:11:23Z")

</div>

Hi @ActiveSync ,

Could you try setting "`Token Claim Name" to roles` instead of `realm_access.roles` and `"Add to userinfo" ON`

Best,  
mj

 ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/9/96a3f34bd971e2dae4a096e7008274b3082a01db.png)

---

<div class="post-metadata">

**Author:** ![ActiveSync](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/activesync/32/6710_2.png) [@ActiveSync](https://forum.opensearch.org/u/ActiveSync)\
**Post date:** [January 2, 2024, 12:21pm UTC](https://forum.opensearch.org/t/openid-keycloak-working-with-opensearch-2-11-1-but-not-passing-roles/17285/3 "2024-01-02T12:21:18Z")

</div>

Hi @Mantas. It works! Thanks 🙂

After authorization I got 502 bad gateway error (I use ingress-nginx k8s).  
Solution here:  
[Proxy\_buffer\_size : 502 bad gateway error - Getting advice - Keycloak](https://keycloak.discourse.group/t/proxy-buffer-size-502-bad-gateway-error/18154/6)
