Debugging LDAP authorization configuration

Versions:

OpenSearch v2.11.0

Describe the issue:

I’ve got a self-contained project in which I’m trying to get opensearch to authorize against LDAP (using glauth). I feel like I’m very close but something is failing. I’m pretty sure I have an issue with some of my searches in the authorization_backend section (see below).

I’m hoping someone familiar with the authorization process help me figure out exactly where I’m wrong. The main issue here is the Cannot retrieve roles for User error you’ll see in the output below.

I’m going to be very verbose here (more details are usually better than fewer, right?). Don’t worry about the included creds in this example being posted, they’re only being used in this sandbox and are included here for reproducibility purposes.

background documentation I’ve read

the setup

  • if you want to get and run this test project:

  • my entire LDAP database

    • served by glauth with this config file
    • username we’re testing is analyst, password @nalyz3r
    • bind DN is cn=binddn,dc=nein,dc=local, password r3@d0n!y
dn: dc=nein,dc=local
dc: nein
dc: local
objectClass: organizationalUnit
objectClass: dcObject
objectClass: top

dn: ou=groups,dc=nein,dc=local
ou: groups
objectClass: organizationalUnit
objectClass: top

dn: ou=users,dc=nein,dc=local
ou: users
objectClass: organizationalUnit
objectClass: top

dn: ou=Administrator,ou=users,dc=nein,dc=local
ou: Administrator
uid: Administrator
description: Administrator
gidNumber: 500
uniqueMember: cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local
memberUid: analyst
objectClass: posixGroup
objectClass: top

dn: ou=Developers,ou=users,dc=nein,dc=local
ou: Developers
uid: Developers
description: Developers
gidNumber: 501
uniqueMember: cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local
memberUid: analyst
objectClass: posixGroup
objectClass: top

dn: ou=Service,ou=users,dc=nein,dc=local
ou: Service
uid: Service
description: Service
gidNumber: 502
uniqueMember: cn=binddn,ou=Service,ou=users,dc=nein,dc=local
uniqueMember: cn=sensor,ou=Service,ou=users,dc=nein,dc=local
memberUid: binddn
memberUid: sensor
objectClass: posixGroup
objectClass: top

dn: cn=binddn,ou=Service,ou=users,dc=nein,dc=local
cn: binddn
uid: binddn
ou: Service
uidNumber: 5001
accountStatus: active
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash
homeDirectory: /home/binddn
description: binddn
gecos: binddn
gidNumber: 502
memberOf: ou=Service,ou=groups,dc=nein,dc=local
shadowExpire: -1
shadowFlag: 134538308
shadowInactive: -1
shadowLastChange: 11000
shadowMax: 99999
shadowMin: -1
shadowWarning: 7

dn: cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local
cn: analyst
uid: analyst
givenName: Analyst
sn: McAnalyzer
ou: Administrator
uidNumber: 1000
accountStatus: active
mail: analyst@nein.local
userPrincipalName: analyst@nein.local
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash
homeDirectory: /home/analyst
description: analyst
gecos: analyst
gidNumber: 500
memberOf: ou=Administrator,ou=groups,dc=nein,dc=local
memberOf: ou=Developers,ou=groups,dc=nein,dc=local
shadowExpire: -1
shadowFlag: 134538308
shadowInactive: -1
shadowLastChange: 11000
shadowMax: 99999
shadowMin: -1
shadowWarning: 7

