# OpenID Connect Integration with Azure AD on Opensearch Operator based setup - Unauthorized access with 401 error

**URL:** <https://forum.opensearch.org/t/openid-connect-integration-with-azure-ad-on-opensearch-operator-based-setup-unauthorized-access-with-401-error/22413>\
**Category:** Security\
**Tags:** security-issue\
**Created:** [November 14, 2024, 3:10am UTC](https://forum.opensearch.org/t/openid-connect-integration-with-azure-ad-on-opensearch-operator-based-setup-unauthorized-access-with-401-error/22413 "2024-11-14T03:10:39Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ar.shashikumar](https://avatars.discourse-cdn.com/v4/letter/a/6a8cbe/32.png) [@ar.shashikumar](https://forum.opensearch.org/u/ar.shashikumar)\
**Post date:** [November 14, 2024, 3:10am UTC](https://forum.opensearch.org/t/openid-connect-integration-with-azure-ad-on-opensearch-operator-based-setup-unauthorized-access-with-401-error/22413/1 "2024-11-14T03:10:39Z")

</div>

**Versions** (relevant - OpenSearch/Dashboard/Server OS/Browser):  
Versions:  
Operator: 2.6.1  
Opensearch: 2.14.0  
K8s: v1.24.17+rke2r1  
OS: Ubuntu  
Setup is based on Opensearch Operator

**Describe the issue** :  
Configured OpenID with Azure based Identity provider. Having both Basic Auth and OpenID configured, when we browse the URL, it takes us to provide the credentials and as a output it throws 401 error “{“statusCode”:401,“error”:“Unauthorized”,“message”:“Authentication Exception”}”

Is there any roles/role\_mapping to be configured in securityconfig.yaml to communicate with Azure AD is one of the concern/query we have. Also what causes Error 401 unauthorized after the below configuration.

**Configuration** :  
Opensearch\_dashboard.yml

```auto
  dashboards:
    env:
      - name: CLIENT_ID
        valueFrom:
          secretKeyRef:
            name: os-client-id
            key: client-id
      - name: CLIENT_SECRET
        valueFrom:
          secretKeyRef:
            name: os-client-secret
            key: client-secret
    additionalConfig:
      opensearch_security.openid.client_id: "${CLIENT_ID}"
      opensearch_security.openid.client_secret: "${CLIENT_SECRET}"
      opensearch.ssl.verificationMode: none
      opensearch.requestHeadersWhitelist: "authorization,securitytenant"
      opensearch_security.auth.multiple_auth_enabled: "true"
      opensearch_security.auth.type: "openid"
      opensearch_security.openid.base_redirect_url: "https://abcd.domain.com"
      opensearch_security.openid.connect_url: "https://login.microsoftonline.com/e255d/v2.0/.well-known/openid-configuration"

```

securityconfig.yml

```auto
 apiVersion: v1
kind: Secret
metadata:
  name: securityconfig-secret
type: Opaque
stringData:
      action_groups.yml: |-
         _meta:
           type: "actiongroups"
           config_version: 2
      internal_users.yml: |-
        _meta:
          type: "internalusers"
          config_version: 2
        admin:
          hash: "$2a$12$efBxsNSmM.QYK9smZhPxt.dqGy/vG5Nk.1KTdqeGbYpZFnE1oCv0q"
          reserved: true
          backend_roles:
          - "admin"
          description: "Demo admin user"
        dashboarduser:
          hash: "$2a$12$efBxsNSmM.QYK9smZhPxt.dqGy/vG5Nk.1KTdqeGbYpZFnE1oCv0q"
          reserved: true
          backend_roles:
          - "admin"
          description: "Demo OpenSearch Dashboards user"
      nodes_dn.yml: |-
        _meta:
          type: "nodesdn"
          config_version: 2
      whitelist.yml: |-
        _meta:
          type: "whitelist"
          config_version: 2
      tenants.yml: |-
        _meta:
          type: "tenants"
          config_version: 2
      roles_mapping.yml: |-
        _meta:
          type: "rolesmapping"
          config_version: 2
        all_access:
          reserved: false
          backend_roles:
          - "admin"
          users:
          - "*"
          description: "Maps admin to all_access"
        own_index:
          reserved: false
          users:
          - "*"
          description: "Allow full access to an index named like the username"
        readall:
          reserved: false
          backend_roles:
          - "readall"
        manage_snapshots:
          reserved: false
          backend_roles:
          - "snapshotrestore"
        dashboard_server:
          reserved: true
          users:
          - "dashboarduser"
      roles.yml: |-
        _meta:
          type: "roles"
          config_version: 2
        dashboard_read_only:
          reserved: true
        security_rest_api_access:
          reserved: true
        # Allows users to view monitors, destinations and alerts
        alerting_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/alerting/alerts/get'
            - 'cluster:admin/opendistro/alerting/destination/get'
            - 'cluster:admin/opendistro/alerting/monitor/get'
            - 'cluster:admin/opendistro/alerting/monitor/search'
        # Allows users to view and acknowledge alerts
        alerting_ack_alerts:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/alerting/alerts/*'
        # Allows users to use all alerting functionality
        alerting_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster_monitor'
            - 'cluster:admin/opendistro/alerting/*'
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - 'indices_monitor'
                - 'indices:admin/aliases/get'
                - 'indices:admin/mappings/get'
        # Allow users to read Anomaly Detection detectors and results
        anomaly_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/ad/detector/info'
            - 'cluster:admin/opendistro/ad/detector/search'
            - 'cluster:admin/opendistro/ad/detectors/get'
            - 'cluster:admin/opendistro/ad/result/search'
            - 'cluster:admin/opendistro/ad/tasks/search'
            - 'cluster:admin/opendistro/ad/detector/validate'
            - 'cluster:admin/opendistro/ad/result/topAnomalies'
        # Allows users to use all Anomaly Detection functionality
        anomaly_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster_monitor'
            - 'cluster:admin/opendistro/ad/*'
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - 'indices_monitor'
                - 'indices:admin/aliases/get'
                - 'indices:admin/mappings/get'
        # Allows users to read Notebooks
        notebooks_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/notebooks/list'
            - 'cluster:admin/opendistro/notebooks/get'
        # Allows users to all Notebooks functionality
        notebooks_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/notebooks/create'
            - 'cluster:admin/opendistro/notebooks/update'
            - 'cluster:admin/opendistro/notebooks/delete'
            - 'cluster:admin/opendistro/notebooks/get'
            - 'cluster:admin/opendistro/notebooks/list'
        # Allows users to read observability objects
        observability_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opensearch/observability/get'
        # Allows users to all Observability functionality
        observability_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opensearch/observability/create'
            - 'cluster:admin/opensearch/observability/update'
            - 'cluster:admin/opensearch/observability/delete'
            - 'cluster:admin/opensearch/observability/get'
        # Allows users to read and download Reports
        reports_instances_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/reports/instance/list'
            - 'cluster:admin/opendistro/reports/instance/get'
            - 'cluster:admin/opendistro/reports/menu/download'
        # Allows users to read and download Reports and Report-definitions
        reports_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/reports/definition/get'
            - 'cluster:admin/opendistro/reports/definition/list'
            - 'cluster:admin/opendistro/reports/instance/list'
            - 'cluster:admin/opendistro/reports/instance/get'
            - 'cluster:admin/opendistro/reports/menu/download'
        # Allows users to all Reports functionality
        reports_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/reports/definition/create'
            - 'cluster:admin/opendistro/reports/definition/update'
            - 'cluster:admin/opendistro/reports/definition/on_demand'
            - 'cluster:admin/opendistro/reports/definition/delete'
            - 'cluster:admin/opendistro/reports/definition/get'
            - 'cluster:admin/opendistro/reports/definition/list'
            - 'cluster:admin/opendistro/reports/instance/list'
            - 'cluster:admin/opendistro/reports/instance/get'
            - 'cluster:admin/opendistro/reports/menu/download'
        # Allows users to use all asynchronous-search functionality
        asynchronous_search_full_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/asynchronous_search/*'
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - 'indices:data/read/search*'
        # Allows users to read stored asynchronous-search results
        asynchronous_search_read_access:
          reserved: true
          cluster_permissions:
            - 'cluster:admin/opendistro/asynchronous_search/get'
        # Allows user to use all index_management actions - ism policies, rollups, transforms
        index_management_full_access:
          reserved: true
          cluster_permissions:
            - "cluster:admin/opendistro/ism/*"
            - "cluster:admin/opendistro/rollup/*"
            - "cluster:admin/opendistro/transform/*"
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - 'indices:admin/opensearch/ism/*'
        # Allows users to use all cross cluster replication functionality at leader cluster
        cross_cluster_replication_leader_full_access:
          reserved: true
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - "indices:admin/plugins/replication/index/setup/validate"
                - "indices:data/read/plugins/replication/changes"
                - "indices:data/read/plugins/replication/file_chunk"
        # Allows users to use all cross cluster replication functionality at follower cluster
        cross_cluster_replication_follower_full_access:
          reserved: true
          cluster_permissions:
            - "cluster:admin/plugins/replication/autofollow/update"
          index_permissions:
            - index_patterns:
                - '*'
              allowed_actions:
                - "indices:admin/plugins/replication/index/setup/validate"
                - "indices:data/write/plugins/replication/changes"
                - "indices:admin/plugins/replication/index/start"
                - "indices:admin/plugins/replication/index/pause"
                - "indices:admin/plugins/replication/index/resume"
                - "indices:admin/plugins/replication/index/stop"
                - "indices:admin/plugins/replication/index/update"
                - "indices:admin/plugins/replication/index/status_check"
      config.yml: |-
        _meta:
          type: "config"
          config_version: "2"
        config:
          dynamic:
            http:
              anonymous_auth_enabled: false
            authc:
              basic_internal_auth_domain:
                http_enabled: true
                transport_enabled: true
                order: "1"
                http_authenticator:
                  type: basic
                  challenge: false
                authentication_backend:
                  type: internal
              openid_auth_domain:
                http_enabled: true
                transport_enabled: true
                order: "0"
                http_authenticator:
                  type: openid
                  challenge: false
                  config:
                    subject_key: email
                    roles_key: roles
                    openid_connect_url: "https://login.microsoftonline.com/2e255d/v2.0/.well-known/openid-configuration"
                    logging.verbose: true
                authentication_backend:
                  type: noop

```

Azure Configuration

1. Registered application
2. Created Client secret
3. Created App role as mentioned in the screenshot
4. Added user/group under Enterprise Applications
5. Created secret as per the configuration os-client-id and os-client-secret

**Relevant Logs or Screenshots** :  
Azure AD Configuration Screenshots:

Enterprise Applications → Users and Groups → Added users with Roles assigned with admin/all\_access

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

App Registrations → owned application → App Roles

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

API Permissions

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

Error in the browser:  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/8/886af773530452e74474e07eec8adfec6458dd72.png)

@pablo @Gsmitt

---

<div class="post-metadata">

**Author:** ![Gsmitt](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/gsmitt/32/1718_2.png) [@Gsmitt](https://forum.opensearch.org/u/Gsmitt)\
**Post date:** [November 14, 2024, 4:02am UTC](https://forum.opensearch.org/t/openid-connect-integration-with-azure-ad-on-opensearch-operator-based-setup-unauthorized-access-with-401-error/22413/2 "2024-11-14T04:02:10Z")

</div>

@ar.shashikumar

Sorry I don’t install docker also I have not messed with Azure AD in while, we ended up going wit a different IDP.

---

<div class="post-metadata">

**Author:** ![ar.shashikumar](https://avatars.discourse-cdn.com/v4/letter/a/6a8cbe/32.png) [@ar.shashikumar](https://forum.opensearch.org/u/ar.shashikumar)\
**Post date:** [November 18, 2024, 1:13pm UTC](https://forum.opensearch.org/t/openid-connect-integration-with-azure-ad-on-opensearch-operator-based-setup-unauthorized-access-with-401-error/22413/3 "2024-11-18T13:13:23Z")

</div>

Just to close on this, we were able to get through OIDC, though we still have few hiccups that opensearch dashboards intermittently shows “Opensearch did not load properly. Check the server output for more information” only for few users but not for all, OIDC part is working.
