HashiCorp Vault — Database Secrets Engine

2 minute read

The database secrets engine generates unique, short-lived database credentials on demand. Vault creates a real database user, gives it to the client, and automatically drops it when the lease expires.


Architecture

┌──────────┐    ① Request creds    ┌──────────┐    ② CREATE USER    ┌──────────┐
│  App     │──────────────────────▶│  Vault   │───────────────────▶│ Database │
│          │    ④ user/password    │          │    ③ user created   │          │
│          │◀──────────────────────│          │◀───────────────────│          │
│          │                       │          │                     │          │
│          │    ⑤ Connect to DB   │          │                     │          │
│          │──────────────────────│──────────│───────────────────▶│          │
│          │                       │          │                     │          │
│          │                       │ ⑥ Lease  │    ⑦ DROP USER     │          │
│          │                       │  expires │───────────────────▶│          │
└──────────┘                       └──────────┘                     └──────────┘

Setup Overview

Three steps to configure dynamic database credentials:

Step What Command Prefix
1 Enable the database engine vault secrets enable database
2 Configure database connection vault write database/config/...
3 Create roles (credential templates) vault write database/roles/...

Step 1 — Enable the Engine

vault secrets enable database

Step 2 — Configure Connection

Vault needs a privileged connection to the database to create/revoke users:

# PostgreSQL
vault write database/config/my-postgres \
    plugin_name="postgresql-database-plugin" \
    allowed_roles="app-readonly,app-readwrite" \
    connection_url="postgresql://:@db.example.com:5432/mydb?sslmode=require" \
    username="vault_admin" \
    password="vault_admin_password"

⚠️ The vault_admin user must have CREATEROLE or equivalent privilege to create new database users.

Rotate the Root Password

After configuration, rotate the root password so only Vault knows it:

vault write -f database/rotate-root/my-postgres

Now the original vault_admin_password is no longer valid — only Vault can access the database with admin privileges.


Step 3 — Create Roles

Roles define what credentials look like:

# Read-only role
vault write database/roles/app-readonly \
    db_name="my-postgres" \
    creation_statements="CREATE ROLE \"\" WITH LOGIN PASSWORD '' VALID UNTIL ''; \
        GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"\";" \
    revocation_statements="REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM \"\"; \
        DROP ROLE IF EXISTS \"\";" \
    default_ttl="1h" \
    max_ttl="24h"

Understanding Creation Statements

Placeholder Value
{{name}} Vault-generated unique username (e.g., v-approle-app-readonly-abc123)
{{password}} Vault-generated random password
{{expiration}} Timestamp when the lease expires

Generate Credentials

vault read database/creds/app-readonly

Expected output:

Key                Value
---                -----
lease_id           database/creds/app-readonly/abc123
lease_duration     1h
lease_renewable    true
password           A1a-random-generated-pwd
username           v-token-app-readonly-abc123-1234567890

Each call generates a new, unique credential pair.


Supported Databases

Database Plugin Name
PostgreSQL postgresql-database-plugin
MySQL/MariaDB mysql-database-plugin
MongoDB mongodb-database-plugin
MSSQL mssql-database-plugin
Oracle oracle-database-plugin
Redis redis-database-plugin
Elasticsearch elasticsearch-database-plugin
Cassandra cassandra-database-plugin
InfluxDB influxdb-database-plugin
Snowflake snowflake-database-plugin

Static Roles (Password Rotation)

For applications that need a fixed username but want automatic password rotation:

vault write database/static-roles/my-static-role \
    db_name="my-postgres" \
    username="existing_app_user" \
    rotation_period="24h" \
    rotation_statements="ALTER ROLE \"\" WITH PASSWORD '';"
# Get current credentials
vault read database/static-creds/my-static-role

The username stays the same, but the password rotates every 24 hours.


Quick Reference

Command Description
vault secrets enable database Enable database engine
vault write database/config/NAME ... Configure connection
vault write -f database/rotate-root/NAME Rotate root password
vault write database/roles/ROLE ... Create dynamic role
vault read database/creds/ROLE Generate credentials
vault write database/static-roles/NAME ... Create static role
vault read database/static-creds/NAME Get static credentials

Next: PostgreSQL & MySQL