2020-02-21 15:55:15 +00:00
---
layout: docs
2022-10-05 20:16:26 +00:00
page_title: LDAP - Secrets Engine
2020-02-21 15:55:15 +00:00
description: >-
2022-10-05 20:16:26 +00:00
The LDAP secret engine manages LDAP entry passwords.
2020-02-21 15:55:15 +00:00
---
2022-10-05 20:16:26 +00:00
# LDAP Secrets Engine
2020-02-21 15:55:15 +00:00
2022-06-01 19:41:11 +00:00
@include 'x509-sha1-deprecation.mdx'
2022-10-05 20:16:26 +00:00
The LDAP secret engine allows management of LDAP entry passwords as well as dynamic creation of credentials.
2021-02-05 17:49:29 +00:00
This engine supports interacting with Active Directory which is compatible with LDAP v3.
2020-02-21 15:55:15 +00:00
This plugin currently supports LDAP v3.
## Quick Setup
2022-10-05 20:16:26 +00:00
1. Enable the LDAP secret engine:
2020-02-21 15:55:15 +00:00
2020-12-17 21:53:33 +00:00
```sh
2022-10-05 20:16:26 +00:00
$ vault secrets enable ldap
2020-12-17 21:53:33 +00:00
```
2020-02-21 15:55:15 +00:00
2020-12-17 21:53:33 +00:00
By default, the secrets engine will mount at the name of the engine. To
enable the secrets engine at a different path, use the `-path` argument.
2020-02-21 15:55:15 +00:00
2022-10-05 20:16:26 +00:00
2. Configure the credentials that Vault uses to communicate with LDAP
2020-12-17 21:53:33 +00:00
to generate passwords:
2020-02-21 15:55:15 +00:00
2020-12-17 21:53:33 +00:00
```sh
2022-10-05 20:16:26 +00:00
$ vault write ldap/config \
2020-12-17 21:53:33 +00:00
binddn=$USERNAME \
bindpass=$PASSWORD \
url=ldaps://138.91.247.105
```
2020-02-21 15:55:15 +00:00
2021-02-05 17:49:29 +00:00
Note: it's recommended a dedicated entry management account be created specifically for Vault.
2020-02-21 15:55:15 +00:00
2020-06-02 17:34:01 +00:00
3. Rotate the root password so only Vault knows the credentials:
2020-02-21 15:55:15 +00:00
2020-12-17 21:53:33 +00:00
```sh
2022-10-05 20:16:26 +00:00
$ vault write -f ldap/rotate-root
2020-12-17 21:53:33 +00:00
```
2020-02-21 15:55:15 +00:00
2020-12-17 21:53:33 +00:00
Note: it's not possible to retrieve the generated password once rotated by Vault.
2021-11-15 19:52:04 +00:00
It's recommended a dedicated entry management account be created specifically for Vault.
2020-02-21 15:55:15 +00:00
2021-02-05 17:49:29 +00:00
### Password Generation
This engine previously allowed configuration of the length of the password that is generated
when rotating credentials. This mechanism was deprecated in Vault 1.5 in favor of
[password policies](/docs/concepts/password-policies). This means the `length` field should
no longer be used. The following password policy can be used to mirror the same behavior
that the `length` field provides:
```hcl
length=<length>
rule "charset" {
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
}
```
## Static Roles
### Setup
2022-10-05 20:16:26 +00:00
1. Configure a static role that maps a name in Vault to an entry in LDAP.
2020-12-17 21:53:33 +00:00
Password rotation settings will be managed by this role.
2020-02-21 15:55:15 +00:00
2020-12-17 21:53:33 +00:00
```sh
2022-10-05 20:16:26 +00:00
$ vault write ldap/static-role/hashicorp \
2020-12-17 21:53:33 +00:00
dn='uid=hashicorp,ou=users,dc=hashicorp,dc=com' \
username='hashicorp' \
rotation_period="24h"
```
2020-02-21 15:55:15 +00:00
2021-02-05 17:49:29 +00:00
2. Request credentials for the "hashicorp" role:
2020-06-02 17:34:01 +00:00
2020-12-17 21:53:33 +00:00
```sh
2022-10-05 20:16:26 +00:00
$ vault read ldap/static-cred/hashicorp
2020-12-17 21:53:33 +00:00
```
2020-02-21 15:55:15 +00:00
2021-02-05 17:49:29 +00:00
### LDAP Password Policy
2020-08-31 17:05:27 +00:00
2022-10-05 20:16:26 +00:00
The LDAP secret engine does not hash or encrypt passwords prior to modifying
2020-08-31 17:05:27 +00:00
values in LDAP. This behavior can cause plaintext passwords to be stored in LDAP.
2020-12-17 21:53:33 +00:00
To avoid having plaintext passwords stored, the LDAP server should be configured
with an LDAP password policy (ppolicy, not to be confused with a Vault password
policy). A ppolicy can enforce rules such as hashing plaintext passwords by default.
2020-08-31 17:05:27 +00:00
2020-12-17 21:53:33 +00:00
The following is an example of an LDAP password policy to enforce hashing on the
2020-08-31 17:05:27 +00:00
data information tree (DIT) `dc=hashicorp,dc=com`:
```
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: ppolicy
dn: olcOverlay={2}ppolicy,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcPPolicyConfig
objectClass: olcOverlayConfig
olcOverlay: {2}ppolicy
olcPPolicyDefault: cn=default,ou=pwpolicies,dc=hashicorp,dc=com
olcPPolicyForwardUpdates: FALSE
olcPPolicyHashCleartext: TRUE
olcPPolicyUseLockout: TRUE
2020-12-17 21:53:33 +00:00
```
2020-08-31 17:05:27 +00:00
2021-02-05 17:49:29 +00:00
### Schema
2020-03-06 22:46:33 +00:00
2022-10-05 20:16:26 +00:00
The LDAP Secret Engine supports three different schemas:
- `openldap` (default)
- `racf`
- `ad`
2020-03-06 22:46:33 +00:00
2021-02-05 17:49:29 +00:00
#### OpenLDAP
2020-03-06 22:46:33 +00:00
2022-10-05 20:16:26 +00:00
By default, the LDAP Secret Engine assumes the entry password is stored in `userPassword`.
2022-08-31 16:58:25 +00:00
There are many object classes that provide `userPassword` including for example:
2020-03-06 22:46:33 +00:00
2020-12-17 21:53:33 +00:00
- `organization`
- `organizationalUnit`
2022-08-31 16:58:25 +00:00
- `organizationalRole`
- `inetOrgPerson`
2020-12-17 21:53:33 +00:00
- `person`
- `posixAccount`
2020-03-06 22:46:33 +00:00
2021-02-05 17:49:29 +00:00
#### Resource Access Control Facility (RACF)
2020-03-06 22:46:33 +00:00
2020-06-02 17:34:01 +00:00
For managing IBM's Resource Access Control Facility (RACF) security system, the secret
2020-03-06 22:46:33 +00:00
engine must be configured to use the schema `racf`.
2020-06-02 17:34:01 +00:00
Generated passwords must be 8 characters or less to support RACF. The length of the
password can be configured using a [password policy](/docs/concepts/password-policies):
2020-03-06 22:46:33 +00:00
```bash
2022-10-05 20:16:26 +00:00
$ vault write ldap/config \
2020-03-06 22:46:33 +00:00
binddn=$USERNAME \
bindpass=$PASSWORD \
url=ldaps://138.91.247.105 \
2020-06-02 17:34:01 +00:00
schema=racf \
password_policy=racf_password_policy
```
2021-02-05 17:49:29 +00:00
#### Active Directory (AD)
2020-08-10 09:24:38 +00:00
For managing Active Directory instances, the secret engine must be configured to use the
schema `ad`.
```bash
2022-10-05 20:16:26 +00:00
$ vault write ldap/config \
2020-08-10 09:24:38 +00:00
binddn=$USERNAME \
bindpass=$PASSWORD \
url=ldaps://138.91.247.105 \
schema=ad
```
2021-02-05 17:49:29 +00:00
### Password Rotation
2020-02-21 15:55:15 +00:00
Passwords can be managed in two ways:
2022-10-05 20:16:26 +00:00
- automatic time based rotation
- manual rotation
2020-02-21 15:55:15 +00:00
### Auto Password Rotation
2020-06-02 17:34:01 +00:00
Passwords will automatically be rotated based on the `rotation_period` configured
in the static role (minimum of 5 seconds). When requesting credentials for a static
2020-02-21 15:55:15 +00:00
role, the response will include the time before the next rotation (`ttl`).
2020-06-02 17:34:01 +00:00
Auto-rotation is currently only supported for static roles. The `binddn` account used
by Vault should be rotated using the `rotate-root` endpoint to generate a password
2020-02-21 15:55:15 +00:00
only Vault will know.
### Manual Rotation
2020-06-02 17:34:01 +00:00
Static roles can be manually rotated using the `rotate-role` endpoint. When manually
2020-02-21 15:55:15 +00:00
rotated the rotation period will start over.
2021-02-05 17:49:29 +00:00
### Deleting Static Roles
2020-02-21 15:55:15 +00:00
2020-06-02 17:34:01 +00:00
Passwords are not rotated upon deletion of a static role. The password should be manually
2020-02-21 15:55:15 +00:00
rotated prior to deleting the role or revoking access to the static role.
2020-08-01 00:25:27 +00:00
2021-02-05 17:49:29 +00:00
## Dynamic Credentials
### Setup
Dynamic credentials can be configured by calling the `/role/:role_name` endpoint:
```bash
2022-10-05 20:16:26 +00:00
$ vault write ldap/role/dynamic-role \
2021-02-05 17:49:29 +00:00
creation_ldif=@/path/to/creation.ldif \
deletion_ldif=@/path/to/deletion.ldif \
rollback_ldif=@/path/to/rollback.ldif \
default_ttl=1h \
max_ttl=24h
```
-> Note: The `rollback_ldif` argument is optional, but recommended. The statements within `rollback_ldif` will be
2021-04-06 17:49:04 +00:00
executed if the creation fails for any reason. This ensures any entities are removed in the event of a failure.
2021-02-05 17:49:29 +00:00
To generate credentials:
```bash
2022-10-05 20:16:26 +00:00
$ vault read ldap/creds/dynamic-role
2021-02-05 17:49:29 +00:00
Key Value
--- -----
2022-10-05 20:16:26 +00:00
lease_id ldap/creds/dynamic-role/HFgd6uKaDomVMvJpYbn9q4q5
2021-02-05 17:49:29 +00:00
lease_duration 1h
lease_renewable true
distinguished_names [cn=v_token_dynamic-role_FfH2i1c4dO_1611952635,ou=users,dc=learn,dc=example]
password xWMjkIFMerYttEbzfnBVZvhRQGmhpAA0yeTya8fdmDB3LXDzGrjNEPV2bCPE9CW6
username v_token_testrole_FfH2i1c4dO_1611952635
```
The `distinguished_names` field is an array of DNs that are created from the `creation_ldif` statements. If more than
one LDIF entry is included, the DN from each statement will be included in this field. Each entry in this field
corresponds to a single LDIF statement. No de-duplication occurs and order is maintained.
### LDIF Entries
User account management is provided through LDIF entries. The LDIF entries may be a base64-encoded version of the
LDIF string. The string will be parsed and validated to ensure that it adheres to LDIF syntax. A good reference
for proper LDIF syntax can be found [here](https://ldap.com/ldif-the-ldap-data-interchange-format/).
Some important things to remember when crafting your LDIF entries:
- There should not be any trailing spaces on any line, including empty lines
- Each `modify` block needs to be preceded with an empty line
- Multiple modifications for a `dn` can be defined in a single `modify` block. Each modification needs to close
2021-04-06 17:49:04 +00:00
with a single dash (`-`)
2021-02-05 17:49:29 +00:00
### Active Directory (AD)
For Active Directory, there are a few additional details that are important to remember:
To create a user programmatically in AD, you first `add` a user object and then `modify` that user to provide a
password and enable the account.
- Passwords in AD are set using the `unicodePwd` field. This must be proceeded by two (2) colons (`::`).
2021-11-15 19:52:04 +00:00
- When setting a password programmatically in AD, the following criteria must be met:
2021-04-06 17:49:04 +00:00
2021-02-05 17:49:29 +00:00
- The password must be enclosed in double quotes (`" "`)
- The password must be in [`UTF16LE` format](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/6e803168-f140-4d23-b2d3-c3a8ab5917d2)
- The password must be `base64`-encoded
- Additional details can be found [here](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/set-user-password-with-ldifde)
- Once a user's password has been set, it can be enabled. AD uses the `userAccountControl` field for this purpose:
- To enable the account, set `userAccountControl` to `512`
- You will likely also want to disable AD's password expiration for this dynamic user account. The
2021-04-06 17:49:04 +00:00
`userAccountControl` value for this is: `65536`
2021-02-05 17:49:29 +00:00
- `userAccountControl` flags are cumulative, so to set both of the above two flags, add up the two values
2021-04-06 17:49:04 +00:00
(`512 + 65536 = 66048`): set `userAccountControl` to `66048`
2021-02-05 17:49:29 +00:00
- See [here](https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties#property-flag-descriptions)
2021-04-06 17:49:04 +00:00
for details on `userAccountControl` flags
2021-02-05 17:49:29 +00:00
`sAMAccountName` is a common field when working with AD users. It is used to provide compatibility with legacy
Windows NT systems and has a limit of 20 characters. Keep this in mind when defining your `username_template`.
See [here](https://docs.microsoft.com/en-us/windows/win32/adschema/a-samaccountname) for additional details.
With regard to adding dynamic users to groups, AD doesn't let you directly modify a user's `memberOf` attribute.
The `member` attribute of a group and `memberOf` attribute of a user are
[linked attributes](https://docs.microsoft.com/en-us/windows/win32/ad/linked-attributes). Linked attributes are
forward link/back link pairs, with the forward link able to be modified. In the case of AD group membership, the
group's `member` attribute is the forward link. In order to add a newly-created dynamic user to a group, we also
need to issue a `modify` request to the desired group and update the group membership with the new user.
#### Active Directory LDIF Example
The various `*_ldif` parameters are templates that use the [go template](https://golang.org/pkg/text/template/)
language. A complete LDIF example for creating an Active Directory user account is provided here for reference:
```ldif
dn: CN={{.Username}},OU=HashiVault,DC=adtesting,DC=lab
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
userPrincipalName: {{.Username}}@adtesting.lab
sAMAccountName: {{.Username}}
dn: CN={{.Username}},OU=HashiVault,DC=adtesting,DC=lab
changetype: modify
replace: unicodePwd
unicodePwd::{{ printf "%q" .Password | utf16le | base64 }}
-
replace: userAccountControl
userAccountControl: 66048
-
dn: CN=test-group,OU=HashiVault,DC=adtesting,DC=lab
changetype: modify
add: member
member: CN={{.Username}},OU=HashiVault,DC=adtesting,DC=lab
-
```
2020-08-01 00:25:27 +00:00
## API
2022-10-05 20:16:26 +00:00
The LDAP secrets engine has a full HTTP API. Please see the [LDAP secrets engine API docs](/api-docs/secret/ldap)
2020-08-01 00:25:27 +00:00
for more details.