Examples highligthing different Vault features.
To have a list of valid CLI flags, use
vault -h
vault <FEATURE> -h
To have Vault running in HA mode, you should have a Consul cluster deployed as backend. You can view the code here: https://github.com/hashicorp/vault-guides/tree/master/operations/provision-vault
More specifically, to configure Vault for HA mode: https://github.com/hashicorp/vault-guides/blob/master/operations/provision-vault/templates/best-practices-vault-systemd.sh.tpl
In progress, under review - you might encounter a few errors: If you want to test replication and failover locally (with 3 independent processes in same machine), you can use this guide: https://github.com/hashicorp/vault-guides/tree/f-local-replication/operations/local-replication
## mariadb setup
sudo yum install -y mariadb-server
sudo systemctl start mariadb
mysqladmin -u root password R00tPassword
mysql -u root -p'R00tPassword' << EOF
GRANT ALL PRIVILEGES ON *.* TO 'vaultadmin'@'127.0.0.1' IDENTIFIED BY 'vaultadminpassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EOF
# Authenticate to Vault
vault auth password
# Mount database backend
vault mount database
# Configure MySQL connection
vault write database/config/mysql \
plugin_name=mysql-legacy-database-plugin \
connection_url="vaultadmin:vaultadminpassword@tcp(127.0.0.1:3306)/" \
allowed_roles="readonly"
# Create MySQL readonly role
vault write database/roles/readonly \
db_name=mysql \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';" \
default_ttl="30m" \
max_ttl="24h"
# Read a set of credentials from the role
vault read database/creds/readonly
# validate the new user exists in the database
mysql -u root -p'R00tPassword' -e "select user from mysql.user;"
# Revoke the user via the lease ID and verify the user has been deleted from the database
vault revoke database/creds/readonly/919fed1c-e6c1-ba0a-9edc-cba5ce58cdc3
# Alternatively, you can revoke a group of users based on prefix:
vault revoke -prefix database/creds/readonly
# Create two basic policies, in two plain text files:
# Contents of user1.hcl:
path "secret/data/user1" {
capabilities = ["create", "update", “read”]
}
# Contents of user2.hcl
path "secret/data/user2" {
capabilities = ["create", "update", “read”]
}
# These policies need to be imported into Vault.
vault policy write user1 user1.hcl
vault policy write user2 user2.hcl
# Generate two tokens, associated with the previously created policies
# For convenience, we can store their value in environment variables:
TOKEN1=$(vault token create -display-name="user1" -policy="user1" -field=token)
TOKEN2=$(vault token create -display-name="user2" -policy="user2" -field=token)
# Now let's write a secret with user1:
VAULT_TOKEN=$TOKEN1 vault kv put secret/user1 "password=secret"
# To retrieve the secret:
VAULT_TOKEN=$TOKEN1 vault kv get secret/user1
# You can also use -field to specify which field to return, or -format to specify output format:
VAULT_TOKEN=$TOKEN1 vault kv get secret/user1 field=password
VAULT_TOKEN=$TOKEN1 vault kv get secret/user1 -format=json
# To update the value:
VAULT_TOKEN=$TOKEN1 vault kv put secret/user1 "password=verysecure"
# And to validate:
VAULT_TOKEN=$TOKEN1 vault kv get -field=password secret/user1
# Attempt to retrieve the secret using the token associated to the user2 policy to see error:
VAULT_TOKEN=$TOKEN2 vault kv get secret/user1
vault secrets enable -path EU_GDPR_data kv
vault write EU_GDPR_data/UK foo=bar
vault write secret/foo bar=baz
vault auth enable userpass
USERPASS_ACCESSOR=$(curl -H "X-Vault-Token: ${VAULT_TOKEN}" \
--request GET $VAULT_ADDR/v1/sys/auth | jq -r '.data."userpass/".accessor')
##################
#SETUP PROCESS0RS
##################
echo '
path "EU_GDPR_data/*" {
capabilities = ["read"]
control_group = {
factor "Dual Controllers" {
identity {
group_names = ["controllers"]
approvals = 2
}
}
}
}
path "secret/*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}'| vault policy write gdpr -
#Create Andrew K entity
echo '
{
"name": "andrewkHcorp",
"metadata": {
"team": "processors"
},
"policies": ["gdpr"]
}' > andrewk-entity.json
ANDREWK_ENTITY_ID=$(curl -H "X-Vault-Token: ${VAULT_TOKEN}" \
--request POST \
--data @andrewk-entity.json $VAULT_ADDR/v1/identity/entity | jq -r '.data.id')
#Create entity alias for Andrew to the userpass backend
echo "{
\"name\": \"andrew\",
\"canonical_id\": \"$ANDREWK_ENTITY_ID\",
\"mount_accessor\": \"$USERPASS_ACCESSOR\"
}" > andrewk-userpass-entity-alias.json
ANDREWK_ENTITY_ALIAS_ID=$(curl -H "X-Vault-Token: ${VAULT_TOKEN}" \
--request POST \
--data @andrewk-userpass-entity-alias.json $VAULT_ADDR/v1/identity/entity-alias | jq -r '.data.id')
echo "{
\"name\": \"processors\",
\"member_entity_ids\": [ \"${ANDREWK_ENTITY_ID}\" ],
\"policies\": [\"gdpr\"]
}" > processors.json
vault write identity/group @processors.json
##################
#SETUP CONTROLLERS
##################
echo '
#For authorization
path "/sys/control-group/authorize" {
capabilities = ["create", "update"]
}
#admin test
path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}'| vault policy write controllers -
#Create Brian G entity
echo '
{
"name": "briangHcorp",
"metadata": {
"team": "controllers"
},
"policies": ["controllers"]
}' > briang-entity.json
BRIANG_ENTITY_ID=$(curl -H "X-Vault-Token: ${VAULT_TOKEN}" \
--request POST \
--data @briang-entity.json $VAULT_ADDR/v1/identity/entity | jq -r '.data.id')
#Create entity alias for Brian to the userpass backend
echo "{
\"name\": \"brian\",
\"canonical_id\": \"$BRIANG_ENTITY_ID\",
\"mount_accessor\": \"$USERPASS_ACCESSOR\"
}" > briang-userpass-entity-alias.json
BRIANG_ENTITY_ALIAS_ID=$(curl -H "X-Vault-Token: ${VAULT_TOKEN}" \
--request POST \
--data @briang-userpass-entity-alias.json $VAULT_ADDR/v1/identity/entity-alias | jq -r '.data.id')
#Create Nico entity
echo '
{
"name": "nicoHcorp",
"metadata": {
"team": "controllers"
},
"policies": ["controllers"]
}' > nico-entity.json
NICO_ENTITY_ID=$(curl -H "X-Vault-Token: ${VAULT_TOKEN}" \
--request POST \
--data @nico-entity.json $VAULT_ADDR/v1/identity/entity | jq -r '.data.id')
#Create entity alias for Nico to the userpass backend
echo "{
\"name\": \"nico\",
\"canonical_id\": \"$NICO_ENTITY_ID\",
\"mount_accessor\": \"$USERPASS_ACCESSOR\"
}" > nico-userpass-entity-alias.json
NICO_ENTITY_ALIAS_ID=$(curl -H "X-Vault-Token: ${VAULT_TOKEN}" \
--request POST \
--data @nico-userpass-entity-alias.json $VAULT_ADDR/v1/identity/entity-alias | jq -r '.data.id')
echo "{
\"name\": \"controllers\",
\"member_entity_ids\": [ \"${BRIANG_ENTITY_ID}\", \"${NICO_ENTITY_ID}\" ],
\"policies\": [\"controllers\"]
}" > controllers.json
vault write identity/group @controllers.json
vault write auth/userpass/users/andrew password=vault
vault write auth/userpass/users/brian password=vault
vault write auth/userpass/users/nico password=vault
# USAGE
# Unset the env token
unset VAULT_TOKEN
# Login as Andrew
vault login -method=userpass username=andrew password=vault
#
# Read the secret
vault read EU_GDPR_data/UK
#Key Value
#--- -----
#wrapping_token: a8ca9e0e-c086-85ae-40da-1b5bd500a873
#wrapping_accessor: e1a58a15-31cd-ca1d-0c10-7613b24e38f3
#wrapping_token_ttl: 24h
#wrapping_token_creation_time: 2018-03-10 16:08:03 -0600 CST
# Now Login as Brian
vault login -method=userpass username=brian password=vault
vault write sys/control-group/authorize accessor=e1a58a15-31cd-ca1d-0c10-7613b24e38f3
# Now Login as Nico
vault login -method=userpass username=nico password=vault
vault write sys/control-group/authorize accessor=e1a58a15-31cd-ca1d-0c10-7613b24e38f3
# Switch back to Andrew and try to unwrap the token
vault login -method=userpass username=andrew password=vault
vault unwrap a8ca9e0e-c086-85ae-40da-1b5bd500a873
#Key Value
#--- -----
#refresh_interval 768h
#foo bar
You can find a step-by step guide here: https://www.vaultproject.io/guides/operations/multi-tenant.html
# Create a wrapped token that can be unwrapped within 30 minutes. We are also detaching the default policy and limiting number of uses.
WRAPPED_TOKEN=$(vault token create -policy=user1 -wrap-ttl=30m -use-limit=2 -no-default-policy=true -field=wrapping_token)
DEFAULT=$(vault token create -field=token)
VAULT_TOKEN=$DEFAULT vault unwrap $WRAPPED_TOKEN
# With the resulting token, you can see how many uses left:
vault token lookup TOKEN
Coming soon
The transit backend can be used to manage the lifecycle of encryption keys, and provide a high level API for developers to consume. Some example workflows:
Transit signing: https://github.com/hashicorp/vault-guides/tree/master/encryption/transit-signing
Using Docker and Dot Net: https://www.vaultproject.io/guides/encryption/transit-rewrap.html
Check step-by-step guide here: https://www.vaultproject.io/guides/operations/mount-filter.html