LDAP - Secrets Engine | Vault | HashiCorp Developer (2024)

Note: This engine can use external X.509 certificates as part of TLS or signature validation.Verifying signatures against X.509 certificates that use SHA-1 is deprecated and is no longerusable without a workaround starting in Vault 1.12. See thedeprecation FAQfor more information.

The LDAP secrets engine provides management of LDAP credentials as well as dynamiccreation of credentials. It supports integration with implementations of the LDAPv3 protocol, including OpenLDAP, Active Directory, and IBM Resource Access ControlFacility (RACF).

The secrets engine has three primary features:

  • Static Credentials
  • Dynamic Credentials
  • Service Account Check-Out
  1. Enable the LDAP secret engine:

    $ vault secrets enable ldap

    By default, the secrets engine will mount at the name of the engine. Toenable the secrets engine at a different path, use the -path argument.

  2. Configure the credentials that Vault uses to communicate with LDAPto generate passwords:

    $ vault write ldap/config \ binddn=$USERNAME \ bindpass=$PASSWORD \ url=ldaps://138.91.247.105

    Note: it's recommended a dedicated entry management account be created specifically for Vault.

  3. Rotate the root password so only Vault knows the credentials:

    $ vault write -f ldap/rotate-root

    Note: it's not possible to retrieve the generated password once rotated by Vault.It's recommended a dedicated entry management account be created specifically for Vault.

Schemas

The LDAP Secret Engine supports three different schemas:

  • openldap (default)
  • racf
  • ad

OpenLDAP

By default, the LDAP Secret Engine assumes the entry password is stored in userPassword.There are many object classes that provide userPassword including for example:

  • organization
  • organizationalUnit
  • organizationalRole
  • inetOrgPerson
  • person
  • posixAccount

Resource access control facility (RACF)

For managing IBM's Resource Access Control Facility (RACF) security system, the secretengine must be configured to use the schema racf.

Generated passwords must be 8 characters or less to support RACF. The length of thepassword can be configured using a password policy:

$ vault write ldap/config \ binddn=$USERNAME \ bindpass=$PASSWORD \ url=ldaps://138.91.247.105 \ schema=racf \ password_policy=racf_password_policy

Active directory (AD)

For managing Active Directory instances, the secret engine must be configured to use theschema ad.

$ vault write ldap/config \ binddn=$USERNAME \ bindpass=$PASSWORD \ url=ldaps://138.91.247.105 \ schema=ad

Static credentials

Setup

  1. Configure a static role that maps a name in Vault to an entry in LDAP.Password rotation settings will be managed by this role.

    $ vault write ldap/static-role/hashicorp \ dn='uid=hashicorp,ou=users,dc=hashicorp,dc=com' \ username='hashicorp' \ rotation_period="24h"
  2. Request credentials for the "hashicorp" role:

    $ vault read ldap/static-cred/hashicorp

Password rotation

Passwords can be managed in two ways:

  • automatic time based rotation
  • manual rotation

Auto password rotation

Passwords will automatically be rotated based on the rotation_period configuredin the static role (minimum of 5 seconds). When requesting credentials for a staticrole, the response will include the time before the next rotation (ttl).

Auto-rotation is currently only supported for static roles. The binddn account usedby Vault should be rotated using the rotate-root endpoint to generate a passwordonly Vault will know.

Manual rotation

Static roles can be manually rotated using the rotate-role endpoint. When manuallyrotated the rotation period will start over.

Deleting static roles

Passwords are not rotated upon deletion of a static role. The password should be manuallyrotated prior to deleting the role or revoking access to the static role.

Setup

Dynamic credentials can be configured by calling the /role/:role_name endpoint:

$ vault write ldap/role/dynamic-role \ 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 beexecuted if the creation fails for any reason. This ensures any entities are removed in the event of a failure.

To generate credentials:

$ vault read ldap/creds/dynamic-roleKey Value--- -----lease_id ldap/creds/dynamic-role/HFgd6uKaDomVMvJpYbn9q4q5lease_duration 1hlease_renewable truedistinguished_names [cn=v_token_dynamic-role_FfH2i1c4dO_1611952635,ou=users,dc=learn,dc=example]password xWMjkIFMerYttEbzfnBVZvhRQGmhpAA0yeTya8fdmDB3LXDzGrjNEPV2bCPE9CW6username v_token_testrole_FfH2i1c4dO_1611952635

The distinguished_names field is an array of DNs that are created from the creation_ldif statements. If more thanone LDIF entry is included, the DN from each statement will be included in this field. Each entry in this fieldcorresponds 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 theLDIF string. The string will be parsed and validated to ensure that it adheres to LDIF syntax. A good referencefor proper LDIF syntax can be found here.

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 closewith a single dash (-)

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 apassword and enable the account.

  • Passwords in AD are set using the unicodePwd field. This must be proceeded by two (2) colons (::).

  • When setting a password programmatically in AD, the following criteria must be met:

    • The password must be enclosed in double quotes (" ")
    • The password must be in UTF16LE format
    • The password must be base64-encoded
    • Additional details can be found here
  • 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. TheuserAccountControl value for this is: 65536
    • userAccountControl flags are cumulative, so to set both of the above two flags, add up the two values(512 + 65536 = 66048): set userAccountControl to 66048
    • See herefor details on userAccountControl flags

sAMAccountName is a common field when working with AD users. It is used to provide compatibility with legacyWindows NT systems and has a limit of 20 characters. Keep this in mind when defining your username_template.See here for additional details.

Since the default username_template is longer than 20 characters which follows the template of v_{{.DisplayName}}_{{.RoleName}}_{{random 10}}_{{unix_time}}, we recommend customising the username_template on the role configuration to generate accounts with names less than 20 characters. Please refer to the username templating document for more information.

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 arelinked attributes. Linked attributes areforward link/back link pairs, with the forward link able to be modified. In the case of AD group membership, thegroup's member attribute is the forward link. In order to add a newly-created dynamic user to a group, we alsoneed 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 templatelanguage. A complete LDIF example for creating an Active Directory user account is provided here for reference:

dn: CN={{.Username}},OU=HashiVault,DC=adtesting,DC=labchangetype: addobjectClass: topobjectClass: personobjectClass: organizationalPersonobjectClass: useruserPrincipalName: {{.Username}}@adtesting.labsAMAccountName: {{.Username}}dn: CN={{.Username}},OU=HashiVault,DC=adtesting,DC=labchangetype: modifyreplace: unicodePwdunicodePwd::{{ printf "%q" .Password | utf16le | base64 }}-replace: userAccountControluserAccountControl: 66048-dn: CN=test-group,OU=HashiVault,DC=adtesting,DC=labchangetype: modifyadd: membermember: CN={{.Username}},OU=HashiVault,DC=adtesting,DC=lab-

Service account Check-Out

