This is a simple web blog to demo use cases with Hashicorp Vault. The app communicates directly with Vault using the API. This is for local demos only. web-blog-demo on Gitlab is used in the cloud on K8s.
It uses python, flask, bootstrap, mongodb, consul, and vault.
sudo mongod --port 27017 --dbpath /Users/sam/Deployments/HashiCorp/mongo_dataFrom the mongo client inside the admin database run the following:
use admin
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 /Users/sam/Deployments/HashiCorp/mongo_datamongo --port 27017 --authenticationDatabase "admin" -u "sam" -p "test123"Start the vault server using a config file.
vault server -config=vaultConfig.hclContent of the config file are below:
storage "file" {
path = "/Users/sam/Deployments/HashiCorp/vault_data"
}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}
disable_mlock = trueexport VAULT_ADDR='http://127.0.0.1:8200'
vault operator init -key-shares=1 -key-threshold=1You 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: 258G83eRO8SMqFWBRs9Bn+8yAdK7HVgtMiAkgOdh5iA=
Initial Root Token: s.ewt0JUqVxTVnU7fW04ZiKiYh
Run the following command to unseal
vault operator unsealvault login s.ewt0JUqVxTVnU7fW04ZiKiYhvault secrets enable databasevault 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-roleChange the X-Vault-Token value below to work for yours.
$ curl \
--header "X-Vault-Token: s.ewt0JUqVxTVnU7fW04ZiKiYh" \
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.ewt0JUqVxTVnU7fW04ZiKiYh'},
)
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. My email is sam and password is test123 to access the app.
- Comment and uncomment the lines in
databse.pyand.envto 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
.envfile. - Browse the Blogs page to show that the creds don't expire.
- Log out of the app
- Comment and uncomment the lines in
databse.pyand.envto 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 adminandshow users. Show how the creds appear and disappear based on the timeout. You will need to browse the web blog to generate new creds.