This is a simple web blog to demo use cases with Hashicorp Vault.
It uses python, flask, bootstrap, mongodb, consul, and vault.
From the mongo client inside the admin database run the following:
db.createUser(
{
user: "sam",
pwd: "test123", // or cleartext password
roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
}
)
Exit the mongo client
sudo mongod --auth --port 27017 --dbpath /var/lib/mongodb
mongo --port 27017 --authenticationDatabase "admin" -u "sam" -p "test123"
We used consul for our storage backend for Vault. Run the command below to start consul in dev mode and enable the UI.
consul agent -data-dir /home/sam/SourcePrograms/consulData -bind 127.0.0.1 -ui -server -bootstrap
You can then access the UI at: http://127.0.0.1:8500/ui
Start the vault server using a config file.
vault server -config=vaultConfig.hcl
Content of the config file are below:
storage "consul" {
address = "127.0.0.1:8500"
path = "vault/"
}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}
disable_mlock = true
export VAULT_ADDR='http://127.0.0.1:8200'
vault operator init
You get the following output. In production you typically would use Vault's PGP and Keybase.io support to encrypt each of these keys so only one person has access to one key only.
Unseal Key 1: swYDskW6NXaSAnS9qw9i3LoHtKD9osgSYmElMZ2WnKZx
Unseal Key 2: WvJ/iXj0eTVilG8Ah2Qd8TIC5W0lrtNVIwmumkUs86rw
Unseal Key 3: mrXUPqw/FwODBZ0RBZIESTNLKOr7b4RTFRsNUacxhaF/
Unseal Key 4: 582m4xbblhzCfZ2yESrib4xdUCLWtNK6OY5WFD539jof
Unseal Key 5: aikfjmr7K7lcROAN2Fhr+tefFwVdQZQzOm0Ut5YygExf
Initial Root Token: s.lI9ntwIVMMZnnhxMRAPg4zu5
Vault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.
Vault does not store the generated master key. Without at least 3 key to
reconstruct the master key, Vault will remain permanently sealed!
It is possible to generate new unseal keys, provided you have a quorum of
existing unseal keys shares. See "vault operator rekey" for more information.
Run the following command 3 times providing 3 out of the 5 unseal keys.
vault operator unseal
vault login s.lI9ntwIVMMZnnhxMRAPg4zu5
vault secrets enable database
vault write database/config/my-mongodb-database \
plugin_name=mongodb-database-plugin \
allowed_roles="my-role" \
connection_url="mongodb://{{username}}:{{password}}@127.0.0.1:27017/admin" \
username="sam" \
password="test123"
Configure a role that maps a name in Vault to a MongoDB command that executes and creates the database credential
vault write database/roles/my-role \
db_name=my-mongodb-database \
creation_statements='{ "db": "admin", "roles": [{ "role": "readWriteAnyDatabase" }, {"role": "read", "db": "foo"}] }' \
default_ttl="10s" \
max_ttl="24h"
vault read database/creds/my-role
Change the X-Vault-Token
value below to work for yours.
$ curl \
--header "X-Vault-Token: s.lI9ntwIVMMZnnhxMRAPg4zu5" \
http://127.0.0.1:8200/v1/database/creds/my-role
{
"data": {
"username": "root-1430158508-126",
"password": "132ae3ef-5a64-7499-351e-bfe59f3a2a21"
}
}
Change the X-Vault-Token
value below to yours.
response = requests.get(
'http://127.0.0.1:8200/v1/database/creds/my-role',
params={'q': 'requests+language:python'},
headers={'X-Vault-Token': 's.lI9ntwIVMMZnnhxMRAPg4zu5'},
)
json_response = response.json()
Database.USER = json_response['data']['username']
Database.PASSWORD = json_response['data']['password']
Database.URI = f'mongodb://{Database.USER}:{Database.PASSWORD}@{Database.SERVER}:{Database.PORT}'
- Make sure you're logged out of the app. Have the VS code screen with the teriminal output showing. Also have the VS code screen side by side to the Chrome screen.
- Comment and uncomment the lines in
databse.py
and.env
to show the static hard-coded creds scenario. - Log into the app
- Show the stdout in VS code's terminal showing the hard-coded username and password are the same as those in the
.env
file. - Browse the Blogs page to show that the creds don't expire.
- Log out of the app
- Comment and uncomment the lines in
databse.py
and.env
to show the dynamic secrets scenario using Vault - Log into the app
- Show the stdout in VS code's terminal showing the auto-generated username and password by vault.
- Browse the Blogs page to show that the creds expire and we get a message saying
mongoDB auth failed due to creds expiring. Rotating creds now
. Then we get new creds. - Pivot over to a terminal with the mongo client running. Make sure you're logged in as an admin. Run the commands:
use admin
andshow users
. Show how the creds appear and disappear based on the timeout. You will need to browse the web blog to generate new creds.