Continuing with the Vault theme. Now I will show you how to integrate Vault with LDAP, for authentication purposes.
The process is extremely simple. But it is worth remembering that we are using the LDAP already created and configured here on the site, in other posts.
https://devops-db.com/category/laboratory/openldap
First important point, the Vault host needs to have DNS configured and the certificate installed as well.
The certificate is installed in /etc/ssl/certs/, there are other posts here that show how to copy the certificate to the right folder: Example: https://devops-db.com/ldap-authentication-linux-ubuntu/
Since everything in devops-db is part of a single project, we will use the same certificate.
Sometimes you need to restart the service (I needed to restart the host) for the certificate to take effect.
Configuration.
Before starting, I installed the ldap-utils package to validate that everything is correct with the connection to the LDAP server.
apt install ldap-utils
ldapsearch -v -x -H ldaps://ldap.devops-db.info:636 -b "cn=Fausto Branco,ou=UserGroups,dc=ldap,dc=devops-db,dc=info" -D "cn=readonly-bind-dn,ou=ServiceGroups,dc=ldap,dc=devops-db,dc=info" -w "1234qwer"
[...]
dn: cn=Fausto Branco,ou=UserGroups,dc=ldap,dc=devops-db,dc=info
structuralObjectClass: inetOrgPerson
entryUUID: 1562ecb8-b08f-103e-892d-61f571994b65
creatorsName: cn=admin,dc=ldap,dc=devops-db,dc=info
createTimestamp: 20240527160821Z
memberOf: cn=GitLabGroup,ou=SecurityGroups,dc=ldap,dc=devops-db,dc=info
memberOf: cn=LinuxAdmin,ou=SecurityGroups,dc=ldap,dc=devops-db,dc=info
memberOf: cn=GitLabAdmin,ou=SecurityGroups,dc=ldap,dc=devops-db,dc=info
memberOf: cn=JenkinsAdmin,ou=SecurityGroups,dc=ldap,dc=devops-db,dc=info
memberOf: cn=JenkinsLabGroup,ou=SecurityGroups,dc=ldap,dc=devops-db,dc=info
entryCSN: 20240527221719.824263Z#000000#000#000000
modifyTimestamp: 20240527221719Z
modifiersName: cn=admin,dc=ldap,dc=devops-db,dc=info
entryDN: cn=Fausto Branco,ou=UserGroups,dc=ldap,dc=devops-db,dc=info
subschemaSubentry: cn=Subschema
hasSubordinates: FALSE
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Note that for security reasons, I use the readonly-bind-dn user that we created with read-only permissions.
If everything is ok, let’s configure the Vault.
You can use an hcl file and save it or directly via cli.
There is the possibility of filtering by groupfilter or userfilter for example, but in this test, I will leave them all open, I don’t have many users in LDAP and I want to do Policy tests.
vault auth enable ldap
Success! Enabled ldap auth method at: ldap/
#######################################################################################################################
vault write auth/ldap/config \
url="ldaps://ldap.devops-db.info:636" \
userdn="dc=ldap,dc=devops-db,dc=info" \
userattr="uid" \
groupdn="dc=ldap,dc=devops-db,dc=info" \
groupfilter="(|(memberUid={{.Username}})(member={{.UserDN}}))" \
groupattr="cn" \
binddn="cn=readonly-bind-dn,ou=ServiceGroups,dc=ldap,dc=devops-db,dc=info" \
bindpass='1234qwer' \
certificate=@/etc/ssl/certs/ldapcacert.crt \
max_page_size=-1 \
insecure_tls=true
Success! Data written to: auth/ldap/config
On the Vault page there is an explanation of each of them: https://developer.hashicorp.com/vault/api-docs/auth/ldap#parameters
Just one point of attention on the certificate parameter. Yes, there is the @ before the path and it only took effect when I copied it and restarted the host.
Since the certificate I use is a “homemade” one, there is no CA and I had to enable the insecure_tls option.
At this point, you should be able to log into Vault with LDAP. let’s try my user fbranco.
Access the vault URL and change the authentication to LDAP:


Now let’s try to login via cli:
vault login -method=ldap username=fbranco
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.CAESIK_9xkCnm7Jl0mdvu-g2_3YH_fwf9fqg_ej7VDG645YGGh4KHGh2cy43UkN2ZWxsTmN2Y0t1TGNNeWNkbDVrbmE
token_accessor k3sT6UwTirYuLYo1bqclzRjV
token_duration 768h
token_renewable true
token_policies ["default"]
identity_policies []
policies ["default"]
token_meta_username fbranco
Policies.
If we are going to control policies by LDAP group, then the same group must have been created in VAULT. In the example, I will use the LinuxAdmin group.
It is worth remembering that the hierarchy of policies, if the user has more than one policy, the least restrictive one applies.
With an administrative account:
vault write auth/ldap/groups/LinuxAdmin policies=vault-admin
Success! Data written to: auth/ldap/groups/LinuxAdmin
Then you can list and get details:
vault list auth/ldap/groups
Keys
----
linuxadmin
#######################################################################################################################
vault read auth/ldap/groups/linuxadmin
Key Value
--- -----
policies [vault-admin]
Now we have to create an administrative policy. It’s a bit extensive so it’s best to create a file for it.
https://github.com/faustobranco/devops-db/blob/master/vault/admin-policy.hcl
vault policy write vault-admin admin-policy.hcl
Success! Uploaded policy: vault-admin
You can now log in with admin permissions.
More Policy tests.
Okay, now let’s do a test with a second policy and another user.
ldapsearch -v -x -H ldaps://ldap.devops-db.info:636 -b "cn=usr-service-jenkins,ou=ServiceGroups,dc=ldap,dc=devops-db,dc=info" -D "cn=readonly-bind-dn,ou=ServiceGroups,dc=ldap,dc=devops-db,dc=info" -w "1234qwer" +
[...]
# usr-service-jenkins, ServiceGroups, ldap.devops-db.info
dn: cn=usr-service-jenkins,ou=ServiceGroups,dc=ldap,dc=devops-db,dc=info
structuralObjectClass: inetOrgPerson
entryUUID: b6f59182-b8f2-103e-8802-4dd6b0ebef4e
creatorsName: cn=admin,dc=ldap,dc=devops-db,dc=info
createTimestamp: 20240607082142Z
entryCSN: 20240607102318.138272Z#000000#000#000000
modifyTimestamp: 20240607102318Z
memberOf: cn=JenkinsLabGroup,ou=SecurityGroups,dc=ldap,dc=devops-db,dc=info
modifiersName: cn=admin,dc=ldap,dc=devops-db,dc=info
entryDN: cn=usr-service-jenkins,ou=ServiceGroups,dc=ldap,dc=devops-db,dc=info
subschemaSubentry: cn=Subschema
hasSubordinates: FALSE
[...]
Searching for the user usr-service-jenkins, we see that he is only a member of one group: JenkinsLabGroup. So let’s create this role, with only read permissions in the KV created in the post: https://devops-db.com/jenkins-vault-integration/
get the list of policies:
vault policy list
default
jenkins
python-rw
vault-admin
root
Let’s then create a group in Vault’s LDAP with the same name as the LDAP group: JenkinsLabGroup and assign the jenkins policy.
vault write auth/ldap/groups/JenkinsLabGroup policies=jenkins
Success! Data written to: auth/ldap/groups/JenkinsLabGroup
Log in:
vault login -method=ldap username=usr-service-jenkins
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.CAESIDvDG9Hc5K6YHcZlq8JsgrC6gCcF4vpnGTPCzbPbDJpcGh4KHGh2cy5RUFRvdUdNamx3Uk43TGc2M0JNQWFJQ3k
token_accessor Ydw8YkD42Tl7nFFU0q63kfF6
token_duration 768h
token_renewable true
token_policies ["default" "jenkins"]
identity_policies []
policies ["default" "jenkins"]
token_meta_username usr-service-jenkins
Take the permissions tests
vault kv get secret/infrastructure/jenkins/test-secret01
================== Secret Path ==================
secret/data/infrastructure/jenkins/test-secret01
======= Metadata =======
Key Value
--- -----
created_time 2025-02-03T18:01:02.576993738Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
====== Data ======
Key Value
--- -----
pwd 1234qwer
username usr-test01
#######################################################################################################################
vault kv put secret/infrastructure/jenkins/test-secret03 username="usr-test03" pwd="1234qwer"
Error writing data to secret/data/infrastructure/jenkins/test-secret03: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/secret/data/infrastructure/jenkins/test-secret03
Code: 403. Errors:
* 1 error occurred:
* permission denied