Issue with JWT Roles Mapping in OpenSearch Dashboards using Authelia OIDC

Versions: 3.1.0 - Docker-compose

Describe the issue:
Hi,

I’m trying to configure OpenSearch Dashboards with OpenID Connect authentication via Authelia. The setup is mostly working, but I keep getting the following warning in the OpenSearch logs when a user logs in

[2025-08-20T09:48:46,187][WARN ][o.o.s.a.h.j.AbstractHTTPJwtAuthenticator] [1fdc4603322a] Failed to get roles from JWT claims with roles_key ‘[groups]’. Check if this key is correct and available in the JWT payload.

Configuration:
I’ve configured the config.yml in OpenSearch like this:

authc:
openid_auth_domain:
http_enabled: true
transport_enabled: false
order: 0
http_authenticator:
type: openid
challenge: false
config:
subject_key: sub
roles_key: groups
openid_connect_url: ``https://authelia.example.com/.well-known/openid-configuration

opensearch# tree
.
├── certs
│ ├── admin.csr
│ ├── admin.key
│ ├── admin.pem
│ ├── node.csr
│ ├── node.key
│ ├── node.pem
│ ├── opensearch.cnf
│ ├── root-ca.key
│ ├── root-ca.pem
│ └── root-ca.srl
├── config
│ ├── action_groups.yml
│ ├── config.yml
│ ├── internal_users.yml
│ ├── nodes_dn.yml
│ ├── roles.yml
│ ├── roles_mapping.yml
│ └── tenants.yml
├── docker-compose.yml
└── opensearch_dashboards.yml

Authelia is configured to include the groups claim in the ID token. However, OpenSearch Dashboards fails to extract roles from the JWT.

Has anyone successfully mapped JWT claims to OpenSearch roles with Authelia or other OIDC providers? Any advice would be appreciated.

Thanks!

Hi,

our config look almost the same:

    # Auth
    authc:

      # Real persons
      openid_auth_domain:
        http_enabled: true
        transport_enabled: false
        order: 0
        http_authenticator:
          type: openid
          challenge: false
          config:
            openid_connect_idp:
              enable_ssl: true
              pemtrustedcas_filepath: /usr/share/opensearch/config/certs/rest-cert-ca.crt
            subject_key: preferred_username
            roles_key: groups
            openid_connect_url: "{{ idp_well_known }}"
        authentication_backend:
          type: noop

We use Keycloak for OIDC, and ansible for automation.

Have you dissected your JWT to verify the data?

Br Sebastian

@vacknov Did you try getting JWT token with curl?