dn: cn=sensor,ou=Service,ou=users,dc=nein,dc=local
cn: sensor
uid: sensor
givenName: Sensor
sn: McSensorface
ou: Service
uidNumber: 1001
accountStatus: active
mail: sensor@nein.local
userPrincipalName: sensor@nein.local
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash
homeDirectory: /home/sensor
description: sensor
gecos: sensor
gidNumber: 502
memberOf: ou=Service,ou=groups,dc=nein,dc=local
shadowExpire: -1
shadowFlag: 134538308
shadowInactive: -1
shadowLastChange: 11000
shadowMax: 99999
shadowMin: -1
shadowWarning: 7
---
_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    http:
      anonymous_auth_enabled: false
    authc:
      internal_auth:
        order: 0
        description: "HTTP basic authentication using the internal user database"
        http_enabled: true
        transport_enabled: true
        http_authenticator:
          type: basic
          challenge: false
        authentication_backend:
          type: internal
      ldap_auth:
        order: 1
        description: "Authenticate using LDAP"
        http_enabled: true
        transport_enabled: true
        http_authenticator:
          type: basic
          challenge: false
        authentication_backend:
          type: ldap
          config:
            enable_ssl: true
            enable_start_tls: false
            enable_ssl_client_auth: false
            verify_hostnames: false
            pemtrustedcas_filepath: /usr/share/opensearch/config/root-ca.pem
            hosts:
            - glauth:636
            bind_dn: cn=binddn,dc=nein,dc=local
            password: "r3@d0n!y"
            userbase: ou=users,dc=nein,dc=local
            usersearch: (uid={0})
            username_attribute: uid
    authz:
      ldap_roles:
        description: "Authorize using LDAP"
        http_enabled: true
        transport_enabled: true
        authorization_backend:
          type: ldap
          config:
            enable_ssl: true
            enable_start_tls: false
            enable_ssl_client_auth: false
            verify_hostnames: false
            pemtrustedcas_filepath: /usr/share/opensearch/config/root-ca.pem
            hosts:
            - glauth:636
            bind_dn: cn=binddn,dc=nein,dc=local
            password: "r3@d0n!y"
            userbase: ou=users,dc=nein,dc=local
            usersearch: (uid={0})
            username_attribute: uid
            rolebase: ou=groups,dc=nein,dc=local
            rolesearch: (memberUid={1})
            userroleattribute: null
            userrolename: none
            rolename: ou
            resolve_nested_roles: true
            skip_users:
              - admin
              - kibanaserver
---

_meta:
  type: "rolesmapping"
  config_version: 2

all_access:
  reserved: false
  backend_roles:
  - "admin"
  - "Administrator"
  description: "Maps admin to all_access"

own_index:
  reserved: false
  users:
  - "*"
  description: "Allow full access to an index named like the username"

kibana_user:
  reserved: false
  backend_roles:
  - "kibanauser"
  - "Developers"
  - "Service"
  description: "Maps kibanauser to kibana_user"

readall:
  reserved: false
  backend_roles:
  - "readall"
  - "Developers"
  - "Service"

manage_snapshots:
  reserved: false
  backend_roles:
  - "snapshotrestore"
  - "Developers"
  - "Service"

kibana_server:
  reserved: true
  users:
  - "kibanaserver"

the process (taken from Docker containers’ logs)

$ curl -u analyst -k https://localhost:9200/_plugins/_security/api/account

  • Bind with binddn, successful
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Bind request basedn=dc=nein,dc=local binddn=cn=binddn,dc=nein,dc=local src=172.27.52.5:41690
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Bind success binddn=cn=binddn,dc=nein,dc=local src=172.27.52.5:41690
  • Search for user analyst successful
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Search request basedn=dc=nein,dc=local binddn=cn=binddn,dc=nein,dc=local filter=(uid=analyst) scope=2 searchbasedn=ou=users,dc=nein,dc=local src=172.27.52.5:41690
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Search request special case="top-level users node"
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF AP: Top-Level Users Browse OK filter=(uid=analyst)
  • Same search for user analyst, reproduced in ldapsearch, successfull:
$ ldapsearch -LLL -H ldap://$(dip opensearch-glauth-1):389 \
    -D 'cn=binddn,dc=nein,dc=local' -w 'r3@d0n!y' \
    -s sub \
    -b 'ou=users,dc=nein,dc=local' \
    '(uid=analyst)'

