Role-based access control for Amazon DocumentDB with Vault

Amazon DocumentDB (with MongoDB compatibility) is a fully managed document database service that supports MongoDB 3.6 or 4.0 workloads.

With role-based access control, you can grant users one or more predefined roles (for example, read, readWrite, or dbOwner) that determine which operations they are authorized to perform on one or more databases.

Concepts

  • User A named entity that can authenticate and perform operations
  • Password — A secret word that authenticates the user
  • Role — A designation that authorizes a user to perform actions on one or more databases
  • Admin Database — A special database to authorize users against
  • Database (DB) — The namespace within a cluster that contains collections

Vault Database Secrets Engine

The database secrets engine generates database credentials dynamically based on configured roles. It works with a number of different databases through a plugin interface. MongoDB is one of the supported plugins for the database secrets engine. This plugin generates database credentials dynamically based on configured roles for the MongoDB database.

Enable the database secrets engine on the Vault server to start using mongodb-database-plugin.

$ vault secrets enable database Success! Enabled the database secrets engine at: database/

Enforcing least privilege

An application often uses a single Amazon DocumentDB cluster as its datastore but some users may need to read and write data, whereas other users may only require read access. The principle of least privilege is a foundational security tool; you can use RBAC to apply this principle by limiting user access to only what is required to perform their functions.

Configure Vault with the proper plugin and Amazon DocumentDB connection information.

$ vault write database/config/my-documentdb-database \     plugin_name=mongodb-database-plugin \     
allowed_roles="documentdb-read-only" \ connection_url="mongodb://{{username}}:{{password}}@<clusterName>.<region>.docdb.amazonaws.com:27017/admin?tls=true" \
username="vaultuser" \
password="vaultpass!"

Configure a role that maps a name in Vault to a MongoDB command that executes and creates the database credential.

$ vault write database/roles/documentdb-read-only \
db_name=my-documentdb-database \
creation_statements='{ "db": "admin", "roles": [{ "role": "readWrite" }, {"role": "read", "db": "foo"}] }' \
default_ttl="1h" \
max_ttl="24h"
Success! Data written to: database/roles/documentdb-read-only

This role generates a credential for a user that only needs to read data from the foo database.

Usage

Generate a new credential by reading from the /creds endpoint with the name of the role.

$ vault read database/creds/documentdb-read-only
Key Value
--- -----
lease_id database/creds/documentdb-read-only/bz5AsIazjr8hfdH25KHsDCfA
lease_duration 1h
lease_renewable true
password 6TpiQ-x0XVKr-feIUlBj
username v-vaultuser-documentdb-read-only--ItceCZHlp0YGn90Puy9Z-1602542024

You can connect and authenticate to your cluster using the username and password with the following CLI command.

mongo --host <clusterName>.<region>.docdb.amazonaws.com:27017 --username v-vaultuser-documentdb-read-only--ItceCZHlp0YGn90Puy9Z-1602542024 --password 6TpiQ-x0XVKr-feIUlBj

Because you are authenticated with the read-only role, you can read data.

db.catalog.find({"name": "banana"})Output:
{ "_id" : 1, "name" : "banana", "quantity" : 10}

However, you are not authorized to write data. For example, the following code attempts to insert new data and receive the following output.

db.catalog.insert({"name": "lemons", "quantity": 99})Output:
WriteResult({ "writeError" : { "code" : 13, "errmsg" : "Authorization failure" } })

The full list of configurable options can be seen on the MongoDB database plugin API page.

Senior DevOps Engineer