Service account check-out provides a library of service accounts that can be checked outby a person or by machines. Vault will automatically rotate the password each time aservice account is checked in. Service accounts can be voluntarily checked in, or Vaultwill check them in when their lending period (or, "ttl", in Vault's language) ends.

The service account check-out functionality works with various schemas,including OpenLDAP, Active Directory, and RACF. In the following usage example, the secretsengine is configured to manage a library of service accounts in an Active Directory instance.

First we'll need to enable the LDAP secrets engine and tell it how to securely connectto an AD server.

$ vault secrets enable ldapSuccess! Enabled the ad secrets engine at: ldap/$ vault write ldap/config \ binddn=$USERNAME \ bindpass=$PASSWORD \ url=ldaps://138.91.247.105 \ userdn='dc=example,dc=com'

Our next step is to designate a set of service accounts for check-out.

$ vault write ldap/library/accounting-team \ service_account_names=fizz@example.com,buzz@example.com \ ttl=10h \ max_ttl=20h \ disable_check_in_enforcement=false

In this example, the service account names of fizz@example.com and buzz@example.com havealready been created on the remote AD server. They've been set aside solely for Vault to handle.The ttl is how long each check-out will last before Vault checks in a service account,rotating its password during check-in. The max_ttl is the maximum amount of time it can liveif it's renewed. These default to 24h, and both use duration format strings.Also by default, a service account must be checked in by the same Vault entity or client token thatchecked it out. However, if this behavior causes problems, set disable_check_in_enforcement=true.

When a library of service accounts has been created, view their status at any time to see if they'reavailable or checked out.

$ vault read ldap/library/accounting-team/statusKey Value--- -----buzz@example.com map[available:true]fizz@example.com map[available:true]

To check out any service account that's available, simply execute:

$ vault write -f ldap/library/accounting-team/check-outKey Value--- -----lease_id ldap/library/accounting-team/check-out/EpuS8cX7uEsDzOwW9kkKOyGWlease_duration 10hlease_renewable truepassword ?@09AZKh03hBORZPJcTDgLfntlHqxLy29tcQjPVThzuwWAx/Twx4a2ZcRQRqrZ1wservice_account_name fizz@example.com

If the default ttl for the check-out is higher than needed, set the check-out to lastfor a shorter time by using:

$ vault write ldap/library/accounting-team/check-out ttl=30mKey Value--- -----lease_id ldap/library/accounting-team/check-out/gMonJ2jB6kYs6d3Vw37WFDCYlease_duration 30mlease_renewable truepassword ?@09AZerLLuJfEMbRqP+3yfQYDSq6laP48TCJRBJaJu/kDKLsq9WxL9szVAvL/E1service_account_name buzz@example.com

This can be a nice way to say, "Although I can have a check-out for 24 hours, if Ihaven't checked it in after 30 minutes, I forgot or I'm a dead instance, so you can justcheck it back in."

If no service accounts are available for check-out, Vault will return a 400 Bad Request.

$ vault write -f ldap/library/accounting-team/check-outError writing data to ldap/library/accounting-team/check-out: Error making API request.URL: POST http://localhost:8200/v1/ldap/library/accounting-team/check-outCode: 400. Errors:* No service accounts available for check-out.

To extend a check-out, renew its lease.

$ vault lease renew ldap/library/accounting-team/check-out/0C2wmeaDmsToVFc0zDiX9cMqKey Value--- -----lease_id ldap/library/accounting-team/check-out/0C2wmeaDmsToVFc0zDiX9cMqlease_duration 10hlease_renewable true

Renewing a check-out means its current password will live longer, since passwords are rotatedanytime a password is checked in either by a caller, or by Vault because the check-out ttlends.

To check a service account back in for others to use, call:

$ vault write -f ldap/library/accounting-team/check-inKey Value--- -----check_ins [fizz@example.com]

Most of the time this will just work, but if multiple service accounts are checked out by the samecaller, Vault will need to know which one(s) to check in.

$ vault write ldap/library/accounting-team/check-in service_account_names=fizz@example.comKey Value--- -----check_ins [fizz@example.com]

To perform a check-in, Vault verifies that the caller should be able to check in a given service account.To do this, Vault looks for either the same entity IDused to check out the service account, or the same client token.

If a caller is unable to check in a service account, or simply doesn't try,Vault will check it back in automatically when the ttl expires. However, if that is too long,service accounts can be forcibly checked in by a highly privileged user through:

$ vault write -f ldap/library/manage/accounting-team/check-inKey Value--- -----check_ins [fizz@example.com]

Or, alternatively, revoking the secret's lease has the same effect.

$ vault lease revoke ldap/library/accounting-team/check-out/PvBVG0m7pEg2940Cb3Jw3KpJAll revocation operations queued successfully!

This engine previously allowed configuration of the length of the password that is generatedwhen rotating credentials. This mechanism was deprecated in Vault 1.5 in favor ofpassword policies. This means the length field shouldno longer be used. The following password policy can be used to mirror the same behaviorthat the length field provides:

length=<length>rule "charset" { charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"}

LDAP password policy

The LDAP secret engine does not hash or encrypt passwords prior to modifyingvalues in LDAP. This behavior can cause plaintext passwords to be stored in LDAP.

To avoid having plaintext passwords stored, the LDAP server should be configuredwith an LDAP password policy (ppolicy, not to be confused with a Vault passwordpolicy). A ppolicy can enforce rules such as hashing plaintext passwords by default.

The following is an example of an LDAP password policy to enforce hashing on thedata information tree (DIT) dc=hashicorp,dc=com:

dn: cn=module{0},cn=configchangetype: modifyadd: olcModuleLoadolcModuleLoad: ppolicydn: olcOverlay={2}ppolicy,olcDatabase={1}mdb,cn=configchangetype: addobjectClass: olcPPolicyConfigobjectClass: olcOverlayConfigolcOverlay: {2}ppolicyolcPPolicyDefault: cn=default,ou=pwpolicies,dc=hashicorp,dc=comolcPPolicyForwardUpdates: FALSEolcPPolicyHashCleartext: TRUEolcPPolicyUseLockout: TRUE

Refer to the LDAP Secrets Enginetutorial to learn how to configure and use the LDAP secrets engine.

API

The LDAP secrets engine has a full HTTP API. Please see the LDAP secrets engine API docsfor more details.

LDAP - Secrets Engine | Vault | HashiCorp Developer (2024)

References

Top Articles
Latest Posts
Article information

Author: Jonah Leffler

Last Updated:

Views: 6519

Rating: 4.4 / 5 (45 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Jonah Leffler

Birthday: 1997-10-27

Address: 8987 Kieth Ports, Luettgenland, CT 54657-9808

Phone: +2611128251586

Job: Mining Supervisor

Hobby: Worldbuilding, Electronics, Amateur radio, Skiing, Cycling, Jogging, Taxidermy

Introduction: My name is Jonah Leffler, I am a determined, faithful, outstanding, inexpensive, cheerful, determined, smiling person who loves writing and wants to share my knowledge and understanding with you.