Database secrets engine for Microsoft SQL Server
Vault can generate secrets on-demand for some systems. For example, when an app needs to access an database server, it asks Vault for credentials. Vault will generate credential granting permissions to access the database server. In addition, Vault will automatically revoke this credential after the time-to-live (TTL) expires.
Challenge
Data protection is a top priority, and database credential rotation is a critical part of any data protection initiative. Each role has a different set of permissions granted to access the database. Automated and continuous credential rotation becomes a necessary element of incident response.
Solution
Applications ask Vault for database credentials rather than setting them as environment variables. The administrator specifies the TTL of the database credentials to enforce its validity so that they are automatically revoked when they are no longer used.
Each app instance can get unique credentials that they don't have to share. By making those credentials short-lived, you reduce the chance that they become compromised. If an attacker compromises an app, you can revoke the app credentials 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 engines
apps
read the secrets from Vault
Prerequisites
This lab was tested on macOS using an x86_64 based processor. If you are running macOS on an Apple silicon-based processor, use a x86_64 based Linux virtual machine in your preferred cloud provider.
To perform the tasks described in this tutorial, you need to have:
- HCP or Vault Community Edition environment
- jq installed
- Docker installed
- ngrok installed and configured with an auth token (HCP Vault Dedicated only)
Scenario Introduction
In this tutorial, you are going to configure the database secrets engine to support
Microsoft SQL Server, and add users to the myapp
database. The Vault-generated MSSQL
credentials in this tutorial use the built in db_datareader
role to have read-only access to the database.
Lab setup
Start MSSQL
Start MSSQL using Docker.
Export an environment variable for the MSSQL SA user.
Export an environment variable for the password created for the SA user.
Note
Use environment variables to streamline Vault configuration during the tutorial.
Write some example SQL that creates a database called
myapp
and inserts sample data.Use
sqlcmd
to run the script to create the database and insert sample data.Example output:
Verify you can read the data from the
location
table.
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 within moments.
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.For Vault Dedicated to interact with resources running on your local machine, you must first establish a tunnel.
In another terminal, start ngrok and connect to MSSQL.
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://
.
The HCP Vault server is ready, you may proceed with the lab.
Configure the database secrets engine
(Persona: admin)
The database secrets engine generates database credentials dynamically based on configured roles.
Enable the database secrets engine at the
database/
path.You've enabled the database secrets engine.
Configure the database secrets engine with the connection credentials for the MSSQL database.
You've configured the secrets engine to work with MSSQL.
Note
Read the Database Root Credential Rotation tutorial to learn about rotating the root credential after the initial configuration of each database.
Define the SQL used to create credentials for the
myapp
database.The SQL has templatized fields
{{name}}
, and{{password}}
. Vault fills in these values when you read the credentials.Note
Important: when you define the role in a production deployment, you must create user creation_statements, revocation_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.
Also note that Amazon RDS does not support using the
sysadmin
role, which Vault uses by default for MSSQL revocation process. If you are using MSSQL on AWS RDS, you must use a custom revocation statement.Refer to the Database Secrets Engine for Microsoft SQL documentation for more information.
Create the role named
readonly
that creates credentials with thereadonly.sql
script.
Vault is now configured to support generating dynamic credentials for Microsoft SQL Server.
Test MSSQL access
(Persona: apps)
Mimic the steps typically performed by an application to generate dynamic credentials
and read data from the myapp
database.
Read credentials from the
readonly
database role.Vault generates a unique username and password to access MSSQL.
Read credentials from the
readonly
database role and save them to an environment variable.Connect to the MSSQL database and list the sample data using the credentials stored in the
TEMP_CREDS
environment variable.The output displays the sample data from the
myapp
database.Attempt to insert data into the table.
The insert permission was denied because the temporary credentials were only assigned a role with read permissions.
Manage leases
(Persona: admin)
The credentials are managed by the lease ID and remain valid for the lease duration (TTL) or until revoked. Once revoked the credentials are no longer valid.
List the existing leases.
All valid leases for database credentials are displayed.
Create a variable that stores the first lease ID.
Renew the lease for the database credential by passing its lease ID.
The TTL of the renewed lease is set to
1h
.Revoke the lease without waiting for its expiration.
List the remaining leases.
The lease is no longer valid and is not displayed.
Revoke all remaining leases associated with the path
database/creds/readonly
.The
prefix
flag matches all valid leases with the path prefix ofdatabase/creds/readonly
.List the existing leases.
All the leases with this path as a prefix have been revoked.
Implement a password policy
(Persona: admin)
Note
Refer to the password policy tutorial for more details.
Define a password policy
The database secrets engines generate passwords that adhere to a default pattern that may be overridden with a new password policy. A policy defines the rules and requirements that the password must adhere to and can provide that password directly through a new endpoint or within secrets engines.
The passwords you want to generate adhere to these requirements.
- length of 20 characters
- at least 1 uppercase character
- at least 1 lowercase character
- at least 1 number
- at least 1 symbol
Define a password policy in a file named
password-policy.hcl
.1 2 3 4 5 6 7 8 9 1011121314151617181920212223
The policy is written in HashiCorp Configuration Language (HCL).
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.
Line 2: The
length
field sets the length of the password returned to20
characters.Lines 4-7: The
charset
rule includes uppercase characters with a minimum of 1 character.Lines 9-12: The
charset
rule includes lowercase characters with a minimum of 1 character.Lines 14-17: The
charset
rule includes numbers with a minimum of 1 character.Lines 19-22: The
charset
rule includes special characters with a minimum of 1 character.Create a Vault password policy named
mssql
with the password policy rules defined inpassword-policy.hcl
.This policy can now be accessed directly to generate a password or referenced by its name
mssql
when configuring supported secrets engines.Generate a password from the
mssql
password policy.The password generated adheres to the defined requirements.
Add a password policy to the database configuration
Now that the password policy has been created, you can assign the policy to the database secrets engine configuration.
Configure the database secrets engine with the
mssql
password policy.Read credentials from the
readonly
database role with themssql
policy attached.The credentials display the
username
andpassword
generated. Thepassword
generated adheres to the mssql password policy defined in the secrets engine's configuration.
Define a username template
(Persona: apps)
The database secrets engine generates usernames that adhere to a default pattern. A customized username template may be provided to meet the needs of your organization.
Note
Ensure that custom username templates include enough randomness to prevent the same username being generated multiple times.
Read credentials from the
readonly
database role.The generated username,
v-token-readonly-wGLPkpDyc6AgqBfMZTD3-1604195404
, uses the default pattern expressed as a Go template,{{ printf "v-%s-%s-%s-%s" (.DisplayName | truncate 8) (.RoleName | truncate 8) (random 20) (unix_time) | truncate 63 }}
.Refer to the Username Templating documentation to learn more functions that can be applied.
Configure the database secrets engine with the username template.
This username template is prefixed with
myorg-
, uses the name of role,readonly
, the unix timestamp in seconds, and a random sequence of 8 characters.Read credentials from the
readonly
database role.The username generated adheres to the template provided to the configuration.
Next Steps
There are some tools available to help integrate your applications with Vault's database secrets engine. Using those tools, the existing applications may require minimum to no code change to work with Vault.
Refer to the Vault Agent caching tutorial.