Skip to content

Instantly share code, notes, and snippets.

@stenio123
Last active November 13, 2022 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stenio123/df27d2bacc90b38aa5edafab802ba015 to your computer and use it in GitHub Desktop.
Save stenio123/df27d2bacc90b38aa5edafab802ba015 to your computer and use it in GitHub Desktop.
Vault Examples

Vault Examples

Examples highligthing different Vault features.

To have a list of valid CLI flags, use

vault -h
vault <FEATURE> -h

HA Replication

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

MySql Secret Engine

## 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

Key value store

# 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

Control Groups/ GDPR

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

Namespaces (Enterprise feature)

You can find a step-by step guide here: https://www.vaultproject.io/guides/operations/multi-tenant.html

Token Wrapping

# 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

Azure MFA

Coming soon

Transit backend

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

Mount Filters/ GDPR (Enterprise feature)

Check step-by-step guide here: https://www.vaultproject.io/guides/operations/mount-filter.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment