»Challenge
Vault's secret engines generate passwords that adhere to a default pattern that may not meet the standards required by your applications or within your organization. You may require passwords with:
- lengths that are smaller or exceed the default length.
- differing charsets
- frequency of characters
- positional requirements for characters
- disallowed repetition
- disallowed words from a dictionary
»Solution
Vault 1.5 introduced support for configurable password generation defined by a password policy. A policy defines the rules and requirements that the password must adhere and can provide that password directly through a new endpoint or within secrets engines.
Secrets engines with support for password policies:
- Active Directory
- Azure
- OpenLDAP
- RabbitMQ
- [All Databases]
»Prerequisites
Vault version 1.5 or later; refer to the Getting Started tutorial to install Vault.
RabbitMQ environment or Docker.
Online tutorial: An interactive tutorial is also available if you do not wish to use AWS. Click the Show Terminal button to start.
»Start Vault
A Vault server is able to generate passwords that meet the requirements of a configurable password policy. These password policies may also be applied to supported secrets engines.
In another terminal, start a Vault dev server with root
as the root token.
$ vault server -dev -dev-root-token-id root
Insecure operation: Do not run a Vault dev server in production. This approach is only used here to simplify the unsealing process for this demonstration.
Export an environment variable for the vault
CLI to address the Vault server.
$ export VAULT_ADDR=http://0.0.0.0:8200
Login with the root token.
$ vault login root
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 root
token_accessor n9CYvD0GK3iV6nwAOZQAy9Md
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]
The Vault server is ready to explore password policies.
»Start RabbitMQ
RabbitMQ is a message-broker that has a secrets engine that enables Vault to generate user credentials.
In another terminal, start a RabbitMQ server running on port 15672
that
has a user named learn_vault
with the password hashicorp
.
$ docker run --rm --name some-rabbit -p 15672:15672 \
-e RABBITMQ_DEFAULT_USER=learn_vault \
-e RABBITMQ_DEFAULT_PASS=hashicorp \
rabbitmq:3-management
Docker downloads the necessary images and launches a RabbitMQ database container. RabbitMQ is ready for Vault to generate credentials.
»Setup RabbitMQ secrets engine with the default password policy
The RabbitMQ secrets engine generates passwords that adhere to a default password policy.
Enable the RabbitMQ secrets engine at the rabbitmq-default-policy
path.
$ vault secrets enable -path rabbitmq-default-policy rabbitmq
Success! Enabled the rabbitmq secrets engine at: rabbitmq-default-policy/
The secrets engine requires configuration so it can communicate with the RabbitMQ server.
Configure the secrets engine to connect to the RabbitMQ server.
$ vault write rabbitmq-default-policy/config/connection \
connection_uri=http://localhost:15672 \
username="learn_vault" \
password="hashicorp"
Success! Data written to: rabbitmq-default-policy/config/connection
The secrets engine is configured to talk to the RabbitMQ server running locally
over the HTTP management
interface,
http://localhost:15672
. The user, learn_vault
, with its password
hashicorp
, is an administrator that was generated when RabbitMQ
started.
Create a role named example
.
$ vault write rabbitmq-default-policy/roles/example \
vhosts='{"/":{"read": ".*", "write": ".*"}}'
Success! Data written to: rabbitmq-default-policy/roles/example
The example
role defines an endpoint for dynamic credential generation. The
credentials generated are granted read and write every entity.
Generate credentials from the example
role.
$ vault read rabbitmq-default-policy/creds/example
Key Value
--- -----
lease_id rabbitmq-default-policy/creds/example/4yCYMMCZ4I4mKBlPsbNNsKdj
lease_duration 768h
lease_renewable true
password v0E6LjTeabrtEAz72cbYINNodWSApPS61vGP
username root-2b3482f7-b522-9997-ab0c-1f3057a396d3
The credentials display the username
and password
generated. The password
generated, v0E6LjTeabrtEAz72cbYINNodWSApPS61vGP
, adheres to the default
password policy for the secrets engine.
»Define a password policy
Create a policy file named example_policy.hcl
.
$ tee example_policy.hcl <<EOF
length=20
rule "charset" {
charset = "abcdefghijklmnopqrstuvwxyz"
min-chars = 1
}
rule "charset" {
charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
min-chars = 1
}
rule "charset" {
charset = "0123456789"
min-chars = 1
}
rule "charset" {
charset = "!@#$%^&*"
min-chars = 1
}
EOF
The policy is written in HashiCorp Configuration Language (HCL). The length
field sets the length of the password returned to 20
characters. Each rule
stanza defines a character set and the minimum number of occurrences those
characters need to appear in the generated password. These rules are cumulative
so each one adds more requirements on the password generated.
Create a Vault password policy named example
with the password policy
rules defined in example_policy.hcl
.
$ vault write sys/policies/password/example policy=@example_policy.hcl
Success! Data written to sys/polices/password/example_policy
This policy can now be accessed directly to generate a password or referenced
by its name example
when configuring supported secrets engines.
Generate a password from the example
password policy.
$ vault read sys/policies/password/example/generate
Key Value
--- -----
password #v!RQDHxHunJ1TUmCyys
The password generated adheres to the requirements:
- length of 20 characters
- at least 1 uppercase character
- at least 1 lowercase character
- at least 1 number
- at least 1 symbol
»Setup RabbitMQ secrets engine with a password policy
The RabbitMQ secrets engine may be configured to adopt a password policy.
Enable the RabbitMQ secrets engine at the rabbitmq-with-policy
path.
$ vault secrets enable -path rabbitmq-with-policy rabbitmq
Success! Enabled the rabbitmq secrets engine at: rabbitmq-with-policy/
The secrets engine requires configuration so it can communicate with the RabbitMQ server.
Configure the secrets engine to connect to the RabbitMQ server and use the
example
password policy.
$ vault write rabbitmq-with-policy/config/connection \
connection_uri=http://localhost:15672 \
username="learn_vault" \
password="hashicorp" \
password_policy="example"
Success! Data written to: rabbitmq-with-policy/config/connection
The same connection information is used to establish the connection with the
RabbitMQ server. The difference is that the password_policy
has been set to
the example
policy defined in Define a password
policy section.
Create a role named example
.
$ vault write rabbitmq-with-policy/roles/example \
vhosts='{"/":{"read": ".*", "write": ".*"}}'
Success! Data written to: rabbitmq-with-policy/roles/example
The example
role defines an endpoint for dynamic credential generation. The
credentials generated are granted read and write on every entity.
Generate a login from the example
role.
$ vault read rabbitmq-with-policy/creds/example
Key Value
--- -----
lease_id rabbitmq-with-policy/creds/example/vfoht23KclCzOuKzlRYeMZZS
lease_duration 768h
lease_renewable true
password HtjHFtdy21*iBpNZjLNb
username root-4efd295b-1a4e-285c-14c8-06b135c5464a
The credentials display the username
and password
generated. The password
generated, HtjHFtdy21*iBpNZjLNb
, adheres to the example password
policy defined in the secrets engine's configuration.
»Next steps
You configured a RabbitMQ secrets engine that generated credentials with the default password policy. Learn more about the RabbitMQ secrets engine by reading the documentation and the API documentation.
Then you defined a password policy and generated a password. Learn more about by reading the documentation and the API documentation.
Finally, you configured another RabbitMQ secrets engine that generated credentials that used a custom password policy.