Understand static and dynamic secrets
Vault will store any secret in a secure manner. The secrets may be SSL certificates and keys for your organization's domain, credentials to connect to a corporate database server, etc. Storing such sensitive information in plaintext is not desirable or secure so Vault secure stores and provides retrieval mechanisms.
Unless the someone in the organization manually changes the secret, they are not updated. The kv secrets engine seen in the CLI, HTTP API and UI introductory tutorials is an example of these static secrets. The KV secrets engine is the most commonly used engine for static secrets.
In addition to offering static secrets through the kv secrets engine, Vault can generate dynamic secrets. Dynamic secrets do not exist until read, so the risk of being stolen is greatly reduced. Because Vault has built-in revocation mechanisms, Vault revokes dynamic secrets after use thereby minimizing the amount of time the secret existed.
Scenario
HashiCups has a requirement for development teams to securely connect their web services and applications when accessing a PostgreSQL database. If each team has to manually manage secrets for web services and applications, there are two potential problems. Ether services would share secrets or it will be a challenge managing secrets. Sharing secrets is always a risk, as a compromised secret has access to multiple applications and services. Managing many secrets is a challenge of it's own. Instead, they can use the Vault dynamic secrets to create secrets when accessed and to invalidate the secrets after use.
It is Oliver's job to set up dynamic secrets for the development teams. They will create a database secrets engine, connect it to a PostgreSQL instance, configure it and test Vault's dynamic secret generation.
Prerequisites
To complete this tutorial, you need the following:
- Vault binary installed in your system PATH.
- Docker installed.
- This scenario requires at least 4GB of memory allocated to Docker.
Set up the lab
Open a terminal and start a Vault dev server with the literal string
root
as the root token value, and enable TLS.The dev server listens on the loopback interface at 127.0.0.1 on TCP port 8200 with TLS enabled. At runtime, the dev server also automatically unseals, and prints the unseal key and initial root token values to the standard output.
Root tokens
The dev mode server starts with an initial root token value set.
Root token use should be guarded in production environments because it provides full access to the Vault server.
You can supply the root token value to start Vault in dev mode for convenience and to keep the steps here focused on the learning goals of this tutorial.
In a new terminal, export the
VAULT_ADDR
andVAULT_CACERT
environment variables using the commands suggested in your Vault dev server output.Copy each command (without the
$
) from the server output, and paste it into the new terminal session.Example:
Example:
Remember to use your dev server's values, not the examples shown here.
Export an environment variable for the
vault
CLI to authenticate with the Vault server.The Vault server is ready.
Secrets engine commands
There are some basic commands that are useful to know when dealing with secrets engines.
Vault provides contexual help for the
secret
subcommand.List the secrets engines enabled by default.
To create a new secrets engine use the
enable
command.The particulars of what to do with each secrets engine will vary, and refer to the documentation for that secrets engine.
Disabling a secrets engine is similar.
Dynamic secrets
The database secrets engine supports a variety of databases through a plugin interface. To use a PostgreSQL database with the secrets engine requires further configuration with the postgresql-database-plugin plugin and connection information. Vault will connect to a PostgreSQL database and then use the HTTP API to create dynamic credentials.
In this section create a database secrets engine, configure it and review the
path-help
command.
Start PostgreSQL
(Persona: developer)
The tutorial requires a PostgreSQL database. Docker provides a PostgreSQL server image that satisfies this requirement.
Back in the first terminal, pull a PostgreSQL server image with
docker
.Create a PostgreSQL database with a root user named
root
with the passwordrootpassword
.Verify that the PostgreSQL container is running.
The credentials generated by the Vault role requires a role named
ro
that has the capability to read all tables.Create a role named
ro
.Grant the ability to read all tables to the role named
ro
.The database and the role with the appropriate permissions is available.
Configure Vault
(Persona: operations)
Create a database secrets engine.
Set an environment variable for the PostreSQL address.
Configure the database secrets engine with the connection credentials for the PostgreSQL database.
Example output:
Using the path after the
secret write
, try thepath-help
command.Run a
vault read
command with the config path and compare the settings.
Create a role
In the dynamic secrets section, you configured the PostgreSQL secrets engine with the allowed role named readonly
. A role is a logical name within Vault that maps to database credentials. The SQL statements express the credentials and assigned to the Vault role.
Note
Important: when you define the role in a production deployment, you must create user creation_statements, revocation_statements, renew_statements, and rotation_statements which are valid for the database you've configured. If you do not specify statements appropriate to creating, revoking, or rotating users, Vault inserts generic statements which can be unsuitable for your deployment.
Create an API request payload containing the database role definition.
The SQL statement contains the templatized fields {{name}}, {{password}}, and {{expiration}}. Vault provides these values when creating the credentials. This creates a new PostgreSQL user and then grants that user the permissions defined in the PostgreSQL role named
ro
. When PostgreSQL starts it creates the PostgreSQL role.Create the role named
readonly
that creates credentials with thecreation_statements
defined in the payload.The role generates database credentials with a default TTL of 1 hour and max TTL of 24 hours.
What format do you use when referencing templated files in a Vault configuration?
Wrap the reference in double curly brackets {{ template }}
.
Request PostgreSQL credentials
When a web service or application needs dynamic credentials, it can read them from Vault given the path created above.
The applications that require the database credentials read them from the secret engine's read only role. Read credentials from the
readonly
database role.Take note of this
username
for comparison later.
Validation
To verify that Vault created the user for PostgreSQL, connect to the database and list all database users.
The output displays a table of all the database credentials generated. The Vault generated credentials appear in this list.
Check this user against the user noted earlier.
Clean up
Unset the
VAULT_TOKEN
,VAULT_ADDR
and thePOSTGRES_URL
environment variable.Stop the PostgreSQL container.
Use
CTRL+C
to stop the server process in the terminal window where you started the server, or use this command to kill the server process from any local terminal session:
Summary
Vault can store static secrets such as usernames and passwords, API keys, PKI certificates, and many other types of secrets.
Dynamic secrets allow you to created just-in-time dynamic credentials for popular cloud providers, database platforms, and container orchestration tools. These dynamic credentials are not available until requested, and revoked when it reaches the defined TTL. This greatly reduces the opportunity of exposure for these credentials because they are only valid for a short period of time.