Introduction
The ldap authentication technique may be used with LDAP (Identity Provider) servers for username and password type credentials. This allows Vault to be incorporated into setups that already utilise LDAP without duplicating user settings.
We'll demonstrate scenario on vault 1.15.1
with LDAP auth method
Scenario
When we have a recursive group under the LDAP tree shown below and we want to assign different policies to all of these groups, for example, prod is the parent group, which has two child groups, operations and developers, and further operations has one more child group, vaultadmin, and we have respective users present in all of these groups who will login to Vault via ldap auth and will have different access levels in Vault due to group policy mapping.
Setup & Configuration
LDAP Configuration
An OpenLDAP docker image provided by osixia/OpenLDAP as well vault 1.15.1
is used in this demo.
# Set 'osixia/openldap:1.3.0' for specific versions.
docker run -p 389:389 --detach osixia/openldap ;
docker ps | grep ldap ; # find the current running ldap CONTAINER_ID
docker exec -it 247c4b6c1b7f /bin/bash ; # attach to container using its bash prompt
Within docker container process attached to:
# // on LDAP docker:
printf "%s" """\
dn: ou=groups,dc=example,dc=org
objectClass: organizationalunit
objectClass: top
ou: groups
description: groups of users
dn: ou=users,dc=example,dc=org
objectClass: organizationalunit
objectClass: top
ou: users
description: users
dn: cn=prod,ou=groups,dc=example,dc=org
objectClass: groupofnames
objectClass: top
description: parent group prod
cn: prod
member: cn=ash,ou=users,dc=example,dc=org
dn: cn=operations,cn=prod,ou=groups,dc=example,dc=org
objectClass: groupofnames
objectClass: top
description: child of parent group prod
cn: operations
member: cn=alex,ou=users,dc=example,dc=org
dn: cn=vaultadmin,cn=operations,cn=prod,ou=groups,dc=example,dc=org
objectClass: groupofnames
objectClass: top
description: child of operations group which is child of parent group prod
cn: vaultadmin
member: cn=bob,ou=users,dc=example,dc=org
dn: cn=developers,cn=prod,ou=groups,dc=example,dc=org
objectClass: groupofnames
objectClass: top
description: child of parent group prod
cn: developers
member: cn=siri,ou=users,dc=example,dc=org
dn: cn=ash,ou=users,dc=example,dc=org
objectClass: person
objectClass: top
cn: ash
sn: ash
memberOf: cn=prod,ou=groups,dc=example,dc=org
userPassword: ash
dn: cn=alex,ou=users,dc=example,dc=org
objectClass: person
objectClass: top
cn: alex
sn: alex
memberOf: cn=operations,cn=prod,ou=groups,dc=example,dc=org
userPassword: alex
dn: cn=bob,ou=users,dc=example,dc=org
objectClass: person
objectClass: top
cn: bob
sn: bob
memberOf: cn=vaultadmin,cn=operations,cn=prod,ou=groups,dc=example,dc=org
userPassword: bob
dn: cn=siri,ou=users,dc=example,dc=org
objectClass: person
objectClass: top
cn: siri
sn: siri
memberOf: cn=developers,cn=prod,ou=groups,dc=example,dc=org
userPassword: siri
""" > ldap_seed_recursive_group.ldif ; # // an example ldif with changes to apply
# ldapadd -x -W -D "cn=admin,dc=example,dc=org" -f ldap_seed_recursive_group.ldif
# Enter LDAP Password: admin
# adding new entry "ou=groups,dc=example,dc=org"
# adding new entry "ou=users,dc=example,dc=org"
# adding new entry "cn=operations,cn=prod,ou=groups,dc=example,dc=org"
# adding new entry "cn=vaultadmin,cn=operations,cn=prod,ou=groups,dc=example,dc=org"
# adding new entry "cn=developers,cn=prod,ou=groups,dc=example,dc=org"
# adding new entry "cn=ash,ou=users,dc=example,dc=org"
# adding new entry "cn=alex,ou=users,dc=example,dc=org"
# adding new entry "cn=bob,ou=users,dc=example,dc=org"
# adding new entry "cn=siri,ou=users,dc=example,dc=org"
The LDIF file (ldap_seed_recursive_group.ldif
) yields two branches of groups
and users
within the suffix example.org
within one group named prod
, which has two child groups named operations
& developers
, and operations
has one more group called vaultadmin
within the branch groups and assigned to their respective users. So, among the individuals established in the users
branch, ash
is a member of the prod
group, alex
is a member of the operations
group, bob
is a member of the vaultadmin
group, and siri
is a member of the developers
group.
Vault Configuration
# // on Vault host
vault auth enable ldap ;
# Success! Enabled ldap auth method at: ldap/
export LDAP_ADDR='ldap://192.168.50.40:389' ;
root@vaults0:/home/vagrant# vault write auth/ldap/config url="${LDAP_ADDR}" \
bindpass="admin" \
starttls=false \
userdn="ou=users,dc=example,dc=org" \
groupdn="ou=groups,dc=example,dc=org" \
binddn="cn=admin,dc=example,dc=org" \
userfilter="(&(objectClass=Person)({{.UserAttr}}={{.Username}})(|(memberOf=cn=prod,ou=groups,dc=example,dc=org)(memberOf=cn=developers,cn=prod,ou=groups,dc=example,dc=org)(memberOf=cn=operations,cn=prod,ou=groups,dc=example,dc=org)(memberOf=cn=vaultadmin,cn=operations,cn=prod,ou=groups,dc=example,dc=org)))" \
groupfilter="(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))" ;
# Success! Data written to: auth/ldap/config
Now, under LDAP Auth, create a group with pre-existing policies with the same name as the LDAP group name.
root@vaults0:/home/vagrant# vault write auth/ldap/groups/prod policies=admin ;
# Success! Data written to: auth/ldap/groups/prod
root@vaults0:/home/vagrant# vault write auth/ldap/groups/operations policies=admin ;
# Success! Data written to: auth/ldap/groups/operations
root@vaults0:/home/vagrant# vault write auth/ldap/groups/developers policies=admin_policy ;
# Success! Data written to: auth/ldap/groups/developers
root@vaults0:/home/vagrant# vault write auth/ldap/groups/vaultadmin policies=admin_auth ;
# Success! Data written to: auth/ldap/groups/vaultadmin
root@vaults0:/home/vagrant#
Login with Vault LDAP auth in order to verify the group policy mapping. We can also login from the Vault UI.
root@vaults0:/home/vagrant# vault login -method=ldap username=ash
Password (will be hidden):
# Success! You are now authenticated. The token information displayed below
# is already stored in the token helper. You do NOT need to run "vault login"
# again. Future Vault requests will automatically use this token.
# Key Value
# --- -----
# token hvs.CAESILiFx2OZkDfCjqbNgLJCrKE6SclajYtAaUrMWYTez-OIGiQKHGh2cy5PdFhodUZhcTdSdnhFMjVEdHhZVGpoczAQzpQVGAM
# token_accessor XEi8fWoz8vSu08K5qHGdKv1y
# token_duration 768h
# token_renewable true
# token_policies ["admin" "default"]
# identity_policies []
# policies ["admin" "default"]
# token_meta_username ash
Reference Links:
- https://www.vaultproject.io/docs/auth/ldap
- https://www.vaultproject.io/api-docs/auth/ldap
- https://hub.docker.com/r/osixia/openldap