OpensSearch dashboard proxy authentication

Versions (relevant - OpenSearch/Dashboard/Server OS/Browser):
Using latest tag for all images in docker-compose.
OpenSearch/Dasboard 2.11.0
Nginx 1.25.2

Describe the issue:
I am trying to setup basic docker-compose of OpenSearch dashboards, which uses single node and Nginx as proxy,
and to use proxy based authentication.
Setup is based on Proxy-based authentication - OpenSearch documentation

First step that I did was to create docker-compose which works, where I can access OpenSearch dashboards
directly through port 5061, or via nginx proxy on port 8090. I used following docker-compose file, with only difference
that volume sections were commented-out (except for nginx configuration):

version: '3'

services:
  opensearch:
    image: opensearchproject/opensearch:latest
    container_name: opensearch
    environment:
      - discovery.type=single-node
      - OPENSEARCH_SECURITY_DISABLED=false  # Temporarily, we'll disable security for simplicity.
    ports:
      - 9200:9200
      - 9600:9600
    networks:
      - opensearch-net
    volumes:
      - ./config.yml:/usr/share/opensearch/config/opensearch-security/config.yml # Mounts the security configuration file to the container

  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:latest
    container_name: opensearch-dashboards
    ports:
      - 5601:5601
    environment:
      OPENSEARCH_HOSTS: 'https://opensearch:9200'
    networks:
      - opensearch-net
    volumes:
      - ./opensearch_dashboards.yml:/usr/share/opensearch-dashboards/config/opensearch_dashboards.yml # Mount the configuration file to the container

  nginx:
    image: nginx:latest
    container_name: nginx-proxy
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 80:80
      - 8090:8090
    networks:
      - opensearch-net

networks:
  opensearch-net:

Everything works well, I was able to access dashboards both directly on 5601 or via proxy on 8090, of course with login screen.

Now next step was to add config.yml and opensearch_dashboards.yml, which I did by binding them as shown in docker-compose.yml file.

Content of config files is given in section below.

Configuration:
Content of config files is the following:
config.yml:

_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    http:
      anonymous_auth_enabled: false
      xff:
        enabled: true
        remoteIpHeader: "x-forwarded-for"
        internalProxies: opensearch-dashboards
    authc:
      basic_internal_auth_domain:
        description: "Authenticate via HTTP Basic against internal users database"
        http_enabled: true
        transport_enabled: true
        order: 4
        http_authenticator:
          type: basic
          challenge: true
        authentication_backend:
          type: intern
      proxy_auth_domain:
        description: "Authenticate via proxy"
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: proxy
          challenge: false
          config:
            user_header: "x-proxy-user"
            roles_header: "x-proxy-roles"
        authentication_backend:
          type: noop

opensearch_dashbards.yml

opensearch.hosts: [https://opensearch:9200]
opensearch.ssl.verificationMode: none
opensearch.username: kibanaserver
opensearch.password: kibanaserver
#opensearch.requestHeadersWhitelist: [authorization, securitytenant]
opensearch.requestHeadersAllowlist: ["securitytenant","Authorization","x-forwarded-for","x-proxy-user","x-proxy-roles"]

opensearch_security.auth.type: "proxy"
opensearch_security.proxycache.user_header: "x-proxy-user"
opensearch_security.proxycache.roles_header: "x-proxy-roles"

opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: [Private, Global]
opensearch_security.readonly_mode.roles: [kibana_read_only]
# Use this setting if you are running opensearch-dashboards without https
opensearch_security.cookie.secure: false
server.host: '0.0.0.0'

Relevant Logs or Screenshots:
When accessing via browser, url:, response is:

{"statusCode":401,"error":"Unauthorized","message":"Authentication Exception"}

In log, following entry appears:

e[36mnginx-proxy              |e[0m 192.168.208.1 - - [20/Oct/2023:07:54:12 +0000] "GET / HTTP/1.1" 401 78 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" "-"
e[32mopensearch-dashboards    |e[0m {"type":"response","@timestamp":"2023-10-20T07:54:12Z","tags":[],"pid":1,"method":"get","statusCode":401,"req":{"url":"/","method":"get","headers":{"x-forwarded-for":"192.168.208.1","x-proxy-user":"kibanaro","x-proxy-roles":"kibanauser,readall","host":"opensearchdash","connection":"close","cache-control":"max-age=0","sec-ch-ua":"\"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"","sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"Windows\"","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","sec-fetch-site":"none","sec-fetch-mode":"navigate","sec-fetch-user":"?1","sec-fetch-dest":"document","accept-encoding":"gzip, deflate, br","accept-language":"en-US,en;q=0.9,sr-RS;q=0.8,sr;q=0.7"},"remoteAddress":"192.168.208.4","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"},"res":{"statusCode":401,"responseTime":43,"contentLength":9},"message":"GET / 401 43ms - 9.0B"}
e[36mnginx-proxy              |e[0m 192.168.208.1 - - [20/Oct/2023:07:54:12 +0000] "GET /favicon.ico HTTP/1.1" 401 78 "http://localhost:8090/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" "-"
e[32mopensearch-dashboards    |e[0m {"type":"response","@timestamp":"2023-10-20T07:54:12Z","tags":[],"pid":1,"method":"get","statusCode":401,"req":{"url":"/favicon.ico","method":"get","headers":{"x-forwarded-for":"192.168.208.1","x-proxy-user":"kibanaro","x-proxy-roles":"kibanauser,readall","host":"opensearchdash","connection":"close","sec-ch-ua":"\"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"","sec-ch-ua-mobile":"?0","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36","sec-ch-ua-platform":"\"Windows\"","accept":"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8","sec-fetch-site":"same-origin","sec-fetch-mode":"no-cors","sec-fetch-dest":"image","referer":"http://localhost:8090/","accept-encoding":"gzip, deflate, br","accept-language":"en-US,en;q=0.9,sr-RS;q=0.8,sr;q=0.7"},"remoteAddress":"192.168.208.4","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36","referer":"http://localhost:8090/"},"res":{"statusCode":401,"responseTime":5,"contentLength":9},"message":"GET /favicon.ico 401 5ms - 9.0B"}

It seems that all relevant headers are passed by Nignx, but 401 response appears every time.
Any idea why this does not work?

Could you test the below instead?

      xff:
        enabled: true
        remoteIpHeader: "x-forwarded-for"
        internalProxies: '.*'