OpenLDAP: Implementing Least-Privilege Bind Authentication with Attribute-Level Access Control


2 views

Many applications need LDAP bind credentials for authentication purposes, but granting full read access creates security risks. The challenge is to implement:

  • Precise attribute filtering
  • Minimal required privileges
  • Secure authentication without information leakage

For most authentication scenarios, you only need:

userPassword (or equivalent like sambaNTPassword)
uid
cn
objectClass (to verify entity type)
accountStatus attributes (like pwdAccountLockedTime)

1. Creating the Restricted Bind User

dn: ou=Applications,dc=example,dc=com
objectclass: top 
objectClass: organizationalunit
ou: Applications

dn: cn=gitlab,ou=Applications,dc=example,dc=com
cn: gitlab
objectClass: simpleSecurityObject
objectClass: organizationalRole
userPassword: {SSHA}hashedpassword

2. Implementing Fine-Grained ACLs

Here's the proper ACL syntax for cn=config:

dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {3}to dn.subtree="ou=People,dc=example,dc=com"
  attrs=userPassword,uid,cn,objectClass
  by dn.exact="cn=gitlab,ou=Applications,dc=example,dc=com" read
  by * none

3. Verifying the Restrictions

Test with ldapsearch:

ldapsearch -H ldaps://ldap.example.com \
-D "cn=gitlab,ou=Applications,dc=example,dc=com" \
-W -b "ou=People,dc=example,dc=com" \
"(uid=testuser)" uid cn userPassword
  • Attribute visibility issues: Ensure you're modifying the correct database backend (check with ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config 'olcDatabase=*')
  • ACL ordering: OpenLDAP evaluates ACLs in sequence - place more specific rules first
  • Samba attributes: For Samba environments, replace userPassword with sambaNTPassword

For applications that need read-only access to specific attributes:

dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {4}to dn.subtree="ou=People,dc=example,dc=com"
  attrs=entry,uid,cn,mail,objectClass,telephoneNumber
  by dn.exact="cn=gitlab,ou=Applications,dc=example,dc=com" read
  by * none

When implementing attribute-level restrictions:

  • ACL processing adds minimal overhead (typically <5% performance impact)
  • For high-volume systems, consider dedicated proxy instances with pre-filtered views
  • Monitor with slapd -d 16383 for ACL evaluation debugging

When implementing LDAP authentication for applications like GitLab, we need to balance functionality with security. The bind account shouldn't have unnecessary privileges or visibility into sensitive attributes beyond what's strictly required for authentication.

For most authentication scenarios, these are the minimal attributes required:

dn
uid
userPassword (or equivalent like sambaNTPassword)
account status attributes (accountStatus, pwdAccountLockedTime)

The issue stems from OpenLDAP's default ACLs. Let's examine a more secure configuration:

# First, let's view current ACLs
ldapsearch -Y EXTERNAL -H ldapi:/// -b olcDatabase={1}mdb,cn=config olcAccess

# Recommended ACL modifications for application bind users
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {3}to dn.subtree="ou=People,dc=example,dc=com"
  by dn.exact="cn=gitlab,ou=Applications,dc=example,dc=com" read
  by * break

add: olcAccess
olcAccess: {4}to attrs=userPassword,sambaNTPassword
  by dn.exact="cn=gitlab,ou=Applications,dc=example,dc=com" compare
  by self write
  by anonymous auth
  by * none

To implement attribute-level restrictions, we can use OpenLDAP's access controls:

# Create a whitelist of visible attributes
dn: olcDatabase={1}mdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {5}to dn.subtree="ou=People,dc=example,dc=com"
  attrs=uid,cn,mail,displayName
  by dn.exact="cn=gitlab,ou=Applications,dc=example,dc=com" read
  by * break

Verify the restrictions are working properly:

# Test with full admin
ldapsearch -D "cn=admin,dc=example,dc=com" -W -b "ou=People,dc=example,dc=com"

# Test with application bind user
ldapsearch -D "cn=gitlab,ou=Applications,dc=example,dc=com" -W \
  -b "ou=People,dc=example,dc=com" "(uid=testuser)"

If using Samba attributes, you'll need additional controls:

# Restrict samba attributes separately
olcAccess: {6}to attrs=sambaNTPassword,sambaLMPassword
  by dn.exact="cn=gitlab,ou=Applications,dc=example,dc=com" compare
  by * none
  • Always create dedicated OUs for service accounts
  • Use simpleSecurityObject for application bind users
  • Regularly audit ACL effectiveness with ldapsearch tests
  • Consider using TLS client certificates for additional security