You’ll find the correct token URL in the openid-configuration (‘https://authelia.example.com/.well-known/openid-configuration’)

curl -k --noproxy '*' -d 'client_id=<client_id>' -d 'username=<username>' -d 'password=<password>' -d 'grant_type=password' -d 'client_secret=<client_secret>' -d 'scope=openid' 'https://authelia.example.com/api/oidc/token'

Hi, thanks for your feedback.

At the moment I’m struggling to obtain a valid JWT token. The authorization code I capture is always expired when I try to exchange it. I retrieve it from the requests sent when I try to open a session on OpenSearch Dashboards.

Here’s the command I used:

curl -X POST https://authelia.example.com/api/oidc/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=authelia_ac_rkW8EwrnUDIDU1k0Vw-UKGDCwQH-C9DGwHuNzdmOFhw.eGC_jGaJJYmB1__NWX2ho9LrJnOonaM4_I0okawa8Qg" \
  -d "redirect_uri=https://dashboard.example.com/auth/openid/login" \
  -d "client_id=opensearch-dashboard-client" \
  -d "client_secret=*****"

And the response I get is:

{"error":"invalid_grant","error_description":"The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The authorization code has already been used."}

I also modified my Authelia configuration to include the claims like this:

claims_policies:
  osdashboard:
    id_token:
      - groups
      - preferred_username
clients:
  - client_id: "opensearch-dashboard-client"
    claims_policy: 'osdashboard'

Since then, the error message has change. Currently in the OpenSearch logs I’m seeing:

[2025-08-20T21:07:44,193][WARN ][o.o.s.a.BackendRegistry  ] [7b100098fbb8] No 'Authorization' header, send 401 and 'WWW-Authenticate Basic'

I’m going to change the parameter token_endpoint_auth_method to client_secret_basic.

Below is the current YAML configuration for the OIDC client (OpenSearch Dashboards) in Authelia:

identity_providers:
  oidc:
    claims_policies:
      osdashboard:
        id_token:
          - groups
          - preferred_username
    clients:
      - client_id: "opensearch-dashboard-client"
        claims_policy: 'osdashboard'
        client_secret: "$argon2******"
        public: false
        authorization_policy: one_factor
        token_endpoint_auth_method: client_secret_post
        redirect_uris:
          - "https://dashboard.example.com/auth/openid/login"
        scopes:
          - openid
          - profile
          - email
          - groups
        grant_types:
          - authorization_code
        response_types:
          - code
        consent_mode: implicit

OpenSearch Dashboards does not support client_secret_basic.

Authelia logs:

time="2025-08-21T00:12:38+02:00" level=error msg="Access Request failed with error: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The request was determined to be using 'token_endpoint_auth_method' method 'client_secret_post', however the OAuth 2.0 client registration does not allow this method. The registered client with id 'opensearch-dashboard-client' is configured to only support 'token_endpoint_auth_method' method 'client_secret_basic'. Either the Authorization Server client registration will need to have the 'token_endpoint_auth_method' updated to 'client_secret_post' or the Relying Party will need to be configured to use 'client_secret_basic'."

OpenSearch Dashboards config:
opensearch_security.openid.client_auth_method: “basic”

{"type":"log","@timestamp":"2025-08-20T22:30:43Z","tags":["fatal","root"],"pid":1,"message":"ValidationError: [config validation of [opensearch_security].openid.client_auth_method]: definition for this key is missing
    at ObjectType.validate (/usr/share/opensearch-dashboards/node_modules/@osd/config-schema/target/out/types/type.js:77:19)
    at ConfigService.validateAtPath (/usr/share/opensearch-dashboards/node_modules/@osd/config/target/config_service.js:162:23)
"}

I am keeping token_endpoint_auth_method: 'client_secret_post' in Authelia.

For now, this is the message I see in the OpenSearch logs:

[2025-08-20T22:42:08,141][WARN ][o.o.s.a.BackendRegistry  ] [8a2fdf136974] No 'Authorization' header, send 401 and 'WWW-Authenticate Basic'

@vacknov I’ve got Authelia working with OpenSearch 3.0

This is my working configuration

opensearch_dashboards.yml

server.name: kibana
server.host: "0.0.0.0"
server.customResponseHeaders : { "Access-Control-Allow-Credentials" : "true" }
server.ssl.enabled: true
server.ssl.certificate: /usr/share/opensearch-dashboards/config/opensearch_dashboards.crt
server.ssl.key: /usr/share/opensearch-dashboards/config/opensearch_dashboards.key

opensearch.ssl.verificationMode: none
opensearch.username: kibanaserver
opensearch.password: kibanaserver
opensearch.requestHeadersWhitelist: ["securitytenant","Authorization"]

opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: ["Global","Private"]
opensearch_security.multitenancy.tenants.enable_private: false
opensearch_security.readonly_mode.roles: ["kibana_read_only"]

#OpenID authentication
opensearch_security.auth.type: ["basicauth","openid"]
opensearch_security.auth.multiple_auth_enabled: true
opensearch_security.openid.connect_url: "https://dockerhub.pablo.local:9091/.well-known/openid-configuration"
opensearch_security.openid.client_id: "opensearch-dashboard-client"
opensearch_security.openid.client_secret: "gokQwqqTMlEnnOa5vWC_pIXlZZR1AHmHqtR.F9-1-x8WHERKIyrELWCNIxc2UmMh0Z5osAY4"
opensearch_security.openid.root_ca: "/usr/share/opensearch-dashboards/config/authelia.crt"
opensearch_security.openid.base_redirect_url: "https://docker1.pablo.local:5601"

opensearch_security.openid.scope: openid profile email groups

config.yml

_meta:
  type: "config"
  config_version: 2
config:
  dynamic:
    http:
      anonymous_auth_enabled: false
      xff:
        enabled: false
        internalProxies: "192\\.168\\.0\\.10|192\\.168\\.0\\.11"
    authc:
      basic_internal_auth_domain:
        description: "Authenticate via HTTP Basic against internal users database"
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: "basic"
          challenge: false
        authentication_backend:
          type: "intern"
      openid_auth_domain:
        http_enabled: true
        transport_enabled: true
        order: 1
        http_authenticator:
          type: "openid"
          challenge: false
          config:
            subject_key: "preferred_username"
            roles_key: "groups"
            openid_connect_url: "https://dockerhub.pablo.local:9091/.well-known/openid-configuration"
            openid_connect_idp.pemtrustedcas_filepath: "/usr/share/opensearch/config/authelia.crt"
            openid_connect_idp.enable_ssl: true
            skip_users:
            - "kibanaro"
            - "kibanaserver"
            - "logstash"
            - "adminp"
            - "fliebeat_internal"
            - "kibanauser"
        authentication_backend:

users_database.yml

users:
  pablo:
    password: "$argon2id$v=19$m=65536,t=3,p=4$+6NPbIEzO+HGQf6qpvIs6A$AX+G0LrV27ZK+tt0hkmx35uqTRGEAAK2frlTMW8ESgc"
    email: pabloe@example.com
    displayname: "Pablo"
    groups:
      - admins
      - admin
      - dev
  pablo1:
    password: "$argon2id$v=19$m=65536,t=3,p=4$+6NPbIEzO+HGQf6qpvIs6A$AX+G0LrV27ZK+tt0hkmx35uqTRGEAAK2frlTMW8ESgc"
    email: pabloe@example.com
    displayname: "Pablo"
    groups:
      - kibanauser
      - dev

configuration.yml

host: 0.0.0.0
port: 9091
log_level: info
server:
 tls:
   key: /config/authelia.key
   certificate: /config/authelia.crt

jwt_secret: ${JWT_SECRET}

authentication_backend:
  file:
    path: /config/users_database.yml

access_control:
  default_policy: one_factor

session:
  cookies:
    - name: authelia_session
      domain: pablo.local
      authelia_url: https://auth.pablo.local:9091
      default_redirection_url: https://dockerhub.pablo.local:9091
      same_site: none               # for cross-site cookies
      expiration: 3600
      inactivity: 300

storage:
  local:
    path: /config/db.sqlite3
  encryption_key: ${STORAGE_ENCRYPTION_KEY}

notifier:
  filesystem:
    filename: /config/notification.txt

identity_providers:
  oidc:
    hmac_secret: ${JWT_SECRET}
    jwks:
      - key: |
          -----BEGIN PRIVATE KEY-----
          MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCS3hHW+AMLyp/k
          iTouXf/eRfz11PF0j1bhpTQDos9OSPh3rwpvqu0OkCEac774u6r2EU/PaTn3ra02
          oEZKogCulC7YvUNkXrIYSAfvrdhOHTk2lJgMkiy/R/+Mstv3vii07fYJvD0RyRs6
          x56us/z3Xt+CPdu2Fn2d6mtcqE7YKESc9UZDs5behkL1TBsqDbBUBnhNCsp7f/b/
          30DAuscM6UuE9L8/Uamidc5niJFo77T2ERbkVl11lMz7DAOrkFPcb3jrqmDa/uq2
          0gsM6ZcduOhG+WJUC2Ru2uVBqlAthL6JNCVcOfFLZfOgezwR2Do2f2iK+W2Amfh6
          8n4LZlAxAgMBAAECggEABAKxqsS+w4yK0XkwWCoLtciEO/vOxKOx6AtEeHlyjwUV
          2OHUJ4C7xLcpmkDxJPZt+JZ4LxYk5bctyNU3Wiwil+HWxicj7xqZYymbYt+EzbxF
          TtDfto8qzuXiy/cp49Hi527sli84XTMYTeJ72jIyzRf/gz1YcbhbQYvQVvlHHuav
          AuWVFR9XBZxTwqj7SGfUsYNURTrz/ZH3S2+TP/DQB6X+AzPVuA9N9PmsY1KpkGWB
          4jO+AFOGw6WWljzTNrItk/l7zqurOgqxbcBUeWhSrU/dxGZBY9ovYVMVQ3Hm426z
          FCA2HREOz/cM7rdmktk+q1CInJRRS4eI7fFCnCRk6QKBgQDA1MRRR6p5BdiHttwO
          9mUjSqSQrsnMxvHxuAub/UbRLLn6DS+63UXHYtTVMImPP3Ll3JEzMrQPjPTvKHG4
          FSSORkFQYb8yu50E+FV1ZPtWakmyA1Bvmi57ultJFG6C230KKWJ2Rfdgqkr/KQFJ
          HGQeuSIfFl13jKcMpiHLAp352QKBgQDC+rDzdAbzQuUAbTulp0cM6DE/B3NdlDuA
          gvEH8jz7J/km61r1jpWQWZvhDu+TWJfk5vNH+kw7G+jypJugG3hNh93nks8Re61J
          i4ZnmMLO3rxSGj6kEhgY21dGs8f51Oe//G6AHCdwbDKXFy0Xav4ONrAs2Q5YNk+o
          OiL/U/P6GQKBgD4i0XfXfgktZw6kT9jKcOCkZs7wY7qGyOO5CJSlUrKIlQ0MPrsa
          HigXorlnwIvWSDHllyxGRFtWcn62K57DwVnPLbC3LqMsbXZyhyci+RJpgYHJK5wq
          tJvN+yhbWxjznSEvILk35nTRqwT5s55ZdbGoumQGEuw4+INM7Uq7dyhRAoGAf73w
          2r/EofHMyPfH4WLz2M/zG8FM4x1v0mV3duZM75ujz8zYnhLZiGY9CzlW2ulrMqvg
          7eJduUgy2W3hDAeTTPBcAREdGu41fP6tgwgBcblaFkxdh+7W3MovpwG4XcUQRKck
          2kgXyr8IchbcEwClDDjmOavHiyGiFKxqK3AcY1kCgYATn9typvviO8J8Y/+0hYu6
          FL+Mx2CJyK0Ft8vMFvE/gFTXTAAK620X8vODr1BpryjELMCQRe+05YeqGo6rhwvi
          QA04yaUDzp/DdSw1bi6dzSmJWKiYUgsbJg/OssyAkIyfhLyPNlMkLLBTm2UHZ+9B
          ZpeTTea5tkQ6+Kvgkmo0eg==
          -----END PRIVATE KEY-----
        use: sig
        algorithm: RS256
    claims_policies:
      osdashboard:
        id_token:
          - groups
          - preferred_username
    clients:
      - client_id: "opensearch-dashboard-client"
        claims_policy: 'osdashboard'
        client_secret: "$pbkdf2-sha512$310000$gFd9sZ5yjgh3IXfmd.bGow$wzGg/Qa1gfAWjXM.6VqUzRdXjbKUgPIozNLJbtYV7VWFhIyRh3VFZTqcn1h7Qs9wBVUPvMCQII51IDMiyVM7jA"
        public: false
        authorization_policy: one_factor
        token_endpoint_auth_method: client_secret_post
        redirect_uris:
          - "https://docker1.pablo.local:5601/auth/openid/login"
        scopes:
          - openid
          - profile
          - email
          - groups
        grant_types:
          - refresh_token
          - authorization_code
        response_types:
          - code
        consent_mode: implicit

2 Likes

@vacknov I didn’t see your opensearch_dashboards.yml

Be sure that scopes in configuration.yml and opensearch_dashboards.yml are the same and both includes groups.

@pablo Here is my opensearch_dashboards.yml.

server.host: "0.0.0.0"
server.port: 5601
server.ssl.enabled: false

opensearch.hosts: ["https://opensearch:9200"]
opensearch.ssl.verificationMode: none
opensearch.ssl.certificate: /usr/share/opensearch-dashboards/config/certs/admin.pem
opensearch.ssl.key: /usr/share/opensearch-dashboards/config/certs/admin.key
opensearch.ssl.certificateAuthorities: [/usr/share/opensearch-dashboards/config/certs/root-ca.pem]

opensearch_security.auth.type: "openid"
opensearch_security.openid.connect_url: "https://authelia.example.com/.well-known/openid-configuration"
opensearch_security.openid.client_id: "opensearch-dashboard-client"
opensearch_security.openid.client_secret: "*******"
opensearch_security.openid.base_redirect_url: "https://dashboard.example.com"
opensearch_security.openid.scope: "openid profile email groups"

opensearch_security.openid.logout_url: "https://authelia.example.com/logout"

opensearch_security.session.ttl: 3600000
opensearch_security.session.keepalive: true  

I’m downgrading to version 3.0.
I’ll apply the changes following your approach and let you know how it goes.

I really appreciate your support and guidance on this issue — thank you!

@vacknov Do you get the Authelia login page, or does it fail before that?

My config also works with 3.1.0.

You’ve disabled SSL (server.ssl.enabled: false), however all your redirects to OSD are HTTPS.

@pablo Authelia and OpenSearch Dashboards are placed behind HAProxy with Let’s Encrypt certificates.

Haproxy

frontend http_front
    bind {{ public-ip }}:443 ssl crt /etc/haproxy/ssl/ strict-sni
    http-request deny if { hdr(host) -i authelia.example.com } !{ src -f /etc/haproxy/whitelist.txt }
    http-request deny if { hdr(host) -i dashboard.example.com } !{ src -f /etc/haproxy/whitelist.txt }
    
    use_backend backend-tools-opensearch-dashboards if { hdr(host) -i dashboard.example.com }     
    use_backend backend-tools-authelia if { hdr(host) -i authelia.example.com }
    
backend backend-tools-opensearch-dashboards
    balance roundrobin
    option forwardfor
    http-request set-header X-Forwarded-Proto https
    http-request add-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Host %[req.hdr(host)]
    server opensearch-dashboards 10.51.0.1:5601 check
    
backend backend-tools-authelia
    balance roundrobin
    option forwardfor 
    http-request add-header X-Forwarded-Port %[dst_port]
    http-request set-header X-Forwarded-Proto https
    option httpchk GET /api/health
    server authelia 10.51.0.1:9091 check

Authelia / configuration.yaml

identity_validation:
  reset_password:
    jwt_secret: "Hp0MyaIrh275cWYq9NCt5ipmJcU0FLOxIo5dMqkc3bQ="
    
theme: light
default_redirection_url: https://example.com

server:
  address: tcp://0.0.0.0:9091/

log:
  level: debug

authentication_backend:
  file:
    path: /config/users_database.yml
    password:
      algorithm: argon2id
      iterations: 3
      memory: 64
      parallelism: 4
      salt_length: 16
      key_length: 32

session:
  name: authelia_session
  secret: "saEFQwdQp3M3SGIkKwDT3wn7xTxTGpO2qPhuGR18ARw="
  expiration: 1h
  inactivity: 5m
  domain: example.com
  same_site: lax

storage:
  local:
    path: /config/storage/db.sqlite3
  encryption_key: "3UU2UsyXYkTWueUkPix3Kki7jSCFoMVbNpqamThae2Q="

access_control:
  default_policy: deny
  rules:
    - domain: "*.foo.com"
      policy: one_factor
    - domain: "*.example.com"
      policy: two_factor

notifier:
  smtp:
    address: smtp://mail.example.com:587
    username: "user@example.com"
    password: "*******"
    sender: "Authelia <no-reply@example.com>"
    subject: "[Authelia] Notification"
    startup_check_address: "user@example.com"
    disable_require_tls: false
    tls:
      skip_verify: false      

identity_providers:
  oidc:
    hmac_secret: "2PRVgcl0y2PMZcD59icamH0vNtoQeqboIvEhKO8Cn1U="
    jwks:
      - key: |
          -----BEGIN PRIVATE KEY-----
          
          -----END PRIVATE KEY-----
        use: sig
        algorithm: RS256      
    claims_policies:
      osdashboard:
        id_token:
          - groups
          - preferred_username
    clients:
      - client_id: "opensearch-dashboard-client"
        claims_policy: 'osdashboard'
        client_secret: "$argon2id$v=19$m=65536,t=3,p=4$NMVrtX7Mz31jamMESuDaoQ$x+hpxTlTUJT4lqpYUlYvt2hhz6A0FpdcbkXMSymEOXM"
        public: false
        authorization_policy: one_factor
        token_endpoint_auth_method: 'client_secret_post'
        redirect_uris:
          -  "https://dashboard.exemple.com/auth/openid/login"
        scopes:
          - openid
          - profile
          - email
          - groups
        grant_types:
          - refresh_token
          - authorization_code
        response_types:
          - code
        consent_mode: implicit
        access_token_signed_response_alg: 'none'
        userinfo_signed_response_alg: 'none'

Authelia/users_database.yml

users:
  alice:
    displayname: "Admin"
    password: "$argon2id$v=19$m=65536,t=3,p=4$wszjeiswsXYGqpZNfLiRKg$DW8Bn7gAq28nHXowpnv4f59exfwpeEketAHpSowX0Vw" 
    email: vacknov@example.com
    groups:
      - admins
  bob:
    displayname: "User"
    password: "$argon2id$v=19$m=65536,t=3,p=4$wszjeiswsXYGqpZNfLiRKg$DW8Bn7gAq28nHXowpnv4f59exfwpeEketAHpSowX0Vw"
    email: user@example.com
    groups:
      - users

Opensearch/config.yml

_meta:
  type: "config"
  config_version: 2
config:
  dynamic:
    http:
      anonymous_auth_enabled: false
      xff:
        enabled: false
        internalProxies: "10\\.51\\.0\\.3|112\\.94\\.20\\.78"
    authc:
      basic_internal_auth_domain:
        description: "Authenticate via HTTP Basic against internal users database"
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: "basic"
          challenge: false
        authentication_backend:
          type: "intern"
      openid_auth_domain:
        http_enabled: true
        transport_enabled: true
        order: 1
        http_authenticator:
          type: "openid"
          challenge: false
          config:
            subject_key: "preferred_username"
            roles_key: "groups"
            openid_connect_url: "https://authelia.example.com/.well-known/openid-configuration"
            openid_connect_idp.enable_ssl: true
            skip_users:
            - "kibanaro"
            - "kibanaserver"
            - "logstash"
            - "admin"
            - "fliebeat_internal"
            - "kibanauser"

Opensearch dasshbord / opensearch_dashbords.yml

server.host: "0.0.0.0"
server.port: 5601
server.ssl.enabled: false 
server.customResponseHeaders : { "Access-Control-Allow-Credentials" : "true" }  

opensearch.hosts: ["https://opensearch:9200"]
opensearch.ssl.verificationMode: none
opensearch.requestHeadersWhitelist: ["securitytenant","Authorization"]  
opensearch.ssl.certificate: /usr/share/opensearch-dashboards/config/certs/admin.pem
opensearch.ssl.key: /usr/share/opensearch-dashboards/config/certs/admin.key
opensearch.ssl.certificateAuthorities: [/usr/share/opensearch-dashboards/config/certs/root-ca.pem]


opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: ["Global","Private"]
opensearch_security.multitenancy.tenants.enable_private: false
opensearch_security.readonly_mode.roles: ["kibana_read_only"]

opensearch_security.auth.type: ["basicauth","openid"]  
opensearch_security.auth.multiple_auth_enabled: true  
opensearch_security.openid.connect_url: "https://authelia.example.com/.well-known/openid-configuration"
opensearch_security.openid.client_id: "opensearch-dashboard-client"
opensearch_security.openid.client_secret: "*********"
opensearch_security.openid.base_redirect_url: "https://dashboard.example.com"
opensearch_security.openid.scope: "openid profile email groups"

# Configuration pour éviter les problèmes d'authentification
opensearch_security.openid.logout_url: "https://authelia.example.com/logout"

config/roles_mappings.yml

all_access:
  reserved: false
  backend_roles:
  - "admin"
  - "admins"
  - "users"
  description: "Maps admin to all_access

Opensearch logs after apply changes

2025-08-21T20:39:12,530][WARN ][o.o.s.h.HTTPBasicAuthenticator] [55cfe0eba429] No 'Basic Authorization' header, send 401 and 'WWW-Authenticate Basic'
[2025-08-21T20:39:12,531][WARN ][o.o.s.a.BackendRegistry  ] [55cfe0eba429] Authentication finally failed for null from 172.25.0.3:35366

I will switch the dashboard to HTTPS for testing.

1 Like

@vacknov OpenSearch Dashboards is whitelisting Authorization header but I can’t see that in your reverse proxy. This header is required for OpenID authentication.

Problem resolved with the following configuration:
config.yml:

openid_auth_domain:
  http_enabled: true
  transport_enabled: true
  order: 1
  http_authenticator:
    type: "openid"
    challenge: false
    config:
      subject_key: "preferred_username"
      roles_key: "groups"
      openid_connect_url: "https://authelia.example.com/.well-known/openid-configuration"
      client_id: "HfDzQgOJYBLgObSMMeHnmZQanxHs5avtVUxS6Q5nMOAxhk8ZwJrL011XfyUuIHJ0Fg2K2jyp"
      client_secret: "opensearch-dashboard-client"
      skip_users:
      - "kibanaro"
      - "kibanaserver"
      - "logstash"
      - "adminp"
      - "kibanauser"
  authentication_backend:
    type: "noop"

Opensearch_dashbords.yml

server.host: "0.0.0.0"
server.port: 5601
server.ssl.enabled: false
server.customResponseHeaders : { "Access-Control-Allow-Credentials" : "true" }

opensearch.hosts: ["https://opensearch:9200"]
opensearch.ssl.verificationMode: none
opensearch.requestHeadersWhitelist: ["securitytenant","Authorization"]
opensearch.ssl.certificate: /usr/share/opensearch-dashboards/config/certs/admin.pem
opensearch.ssl.key: /usr/share/opensearch-dashboards/config/certs/admin.key
opensearch.ssl.certificateAuthorities: [/usr/share/opensearch-dashboards/config/certs/root-ca.pem]

opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: ["Global","Private"]
opensearch_security.multitenancy.tenants.enable_private: false
opensearch_security.readonly_mode.roles: ["kibana_read_only"]

opensearch_security.auth.type: ["basicauth","openid"]
opensearch_security.auth.multiple_auth_enabled: true
opensearch_security.openid.connect_url: "https://authelia.example.com/.well-known/openid-configuration"
opensearch_security.openid.client_id: "opensearch-dashboard-client"
opensearch_security.openid.client_secret: "HfDzQgOJYBLgObSMMeHnmZQanxHs5avtVUxS6Q5nMOAxhk8ZwJrL011XfyUuIHJ0Fg2K2jyp"
opensearch_security.openid.base_redirect_url: "https://dashboard.example.com"
opensearch_security.openid.scope: "openid profile email groups"
opensearch_security.openid.header: "Authorization"

Haproxy/ Backend

backend backend-htp-tools-dashboard
    balance roundrobin
    option forwardfor
    http-request set-header X-Forwarded-Proto https
    http-request add-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Host %[req.hdr(host)]
    server opensearch-dashboard 10.51.0.1:5601 check

Thanks a lot for your help :folded_hands:
I’ll stay active on the forum to help others who might face the same issue.

2 Likes