Database secrets engine with MongoDB
Data protection is a top priority, and database credential rotation is a critical part of any data protection initiative. When hackers attack a system, continuous credential rotation becomes necessary, and you should strive to automate the process.
Vault's database secrets engine generates database credentials dynamically based on user-defined roles. The database administrator can pre-define the time-to-live (TTL) of the database credentials to enforce its validity so that they are automatically revoked when they expire.
Each app instance can get unique credentials that they don't have to share. By making those credentials short-lived, you reduce the chance of compromise. If an attacker compromises an app, the credentials used by the app can be revoked rather than changing more global sets of credentials.
Personas
The end-to-end scenario described in this tutorial involves two personas:
admin
with privileged permissions to configure secrets enginesVault clients
(users, apps, systems, etc.) read the secrets from Vault
Prerequisites
Note
This lab works on macOS using x86_64 based processors. If you are running macOS on an Apple silicon processor, consider using a x86_64 based Linux virtual machine in your preferred cloud provider.
To perform the tasks described in this tutorial, you need to have:
- Docker to run MongDB
- Vault installed
- jq installed
- ngrok installed and configured with an auth token (required for HCP Vault Dedicated)
Lab setup
Start MongoDB
The tutorial requires a MongoDB database. Docker provides a MongoDB server image that you will use in this lab.
Note
This tutorial also works for an existing MongoDB database given appropriate credentials and connection information.
Create a MongoDB database with a root user named
mdbadmin
with the passwordhQ97T9JJKZoqnFn2NXE
.
The database is now available to experiment with the database secrets engine.
Start Vault
Note
If you do not have access to an HCP Vault Dedicated cluster, visit the Create a Vault Cluster on HCP tutorial.
Launch the HCP Portal and login.
Click Vault in the left navigation pane.
In the Vault clusters pane, click vault-cluster.
Under Cluster URLs, click Public Cluster URL.
In a terminal, set the
VAULT_ADDR
environment variable to the copied address.Return to the Overview page and click Generate token.
Vault generates a new token.
Copy the Admin Token.
Return to the terminal and set the
VAULT_TOKEN
environment variable.Set the
VAULT_NAMESPACE
environment variable toadmin
.The
admin
namespace is the top-level namespace automatically created by HCP Vault. All CLI operations default to use the namespace defined in this environment variable.Type
vault status
to verify your connectivity to the Vault cluster.You must establish a tunnel for Vault Dedicated to interact with resources running on your local machine.
In another terminal, start ngrok and connect to postgreSQL.
Example output:
Copy the ngrok forwarding address.
Return to the terminal where you set the
VAULT_ADDR
environment variable and set an environment variable for the ngrok address. Do not includetcp://
.
You are ready to proceed with the tutorial.
Scenario introduction
In this tutorial, you will configure the MongoDB secrets engine and create a "tester" role that has read and write permissions.
- Enable the database secrets engine - admin task
- Configure MongoDB secrets engine - admin task
- Create a role - admin task
- Request MongoDB credentials - Vault clients to perform
This tutorial is running Vault in development mode, and use the root
token.
Be sure to read the Policy requirements section at the
end.
Enable the database secrets engine
(Persona: admin)
The database secrets engine generates database credentials dynamically based on configured roles.
Open a web browser and launch the Vault UI (the address is the same as
VAULT_ADDR
).Enter the token in the Token field and click Sign In (the token is the same as
VAULT_TOKEN
).Select Enable new engine.
Select Databases from the list, and then click Next.
Enter
mongodb
in the Path field.Click Enable Engine to complete.
You enabled the database secrets engine at mongodb/
.
Configure MongoDB secrets engine
(Persona: admin)
The database secrets engine supports popular databases through a
plugin interface. To use a MongoDB database with the secrets engine
requires further configuration with the mongodb-database-plugin
plugin,
and connection information.
Select Create connection in the Connections tab for
mongodb
.Select MongoDB from the Database plugin drop-down list.
Enter
mongo-test
in the Connection Name field.Enter the following in the Connection URL field replacing
<host:port>
with the value from theMONGODB_URL
environment variable.Enter
mdbadmin
in the Username andhQ97T9JJKZoqnFn2NXE
in the Password text fields.Click Create database.
When prompted, click Enable without rotating to continue.
This is an optional step; you should rotate the root user's password in production use. The rest of this tutorial relies on the password you set when staring the MongoDB container, so you should skip this step to complete the tutorial.
Read the Database Root Credential Rotation tutorial to learn about rotating the root credential after the initial configuration of each database.
Select mongodb.
Select the Overview tab. Once you set up a database connection, the overview page displays the current configuration summary.
The Vault generated password has a default pattern which may not adhere to your organization's password requirements. Read the User Configurable Password Generation for Secret Engines tutorial to learn about configuring the Vault-generated database password schema.
Create a role
(Persona: admin)
A role is a logical name within Vault that maps to database credentials. Some applications may just need read permissions, and others may require read and write permissions. Practice the principle of least privilege and create a role appropriately for each database client.
Note
Important: when you define the role in a production deployment, you must create user creation_statements and revocation_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.
In this step, you will create a "tester" role with time-to-live (TTL) set to 1 hour, and the maximum TTL is 24 hours. This allows Vault to revoke the credentials automatically once they reach the TTL.
In the
mongodb
overview page, select Create new.Enter
tester
in the Role name field.Enter
mongo-test
in the Database name field.Select dynamic from the Type of role drop-down list.
Verify Generated credential's Time-to-Live (TTL) and Generated credential's maximum Time-to-Live (Max TTL) is to set the value to 1 hour and 1 day respectively.
Enter the following in the Creation statement field.
The Create Role page should look as below:
Click Create Role to complete.
Vault can now dynamically generate database credentials useful for connecting to
the mongodb
database.
Request MongoDB credentials
(Persona: Vault clients)
To connect to the MongoDB, Vault clients request Vault to dynamically generate the
database credentials based on its role. In this case, the tester
role.
This step uses the root
token for demonstration. In reality, Vault clients
would never use Vault's root
token. After learning the basic steps, continue
onto the Policy requirements section.
Return to the mongo-test configuration page by selecting mongodb > mongo-test.
Select the tester role.
Select Generate credentials.
This presents the generated lease. Click on the copy to clipboard icon to copy the generated username and password.
NOTE: From the mongodb overview page, enter the role name in the Get Credentials field and click Get Credentials to do the same. The Get Credentials works for any role configured on the mongodb.
The MongoDB credentials are a username and a password. Vault identifies the credentials by their lease ID.
Read the customize the generated username schema section for additional discussion.
Validation
Connect to the MongoDB database using the Vault generated credentials.
Example:
You can list databases.
Enter exit
to exit out of the Docker container.
Policy requirements
Each persona requires a different set of capabilities, and you use ACL policies to enforce those capabilities. If you are not familiar with policies, complete the policies tutorial.
Example policy for admin
The admin persona needs to be able to set up the database secrets engine.
- Enable the database secrets engine at
mongodb
(sys/mounts/mongodb
) - Configure the MongoDB connection (
mongodb/config/mongo-test
) - Create a role (
mongodb/roles/tester
)
An admin needs to set up the Vault clients so they can communicate with Vault.
- Create policies for the Vault clients (
sys/policies/acl/<policy_name>
) - Enable an auth method for the Vault clients to login with Vault (
sys/auth/<auth_method>
) - Configure the auth method (
auth/<auth_method>
)
You should be able to complete this tutorial using a token with the above policy attached. If you are not familiar with creating policies, read the Vault Policies tutorial.
Example policy for Vault clients
The Vault clients persona needs to be able to request credentials from Vault.
Create a client policy
Select Policies and then Create ACL policy.
Enter
clients
in the Name field.Copy the policy and paste it into the Policy text box.
Click Create policy.
Log out of the Vault UI and switch to the terminal session you started in the Lab setup section.
Create a token with the
clients
policy attached.Example output:
Copy the generated
token
value. In this example, the token ishvs.ad3DG8zxyPcqq4cvrMzsIxr9
.Return to the Vault UI and enter the generated token to sign in.
Select mongodb/.
Under Get Credentials, enter
tester
in the Role to use field.Click Get Credentials to display the credentials.
Customize the generated username schema
In the request MongoDB credentials section, you
saw the Vault generated username and password. The generated username resembles v-token-tester-6iRIcGv8tLpu816oblPY-1556567086
. This may be less
obvious to differentiate a username from another when you are auditing the
database access.
Update the mongo-test
connection configuration to specify that the generated
database username to have the format of
mongo-<role_name>-<random_char_length_8>
.
In this tutorial, you created a tester
role, so the <role_name>
is
tester
.
Update the
mongo-test
connection configuration with username template.The
username_template
parameter specifies the username format ("mongo-test-{{.RoleName}}-{{random 8}}"
). The{{.RoleName}}
returns the role name (tester
) used to request a lease. The{{random 8}}
returns 8 random characters.Request a new set of credentials.
Example output:
The generated username (
mongo-test-tester-vLjw7VJI
) adheres to the username template.
To customize the password rules, read the User Configurable Password Generation for Secret Engines tutorial.
Next steps
Resources are available to help integrate your applications with a Vault database secrets engine. You can use these resources, and your existing applications will require little to no code changes to work with Vault.
Refer to the following tutorials: