open-vault/website/source/guides/secret-mgmt/db-root-rotation.html.md
Jeff Escalante a3dfde5cec New Docs Website (#5535)
* conversion stage 1

* correct image paths

* add sidebar title to frontmatter

* docs/concepts and docs/internals

* configuration docs and multi-level nav corrections

* commands docs, index file corrections, small item nav correction

* secrets converted

* auth

* add enterprise and agent docs

* add extra dividers

* secret section, wip

* correct sidebar nav title in front matter for apu section, start working on api items

* auth and backend, a couple directory structure fixes

* remove old docs

* intro side nav converted

* reset sidebar styles, add hashi-global-styles

* basic styling for nav sidebar

* folder collapse functionality

* patch up border length on last list item

* wip restructure for content component

* taking middleman hacking to the extreme, but its working

* small css fix

* add new mega nav

* fix a small mistake from the rebase

* fix a content resolution issue with middleman

* title a couple missing docs pages

* update deps, remove temporary markup

* community page

* footer to layout, community page css adjustments

* wip downloads page

* deps updated, downloads page ready

* fix community page

* homepage progress

* add components, adjust spacing

* docs and api landing pages

* a bunch of fixes, add docs and api landing pages

* update deps, add deploy scripts

* add readme note

* update deploy command

* overview page, index title

* Update doc fields

Note this still requires the link fields to be populated -- this is solely related to copy on the description fields

* Update api_basic_categories.yml

Updated API category descriptions. Like the document descriptions you'll still need to update the link headers to the proper target pages.

* Add bottom hero, adjust CSS, responsive friendly

* Add mega nav title

* homepage adjustments, asset boosts

* small fixes

* docs page styling fixes

* meganav title

* some category link corrections

* Update API categories page

updated to reflect the second level headings for api categories

* Update docs_detailed_categories.yml

Updated to represent the existing docs structure

* Update docs_detailed_categories.yml

* docs page data fix, extra operator page remove

* api data fix

* fix makefile

* update deps, add product subnav to docs and api landing pages

* Rearrange non-hands-on guides to _docs_

Since there is no place for these on learn.hashicorp, we'll put them
under _docs_.

* WIP Redirects for guides to docs

* content and component updates

* font weight hotfix, redirects

* fix guides and intro sidenavs

* fix some redirects

* small style tweaks

* Redirects to learn and internally to docs

* Remove redirect to `/vault`

* Remove `.html` from destination on redirects

* fix incorrect index redirect

* final touchups

* address feedback from michell for makefile and product downloads
2018-10-19 08:40:11 -07:00

12 KiB

layout page_title sidebar_title sidebar_current description
guides DB Root Credential Rotation - Guides DB Root Credential Rotation guides-secret-mgmt-db-root-rotation Vault enables the combined database secret engines to automate the rotation of root credentials.

Database Root Credential Rotation

Database Secrets Engine

Vault's database secrets engine provides a centralized workflow for managing credentials for various database systems. By leveraging this, every service instance gets a unique set of database credentials instead of sharing one. Having those credentials tied directly to each service instance and live only for the life of the service, any abnormal access pattern can be mapped to a specific service instance and its credential can be revoked immediately.

This reduces the manual tasks performed by the database administrator and make the access to the database to be more efficient and secure.

The Secret as a Service: Dynamic Secrets guide demonstrates the primary workflow.

Reference Material

Estimated Time to Complete

10 minutes

Challenge

Because Vault is managing the database credentials on behalf of the database administrator, it must also be given a set of highly privileged credentials which can grant and revoke access to the database system. Therefore, it is very common to give Vault the root credentials.

However, these credentials are often long-lived and never change once configured on Vault. This may violate the Governance, Risk and Compliance (GRC) surrounding that data stored in the database.

Solution

Use the Vault's /database/rotate-root/:name API endpoint to rotate the root credentials stored for the database connection.

DB Root Credentials

~> Best Practice: Use this feature to rotate the root credentials immediately after the initial configuration of each database.

Prerequisites

To perform the tasks described in this guide, you need to have a Vault environment. Refer to the Getting Started guide to install Vault. Make sure that your Vault server has been initialized and unsealed.

PostgreSQL

This guide requires that you have a PostgreSQL server to connect to. If you don't have one, install PostgreSQL.

Policy requirements

-> NOTE: For the purpose of this guide, you can use root token to work with Vault. However, it is recommended that root tokens are only used for just enough initial setup or in emergencies. As a best practice, use tokens with appropriate set of policies based on your role in the organization.

To perform all tasks demonstrated in this guide, your policy must include the following permissions:

# Mount secret engines
path "sys/mounts/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

# Configure the database secret engine and create roles
path "database/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

If you are not familiar with policies, complete the policies guide.

Steps

Using Vault, you can easily rotate the root credentials for your database through the database/rotate-root/:name endpoint.

This guide demonstrates the overall workflow to manage the database credentials including the root.

You are going to perform the following:

  1. Enable the database secret engine
  2. Configure PostgreSQL secret engine
  3. Verify the configuration (Optional)
  4. Rotate the root credentials

Step 1: Enable the database secret engine

CLI command

Enable a database secret engine:

$ vault secrets enable database

NOTE: This example enables the database secret engine at the /database path in Vault.

API call using cURL

To enable a database secret engine, use the /sys/mounts endpoint.

$ curl --header "X-Vault-Token: ..." \
       --request POST \
       --data '{"type":"database"}' \
       https://127.0.0.1:8200/v1/sys/mounts/database

NOTE: This example mounts database secret engine at /database, and passes the secret engine type ("database") in the request payload.

Step 2: Configure PostgreSQL secret engine

In the Secret as a Service: Dynamic Secrets guide, the PostgreSQL plugin was configured with its root credentials embedded in the connection_url (root and rootpassword) as below:

$ vault write database/config/postgresql \
      plugin_name=postgresql-database-plugin \
      allowed_roles="*" \
      connection_url=postgresql://root:rootpassword@postgres.host.address:5432/postgres

The username and password can be templated using the format, {{<field-name>}}.

~> In order to leverage the database root credential rotation feature, you must use the templated credentials: {{username}} and {{password}}.

CLI command

$ vault write database/config/postgresql \
     plugin_name=postgresql-database-plugin \
     connection_url="postgresql://{{username}}:{{password}}@postgres.host.address:5432/postgres" \
     allowed_roles="*" \
     username="root" \
     password="rootpassword"

Notice that the connection_url value contains the templated credentials, and username and password parameters are also passed to initiate the connection.

Create a role, readonly:

# Create readonly.sql defining the role privilege  
$ tee readonly.sql <<EOF
CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "{{name}}";
EOF

# Create a role named 'readonly' with TTL of 1 hr
$ vault write database/roles/readonly db_name=postgresql \
         creation_statements=@readonly.sql \
         default_ttl=1h max_ttl=24h

API call using cURL

$ tee payload.json <<EOF
{
    "plugin_name": "postgresql-database-plugin",
    "connection_url": "postgresql://{{username}}:{{password}}@postgres.host.address:5432/postgres",
    "allowed_roles": "readonly",
    "username": "root",
    "password": "rootpassword"
}
EOF

$ curl --header "X-Vault-Token: ..."
       --request POST \
       --data @payload.json \
       http://127.0.0.1:8200/v1/database/config/postgresql

Notice that the connection_url value contains the templated credentials, and username and password parameters are also passed to initiate the connection.

Create a role, readonly:

# Create the request payload
$ tee payload.json <<EOF
{
	"db_name": "postgres",
	"creation_statements": "CREATE ROLE '{{name}}' WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
  GRANT SELECT ON ALL TABLES IN SCHEMA public TO '{{name}}';",
	"default_ttl": "1h",
	"max_ttl": "24h"
}
EOF

$ curl --header "X-Vault-Token: ..."
       --request POST \
       --data @payload.json \
       http://127.0.0.1:8200/v1/database/roles/readonly

Step 3: Verify the configuration (Optional)

Before rotate the root credentials, make sure that the secret engine was configured correctly.

CLI command

# Get a new set of credentials
$ vault read database/creds/readonly
Key                Value
---                -----
lease_id           database/creds/readonly/999c43f0-f79e-ba90-24a8-4de5af33a2e9
lease_duration     1h
lease_renewable    true
password           A1a-u7wxtrpx09xp40yq
username           v-root-readonly-x6q809467q98yp4yx4z4-1525378026e


# Make sure that you can connect to the database using the Vault generated credentials
$ psql -h postgres.host.address -p 5432 \
       -U v-root-readonly-x6q809467q98yp4yx4z4-1525378026e postgres
Password for user v-root-readonly-x6q809467q98yp4yx4z4-1525378026:

postgres=> \du
Role name                                       |                         Attributes                         | Member of
------------------------------------------------+------------------------------------------------------------+----------
postgres                                        | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
v-root-readonly-x6q809467q98yp4yx4z4-1525378026 | Password valid until 2018-05-03 21:07:11+00                | {}

postgres=> \q

API call using cURL

# Get a new set of credentials
$ curl --header "X-Vault-Token: 1c97b03a-6098-31cf-9d8b-b404e52dcb4a" \
       http://127.0.0.1:8200/v1/database/creds/readonly | jq
{
   "request_id": "527970fd-f5e8-4de5-d4ed-1b7970eaef0b",
   "lease_id": "database/creds/readonly/ac79265e-668c-242f-4f67-1dae33da094c",
   "renewable": true,
   "lease_duration": 3600,
   "data": {
     "password": "A1a-0tr8u15y0us2u08v",
     "username": "v-root-readonly-x7v65y1xuprzxv9vpt80-1525378873"
   },
   "wrap_info": null,
   "warnings": null,
   "auth": null
}

# Make sure that you can connect to the database using the Vault generated credentials
$ psql -h postgres.host.address -p 5432 \
       -U v-root-readonly-x6q809467q98yp4yx4z4-1525378026e postgres
Password for user v-root-readonly-x6q809467q98yp4yx4z4-1525378026:

postgres=> \du
Role name                                       |                         Attributes                         | Member of
------------------------------------------------+------------------------------------------------------------+----------
postgres                                        | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
v-root-readonly-x6q809467q98yp4yx4z4-1525378026 | Password valid until 2018-05-03 21:07:11+00                | {}
v-root-readonly-x7v65y1xuprzxv9vpt80-1525378873 | Password valid until 2018-05-03 21:21:18+00                | {}

postgres=> \q

This confirms that the Vault successfully connected to your PostgreSQL server and created a new user based on the privilege defined by readonly.sql.

The user credentials generated by the Vault has a limited TTL based on your configuration (default_ttl). In addition, you can revoke them if necessary.

Step 4: Rotate the root credentials

Vault provides an API endpoint to easily rotate the root database credentials.

CLI command

$ vault write -force database/rotate-root/postgresql

API call using cURL

$ curl --header "X-Vault-Token: ..." \
       --request POST \
       http://127.0.0.1:8200/v1/database/rotate-root/postgresql

This is all you need to do.



Repeat Step 3 to verify that Vault continues to generate database credentials after the root credential rotation.

To verify that the root credential was rotated:

$ psql -h postgres.host.address -p 5432 -U root postgres
Password for user root:

Entering the initial password (e.g. rootpassword) will not work since the password was rotated by the Vault.

You can invoke the database/rotate-root/:name endpoint periodically to secure the root credential.

~> NOTE: Once the root credential was rotated, only the Vault knows the new root password. This is the same for all root database credentials given to Vault. Therefore, you should create a separate superuser dedicated to the Vault usage which is not used for other purposes.

Next steps

In this guide, you learned how to rotate the root database credentials.

Read the AppRole Pull Authentication guide to learn about generating a client token for your app so that it can request database credentials from Vault.