dn: cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local
cn: analyst
uid: analyst
givenName: Analyst
sn: McAnalyzer
ou: Administrator
uidNumber: 1000
accountStatus: active
mail: analyst@nein.local
userPrincipalName: analyst@nein.local
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash
homeDirectory: /home/analyst
description: analyst
gecos: analyst
gidNumber: 500
memberOf: ou=Administrator,ou=groups,dc=nein,dc=local
memberOf: ou=Developers,ou=groups,dc=nein,dc=local
shadowExpire: -1
shadowFlag: 134538308
shadowInactive: -1
shadowLastChange: 11000
shadowMax: 99999
shadowMin: -1
shadowWarning: 7

  • Bind with analyst, successful
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Bind request basedn=dc=nein,dc=local binddn=cn=analyst,ou=administrator,ou=users,dc=nein,dc=local src=172.27.52.5:41696
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Bind success binddn=cn=analyst,ou=administrator,ou=users,dc=nein,dc=local src=172.27.52.5:41696
  • Bind with binddn, successful
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Bind request basedn=dc=nein,dc=local binddn=cn=binddn,dc=nein,dc=local src=172.27.52.5:41708
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Bind success binddn=cn=binddn,dc=nein,dc=local src=172.27.52.5:41708
  • Search for objectClass=* in cn=analyst,ou=administrator,ou=users,dc=nein,dc=local, fails?
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Search request basedn=dc=nein,dc=local binddn=cn=binddn,dc=nein,dc=local filter=(objectClass=*) scope=0 searchbasedn=cn=analyst,ou=administrator,ou=users,dc=nein,dc=local src=172.27.52.5:41708
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF Search request default case=
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF AP: Account Search OK filter=(objectClass=*)
opensearch-glauth-1  | Wed, 29 Nov 2023 17:49:20 +0000 INF AP: Search OK filter=(objectClass=*)
opensearch-node1     | [2023-11-29T17:49:20,931][ERROR][o.o.s.a.BackendRegistry  ] [opensearch-node1] Cannot retrieve roles for User [name=analyst, backend_roles=[], requestedTenant=null] from ldap due to OpenSearchSecurityException[OpenSearchSecurityException[No user 'cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local' found]]; nested: OpenSearchSecurityException[No user 'cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local' found];
opensearch-node1     | org.opensearch.OpenSearchSecurityException: OpenSearchSecurityException[No user 'cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local' found]
  • Same search reproduced with ldapsearch (no results)
$ ldapsearch -LLL -H ldap://$(dip opensearch-glauth-1):389 \
    -D 'cn=binddn,dc=nein,dc=local' -w 'r3@d0n!y' \
    -s base \
    -b 'cn=analyst,ou=administrator,ou=users,dc=nein,dc=local' \
    '(objectClass=*)'

Hi @tlacuache ,

In your ldapsearch you are using ldap:389 and in your config.yml you are setting up ldaps:636 (with your pemtrustedcas_filepath: /usr/share/opensearch/config/root-ca.pem ).

Could you run ldapsearch against the ldaps:636 and query one of the users that you are expecting the rolename: ou based on rolebase: ou=groups,dc=nein,dc=local to translate to one of the backend roles defined in your roles_mapping.yml (in your case: “Developers” or “Service”

Could you please share your roles.yml as well?

Let me know if you have any questions.

Best,
Mantas

Thank you for responding. I’ve got my server listening on both LDAP (389) and LDAPS (636) and just used 389 on the command-line for convenience. The same results are returned from both.

Here is the search for all the groups (base for search is ou=groups,dc=nein,dc=local, no filter):

dn: ou=groups,dc=nein,dc=local
ou: groups
objectClass: organizationalUnit
objectClass: top

dn: ou=Administrator,ou=groups,dc=nein,dc=local
ou: Administrator
uid: Administrator
description: Administrator
gidNumber: 500
uniqueMember: cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local
objectClass: groupOfUniqueNames
objectClass: top

dn: ou=Developers,ou=groups,dc=nein,dc=local
ou: Developers
uid: Developers
description: Developers
gidNumber: 501
uniqueMember: cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local
objectClass: groupOfUniqueNames
objectClass: top

dn: ou=Service,ou=groups,dc=nein,dc=local
ou: Service
uid: Service
description: Service
gidNumber: 502
uniqueMember: cn=binddn,ou=Service,ou=users,dc=nein,dc=local
uniqueMember: cn=sensor,ou=Service,ou=users,dc=nein,dc=local
objectClass: groupOfUniqueNames
objectClass: top

Here is the search for a user belonging to the Developers group (base for search is ou=users,dc=nein,dc=local, search filter is (memberOf=ou=Developers,ou=groups,dc=nein,dc=local)):

dn: cn=analyst,ou=Administrator,ou=users,dc=nein,dc=local
cn: analyst
uid: analyst
givenName: Analyst
sn: McAnalyzer
ou: Administrator
uidNumber: 1000
accountStatus: active
mail: analyst@nein.local
userPrincipalName: analyst@nein.local
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash
homeDirectory: /home/analyst
description: analyst
gecos: analyst
gidNumber: 500
memberOf: ou=Administrator,ou=groups,dc=nein,dc=local
memberOf: ou=Developers,ou=groups,dc=nein,dc=local
shadowExpire: -1
shadowFlag: 134538308
shadowInactive: -1
shadowLastChange: 11000
shadowMax: 99999
shadowMin: -1
shadowWarning: 7

Here is my roles.yml:

_meta:
  type: "roles"
  config_version: 2

# Restrict users so they can only view visualization and dashboard on OpenSearchDashboards
kibana_read_only:
  reserved: true

# The security REST API access role is used to assign specific users access to change the security settings through the REST API.
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'
    - 'cluster:admin/opensearch/alerting/findings/get'

# 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/*'
    - 'cluster:admin/opensearch/alerting/*'
    - 'cluster:admin/opensearch/notifications/feature/publish'
  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/*"
    - "cluster:admin/opensearch/notifications/feature/publish"
  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"

# Allow users to read ML stats/models/tasks
ml_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/ml/stats/nodes'
    - 'cluster:admin/opensearch/ml/models/get'
    - 'cluster:admin/opensearch/ml/models/search'
    - 'cluster:admin/opensearch/ml/tasks/get'
    - 'cluster:admin/opensearch/ml/tasks/search'

# Allows users to use all ML functionality
ml_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster_monitor'
    - 'cluster:admin/opensearch/ml/*'
  index_permissions:
    - index_patterns:
        - '*'
      allowed_actions:
        - 'indices_monitor'

# Allows users to use all Notifications functionality
notifications_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/notifications/*'

# Allows users to read Notifications config/channels
notifications_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/notifications/configs/get'
    - 'cluster:admin/opensearch/notifications/features'
    - 'cluster:admin/opensearch/notifications/channels/get'

# Allows users to use all snapshot management functionality
snapshot_management_full_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/snapshot_management/*'
    - 'cluster:admin/opensearch/notifications/feature/publish'
    - 'cluster:admin/repository/*'
    - 'cluster:admin/snapshot/*'

# Allows users to see snapshots, repositories, and snapshot management policies
snapshot_management_read_access:
  reserved: true
  cluster_permissions:
    - 'cluster:admin/opensearch/snapshot_management/policy/get'
    - 'cluster:admin/opensearch/snapshot_management/policy/search'
    - 'cluster:admin/opensearch/snapshot_management/policy/explain'
    - 'cluster:admin/repository/get'
    - 'cluster:admin/snapshot/get'

Hi @tlacuache

Could you please test your Authorization with the below:

authz:
      ldap_roles:
        description: "Authorize using LDAP"
        http_enabled: true
        transport_enabled: true
        authorization_backend:
          type: ldap
          config:
            enable_ssl: true
            enable_start_tls: false
            enable_ssl_client_auth: false
            verify_hostnames: false
            pemtrustedcas_filepath: /usr/share/opensearch/config/root-ca.pem
            hosts:
            - glauth:636
            bind_dn: cn=binddn,dc=nein,dc=local
            password: "r3@d0n!y"
            userbase: ou=users,dc=nein,dc=local
            usersearch: (uid={0})
            username_attribute: cn
            rolebase: ou=groups,dc=nein,dc=loca
            rolesearch: uniqueMember
            userroleattribute: null
            userrolename: none
            rolename: ou
            resolve_nested_roles: true
            skip_users:
              - admin
              - kibanaserver

Thanks,
Mantas

Could you also run the curl command below and share the outcome with me (both authz(s) if possible):

curl --insecure -u <ldap_user>:<ldap_password> -XGET https://<OS_node>:9200/_plugins/_security/authinfo?pretty

Thanks

Here it is with the original config.yml authz section:

{
  "user" : "User [name=analyst, backend_roles=[], requestedTenant=null]",
  "user_name" : "analyst",
  "user_requested_tenant" : null,
  "remote_address" : "172.26.28.1:58394",
  "backend_roles" : [ ],
  "custom_attribute_names" : [
    "attr.ldap.accountStatus",
    "ldap.original.username",
    "attr.ldap.shadowLastChange",
    "attr.ldap.userPrincipalName",
    "attr.ldap.shadowInactive",
    "attr.ldap.objectClass",
    "attr.ldap.uid",
    "attr.ldap.givenName",
    "attr.ldap.shadowFlag",
    "ldap.dn",
    "attr.ldap.cn",
    "attr.ldap.gidNumber",
    "attr.ldap.description",
    "attr.ldap.ou",
    "attr.ldap.shadowMin",
    "attr.ldap.shadowWarning",
    "attr.ldap.uidNumber",
    "attr.ldap.gecos",
    "attr.ldap.sn",
    "attr.ldap.shadowExpire",
    "attr.ldap.homeDirectory",
    "attr.ldap.shadowMax",
    "attr.ldap.loginShell",
    "attr.ldap.mail"
  ],
  "roles" : [
    "own_index"
  ],
  "tenants" : {
    "analyst" : true
  },
  "principal" : null,
  "peer_certificates" : "0",
  "sso_logout_url" : null
}

With the new authz section you posted above, the output of that curl command is identical as to the first (minus the remote_address, which changed as the docker network went down and back up). Error message in the logs seems to be the same as well.

Hi @tlacuache,

I will run some tests in my lab and update you shortly.
What IDP are you using for your LDAP?

Best,
Mantas

Every part of my example is completely self-contained and reproducible, see my original post. You can just grab that directory from the github repo I linked. The LDAP server is glauth, and is built-in as part of my docker-compose services.

It is certainly possible this could be an issue with glauth, that’s one of the things I’m trying to figure out. I could try it with openldap instead, I guess.

Hi @tlacuache, I have tried to set Glauth as per your example using the same configuration and I had no luck searching for the roles as of yet. I have also noticed that the bind user/dn does not have full access to read schema which might be an issue.
I will keep you updated if any progress.

Have you tried it with OpenLDAP yet? I have integrated OpenSearch with it, in the past, with no issues.

Best,
Mantas

I greatly appreciate you looking. I worried that it might be an issue with glauth not doing something quite up to the LDAP spec. I like using glauth for other projects as it’s simpler to deploy and configure than openldap but I have used that in the past as well so I’ll switch to that and give it a shot.

I wanted something lighter and more modern than openLDAP so I tried out lldap as an alternative to glauth. I was able to get it working correctly. Thank you for looking at this with me.

You are welcome, glad to hear you made it work. will keep you updated on glauth.

Thanks. I do like glauth because it has support for yubikey, 2fa and multiple backends, but for now switching to lldap has got me up and running. I appreciate your time.