mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-05 04:16:31 +02:00
Add docs for Active Directory secret check-out (#7664)
This commit is contained in:
parent
88271ad838
commit
ef98dd580e
@ -191,6 +191,222 @@ $ curl \
|
||||
"username": "my-application"
|
||||
}
|
||||
```
|
||||
|
||||
## Library management
|
||||
|
||||
The `library` endpoint configures the sets of service accounts that Vault will offer for check-out.
|
||||
|
||||
### Parameters
|
||||
|
||||
* `name` (string: "", required): The name of the set of service accounts.
|
||||
* `service_account_names` (string: "", or list: [] required): The names of all the service accounts that can be
|
||||
checked out from this set. These service accounts must only be used by Vault, and may only be in one set. These
|
||||
service accounts must already exist in Active Directory.
|
||||
* `ttl` (duration: "24h", optional): The maximum amount of time a single check-out lasts before Vault
|
||||
automatically checks it back in. Defaults to 24 hours. Setting it to zero reflects an unlimited lending period.
|
||||
* `max_ttl` (duration: "24h", optional): The maximum amount of time a check-out last with renewal before Vault
|
||||
automatically checks it back in. Defaults to 24 hours. Setting it to zero reflects an unlimited lending period.
|
||||
* `disable_check_in_enforcement` (bool: false, optional): Disable enforcing that service accounts must be
|
||||
checked in by the entity or client token that checked them out. Defaults to false.
|
||||
|
||||
When adding a service account to the library, Vault verifies it already exists in Active Directory.
|
||||
|
||||
| Method | Path |
|
||||
| :------- | :---------------------- |
|
||||
| `LIST` | `/ad/library` |
|
||||
| `POST` | `/ad/library/:set_name` |
|
||||
| `GET` | `/ad/library/:set_name` |
|
||||
| `DELETE` | `/ad/library/:set_name` |
|
||||
|
||||
### Sample Post Request
|
||||
|
||||
```
|
||||
$ curl \
|
||||
--header "X-Vault-Token: ..." \
|
||||
--request POST \
|
||||
--data @payload.json \
|
||||
http://127.0.0.1:8200/v1/ad/library/accounting-team
|
||||
```
|
||||
|
||||
### Sample Post Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"service_account_names": ["fizz@example.com", "buzz@example.com"],
|
||||
"ttl": "10h",
|
||||
"max_ttl": "20h",
|
||||
"disable_check_in_enforcement": false
|
||||
}
|
||||
```
|
||||
|
||||
### Sample Get Response
|
||||
|
||||
```json
|
||||
{
|
||||
"service_account_names": ["fizz@example.com", "buzz@example.com"],
|
||||
"ttl": "10h",
|
||||
"max_ttl": "20h",
|
||||
"disable_check_in_enforcement": false
|
||||
}
|
||||
```
|
||||
|
||||
### Sample List Response
|
||||
|
||||
Performing a `LIST` on the `/ad/library` endpoint will list the names of all the sets of service accounts Vault contains.
|
||||
|
||||
```json
|
||||
[
|
||||
"accounting-team"
|
||||
]
|
||||
```
|
||||
|
||||
## Check-out management
|
||||
|
||||
These endpoints help manage check-outs.
|
||||
|
||||
### Check a credential out
|
||||
|
||||
Returns a `200` if a credential is available, and a `400` if no credential is available.
|
||||
|
||||
* `name` (string: "", required): The name of the set of service accounts.
|
||||
* `ttl` (duration: "", optional): The maximum amount of time a check-out lasts before Vault
|
||||
automatically checks it back in. Setting it to zero reflects an unlimited lending period.
|
||||
Defaults to the set's `ttl`. If the requested `ttl` is higher than the set's, the set's will be used.
|
||||
|
||||
| Method | Path |
|
||||
| :------- | :-------------------------------- |
|
||||
| `POST` | `/ad/library/:set_name/check-out` |
|
||||
|
||||
### Sample Post Request
|
||||
|
||||
```
|
||||
$ curl \
|
||||
--header "X-Vault-Token: ..." \
|
||||
--request POST \
|
||||
--data @payload.json \
|
||||
http://127.0.0.1:8200/v1/ad/library/accounting-team/check-out
|
||||
```
|
||||
|
||||
### Sample Post Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"ttl": "1h"
|
||||
}
|
||||
```
|
||||
|
||||
### Sample Post Response
|
||||
```json
|
||||
{
|
||||
"request_id": "364a17d4-e5ab-998b-ceee-b49929229e0c",
|
||||
"lease_id": "ad/library/accounting-team/check-out/aoBsaBEI4PK96VnukubvYDlZ",
|
||||
"renewable": true,
|
||||
"lease_duration": 36000,
|
||||
"data": {
|
||||
"password": "?@09QW0KZ8DSBu3deIu7XLY1NZqzwhozmMAZ6v0IcZJGOjs5GvpVMvOeW7/duls2",
|
||||
"service_account_name": "fizz@example.com"
|
||||
},
|
||||
"wrap_info": null,
|
||||
"warnings": null,
|
||||
"auth": null
|
||||
}
|
||||
```
|
||||
|
||||
### Check a credential in
|
||||
|
||||
By default, check-in must be called by the same entity or client token used for check-out.
|
||||
To disable this behavior, use the `disable_check_in_enforcement` toggle on the library set. Or, use
|
||||
the `ad/library/manage/:set_name/check-in` behavior to force check-in of the account. Access to the
|
||||
"manage" endpoint should only be granted to highly privileged Vault users, like Vault operators.
|
||||
|
||||
If a caller attempts to check in a service account they're not authorized to check in, they will
|
||||
receive an error response. If they attempt to check in a service account they _are_ authorized to
|
||||
check in, but it's _already_ checked in, they will receive a successful response but the account
|
||||
will not be included in the `check_ins` listed. `check_ins` shows which service accounts were checked
|
||||
in _by this particular call_.
|
||||
|
||||
* `name` (string: "", required): The name of the set of service accounts.
|
||||
* `service_account_names` (string: "", or list: [] optional): The names of all the service accounts to be
|
||||
checked in. May be omitted if only one is checked out.
|
||||
|
||||
| Method | Path |
|
||||
| :------- | :-------------------------------------- |
|
||||
| `POST` | `/ad/library/:set_name/check-in` |
|
||||
| `POST` | `/ad/library/manage/:set_name/check-in` |
|
||||
|
||||
### Sample Post Request
|
||||
|
||||
```
|
||||
$ curl \
|
||||
--header "X-Vault-Token: ..." \
|
||||
--request POST \
|
||||
--data @payload.json \
|
||||
http://127.0.0.1:8200/v1/ad/library/accounting-team/check-in
|
||||
```
|
||||
|
||||
### Sample Post Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"service_account_names": ["fizz@example.com"]
|
||||
}
|
||||
```
|
||||
|
||||
### Sample Post Response
|
||||
```json
|
||||
{
|
||||
"request_id": "db45c714-3f68-b748-95bc-8f7467637a52",
|
||||
"lease_id": "",
|
||||
"renewable": false,
|
||||
"lease_duration": 0,
|
||||
"data": {
|
||||
"check_ins": ["fizz@example.com"]
|
||||
},
|
||||
"wrap_info": null,
|
||||
"warnings": null,
|
||||
"auth": null
|
||||
}
|
||||
```
|
||||
|
||||
### Check the status of service accounts
|
||||
|
||||
| Method | Path |
|
||||
| :------- | :----------------------------- |
|
||||
| `GET` | `/ad/library/:set_name/status` |
|
||||
|
||||
### Sample Get Request
|
||||
|
||||
```
|
||||
$ curl \
|
||||
--header "X-Vault-Token: ..." \
|
||||
--request GET \
|
||||
--data @payload.json \
|
||||
http://127.0.0.1:8200/v1/ad/library/accounting-team/status
|
||||
```
|
||||
|
||||
### Sample Get Response
|
||||
```json
|
||||
{
|
||||
"request_id": "9e44c8b5-d142-5867-2a11-49f3ba71215a",
|
||||
"lease_id": "",
|
||||
"renewable": false,
|
||||
"lease_duration": 0,
|
||||
"data": {
|
||||
"buzz@example.com": {
|
||||
"available": true
|
||||
},
|
||||
"fizz@example.com": {
|
||||
"available": false,
|
||||
"borrower_client_token": "4c653e473bf7e27c6759fccc3def20c44d776279",
|
||||
"borrower_entity_id": "631256b1-8523-9838-5501-d0a1e2cdad9c"
|
||||
}
|
||||
},
|
||||
"wrap_info": null,
|
||||
"warnings": null,
|
||||
"auth": null
|
||||
}
|
||||
```
|
||||
|
||||
## Rotate Root Credentials
|
||||
|
||||
Rotate the `bindpass` to a new one known only to Vault.
|
||||
|
||||
@ -11,18 +11,24 @@ description: |-
|
||||
# Active Directory Secrets Engine
|
||||
|
||||
The Active Directory (AD) secrets engine is a plugin residing [here](https://github.com/hashicorp/vault-plugin-secrets-active-directory).
|
||||
It has two main features.
|
||||
|
||||
The AD secrets engine rotates AD passwords dynamically,
|
||||
and is designed for a high-load environment where many instances may be accessing
|
||||
The first feature (password rotation) is where the AD secrets engine rotates AD passwords dynamically.
|
||||
This is designed for a high-load environment where many instances may be accessing
|
||||
a shared password simultaneously. With a simple set up and a simple creds API,
|
||||
it doesn't require instances to be manually registered in advance to gain access.
|
||||
As long as access has been granted to the creds path via a method like
|
||||
[AppRole](https://www.vaultproject.io/api/auth/approle/index.html), they're available.
|
||||
[AppRole](https://www.vaultproject.io/api/auth/approle/index.html), they're available. Passwords are
|
||||
lazily rotated based on preset TTLs and can have a length configured to meet your needs.
|
||||
|
||||
Passwords are lazily rotated based on preset TTLs and can have a length configured to meet
|
||||
your needs.
|
||||
The second feature (service account check-out) is where a library of service accounts can
|
||||
be checked out by a person or by machines. Vault will automatically rotate the password
|
||||
each time a service account is checked in. Service accounts can be voluntarily checked in, or Vault
|
||||
will check them in when their lending period (or, "ttl", in Vault's language) ends.
|
||||
|
||||
## A Note on Lazy Rotation
|
||||
## Password Rotation
|
||||
|
||||
### A Note on Lazy Rotation
|
||||
|
||||
To drive home the point that passwords are rotated "lazily", consider this scenario:
|
||||
|
||||
@ -41,7 +47,7 @@ Therefore, the AD TTL can be considered a soft contract. It's fulfilled when the
|
||||
To ensure your passwords are rotated as expected, we'd recommend you configure services to request each password at least
|
||||
twice as often as its TTL.
|
||||
|
||||
## A Note on Escaping
|
||||
### A Note on Escaping
|
||||
|
||||
**It is up to the administrator** to provide properly escaped DNs. This
|
||||
includes the user DN, bind DN for search, and so on.
|
||||
@ -62,7 +68,7 @@ For reference, see [RFC 4514](https://www.ietf.org/rfc/rfc4514.txt) and this
|
||||
[TechNet post on characters to escape in Active
|
||||
Directory](http://social.technet.microsoft.com/wiki/contents/articles/5312.active-directory-characters-to-escape.aspx).
|
||||
|
||||
## Quick Setup
|
||||
### Quick Setup
|
||||
|
||||
Most secrets engines must be configured in advance before they can perform their
|
||||
functions. These steps are usually completed by an operator or configuration
|
||||
@ -110,9 +116,9 @@ this role.
|
||||
4. Grant "my-application" access to its creds at `ad/creds/my-application` using an
|
||||
auth method like [AppRole](https://www.vaultproject.io/api/auth/approle/index.html).
|
||||
|
||||
## FAQ
|
||||
### FAQ
|
||||
|
||||
### What if someone directly rotates an Active Directory password that Vault is managing?
|
||||
#### What if someone directly rotates an Active Directory password that Vault is managing?
|
||||
|
||||
If an administrator at your company rotates a password that Vault is managing,
|
||||
the next time an application asks _Vault_ for that password, Vault won't know
|
||||
@ -132,7 +138,7 @@ The password `ttl` on a role can be updated at any time to ensure that the
|
||||
responsibility of updating passwords can be left to Vault, rather than
|
||||
requiring manual administrator updates.
|
||||
|
||||
### Why does Vault return the last password in addition to the current one?
|
||||
#### Why does Vault return the last password in addition to the current one?
|
||||
|
||||
Active Directory promises _eventual consistency_, which means that new
|
||||
passwords may not be propagated to all instances immediately. To deal with
|
||||
@ -140,6 +146,194 @@ this, Vault returns the current password with the last password if it's known.
|
||||
That way, if a new password isn't fully operational, the last password can also
|
||||
be used.
|
||||
|
||||
## Service Account Check-Out
|
||||
|
||||
Vault offers the ability to check service accounts in and out. This is a separate,
|
||||
different set of functionality from the password rotation feature above. Let's walk
|
||||
through how to use it, with explanation at each step.
|
||||
|
||||
First we'll need to enable the AD secrets engine and tell it how to talk to our AD
|
||||
server just as we did above.
|
||||
|
||||
```text
|
||||
$ vault secrets enable ad
|
||||
Success! Enabled the ad secrets engine at: ad/
|
||||
|
||||
$ vault write ad/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.
|
||||
|
||||
```text
|
||||
$ vault write ad/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` have
|
||||
already 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 live
|
||||
if it's renewed. These default to `24h`. Also by default, a service account must be checked in
|
||||
by the same Vault entity or client token that checked 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're
|
||||
available or checked out.
|
||||
|
||||
```text
|
||||
$ vault read ad/library/accounting-team/status
|
||||
Key Value
|
||||
--- -----
|
||||
buzz@example.com map[available:true]
|
||||
fizz@example.com map[available:true]
|
||||
```
|
||||
|
||||
To check out any service account that's available, simply execute:
|
||||
|
||||
```text
|
||||
$ vault write -f ad/library/accounting-team/check-out
|
||||
Key Value
|
||||
--- -----
|
||||
lease_id ad/library/accounting-team/check-out/EpuS8cX7uEsDzOwW9kkKOyGW
|
||||
lease_duration 10h
|
||||
lease_renewable true
|
||||
password ?@09AZKh03hBORZPJcTDgLfntlHqxLy29tcQjPVThzuwWAx/Twx4a2ZcRQRqrZ1w
|
||||
service_account_name fizz@example.com
|
||||
```
|
||||
|
||||
If the default `ttl` for the check-out is higher than needed, set the check-out to last
|
||||
for a shorter time by using:
|
||||
|
||||
```text
|
||||
$ vault write ad/library/accounting-team/check-out ttl=30m
|
||||
Key Value
|
||||
--- -----
|
||||
lease_id ad/library/accounting-team/check-out/gMonJ2jB6kYs6d3Vw37WFDCY
|
||||
lease_duration 30m
|
||||
lease_renewable true
|
||||
password ?@09AZerLLuJfEMbRqP+3yfQYDSq6laP48TCJRBJaJu/kDKLsq9WxL9szVAvL/E1
|
||||
service_account_name buzz@example.com
|
||||
```
|
||||
|
||||
This can be a nice way to say, "Although I _can_ have a check-out for 24 hours, if I
|
||||
haven't checked it in after 30 minutes, I forgot or I'm a dead instance, so you can just
|
||||
check it back in."
|
||||
|
||||
If no service accounts are available for check-out, Vault will return a 400 Bad Request.
|
||||
|
||||
```text
|
||||
$ vault write -f ad/library/accounting-team/check-out
|
||||
Error writing data to ad/library/accounting-team/check-out: Error making API request.
|
||||
|
||||
URL: PUT http://localhost:8200/v1/ad/library/accounting-team/check-out
|
||||
Code: 400. Errors:
|
||||
|
||||
* No service accounts available for check-out.
|
||||
```
|
||||
|
||||
To extend a check-out, renew its lease.
|
||||
|
||||
```text
|
||||
$ vault lease renew ad/library/accounting-team/check-out/0C2wmeaDmsToVFc0zDiX9cMq
|
||||
Key Value
|
||||
--- -----
|
||||
lease_id ad/library/accounting-team/check-out/0C2wmeaDmsToVFc0zDiX9cMq
|
||||
lease_duration 10h
|
||||
lease_renewable true
|
||||
```
|
||||
|
||||
Renewing a check-out means its current password will live longer, since passwords are rotated
|
||||
anytime a password is _checked in_ either by a caller, or by Vault because the check-out `ttl`
|
||||
ends.
|
||||
|
||||
To check a service account back in for others to use, call:
|
||||
|
||||
```text
|
||||
$ vault write -f ad/library/accounting-team/check-in
|
||||
Key Value
|
||||
--- -----
|
||||
check_ins [fizz@example.com]
|
||||
```
|
||||
|
||||
Most of the time this will just work, but if multiple service accounts checked out by the same
|
||||
caller, Vault will need to know which one(s) to check in.
|
||||
|
||||
```text
|
||||
$ vault write ad/library/accounting-team/check-in service_account_names=fizz@example.com
|
||||
Key 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 ID](https://learn.hashicorp.com/vault/identity-access-management/iam-identity)
|
||||
used 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:
|
||||
|
||||
```text
|
||||
$ vault write -f ad/library/manage/accounting-team/check-in
|
||||
Key Value
|
||||
--- -----
|
||||
check_ins [fizz@example.com]
|
||||
```
|
||||
|
||||
Or, alternatively, revoking the secret's lease has the same effect.
|
||||
|
||||
```text
|
||||
$ vault lease revoke ad/library/accounting-team/check-out/PvBVG0m7pEg2940Cb3Jw3KpJ
|
||||
All revocation operations queued successfully!
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Old passwords are still valid for a period of time.
|
||||
|
||||
During testing, we found that by default, many versions of Active Directory
|
||||
perpetuate old passwords for a short while. After we discovered this behavior,
|
||||
we found articles discussing it by searching for "AD password caching" and "OldPasswordAllowedPeriod". We
|
||||
also found [an article from Microsoft](https://support.microsoft.com/en-us/help/906305/new-setting-modifies-ntlm-network-authentication-behavior)
|
||||
discussing how to configure this behavior. This behavior appears to vary by AD
|
||||
version. We recommend you test the behavior of your particular AD server,
|
||||
and edit its settings to gain the desired behavior.
|
||||
|
||||
#### I get a lot of 400 Bad Request's when trying to check out service accounts.
|
||||
|
||||
This will occur when there aren't enough service accounts for those requesting them. Let's
|
||||
suppose our "accounting-team" service accounts are the ones being requested. When Vault
|
||||
receives a check-out call but none are available, Vault will log at debug level:
|
||||
"'accounting-team' had no check-outs available". Vault will also increment a metric
|
||||
containing the strings "active directory", "check-out", "unavailable", and "accounting-team".
|
||||
|
||||
Once it's known _which_ library needs more service accounts for checkout, fix this issue
|
||||
by merely creating a new service account for it to use in Active Directory, then adding it to
|
||||
Vault like so:
|
||||
|
||||
```text
|
||||
$ vault write ad/library/accounting-team \
|
||||
service_account_names=fizz@example.com,buzz@example.com,new@example.com
|
||||
```
|
||||
|
||||
In this example, fizz and buzz were pre-existing but were still included in the call
|
||||
because we'd like them to exist in the resulting set. The new account was appended to
|
||||
the end.
|
||||
|
||||
#### Sometimes Vault gives me a password but then AD says it's not valid.
|
||||
|
||||
Active Directory is eventually consistent, meaning that it can take some time for word
|
||||
of a new password to travel across all AD instances in a cluster. In larger clusters, we
|
||||
have observed the password taking over 10 seconds to propagate fully. The simplest way to
|
||||
handle this is to simply wait and retry using the new password.
|
||||
|
||||
## API
|
||||
|
||||
The Active Directory secrets engine has a full HTTP API. Please see the
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user