Skip to content

Using hashicorp vault for personal secrets

Today I will show you how to use vault for your personal secrets. Normally you would auth and get access to some path in vault where everyone in your team have access too, but in some cases you may want to use vault for your own secrets as well, i.e for storing passphrase for the ssh private key or email or something similar.

So here is a list of commands that needs to be run, first as an admin to set up auth and policies, and then as a user, auth and read/write secrets.

Create a policy that allows actions under ones identity:

cat <<EOF | vault policy write identity -
path "secret/data/{{identity.entity.id}}/*" {
	capabilities = ["create", "read", "update", "delete"]
}
EOF

Enable userpass under usrpss(can name it anything) auth to test:

vault auth enable -path=usrpss userpass

Create users with identity policy:

vault write auth/usrpss/users/user1 password=123456 policies=identity
vault write auth/usrpss/users/user2 password=123456 policies=identity

Get accessor id for the auth:

vault auth list -format=json | jq -r '.["usrpss/"].accessor' > usrpss_accessor.txt

Create entity and save its id:

vault write -format=json identity/entity name="user1" policies="identity" | jq -r ".data.id" > entity_id.txt

vault write -format=json identity/entity name="user2" policies="identity" | jq -r ".data.id" > entity_id2.txt

Create entity-alias and map entity to the auth:

vault write identity/entity-alias name=usr1 canonical_id=$(cat entity_id.txt) mount_accessor=$(cat usrpss_accessor.txt)
vault write identity/entity-alias name=usr2 canonical_id=$(cat entity_id2.txt) mount_accessor=$(cat usrpss_accessor.txt)

Login as new user user1, it will show your identity id, under which you can read/write secrets:

vault login -format=json -method=userpass -path=usrpss username=user1 password=123456 | grep entity_id
# "entity_id": "03fc5c89-6ddd-f1da-9459-0b7fec4dbaf4",

Write a secret:

vault kv put secret/03fc5c89-6ddd-f1da-9459-0b7fec4dbaf4/test key=yyy111

Read the secret:

vault kv get secret/03fc5c89-6ddd-f1da-9459-0b7fec4dbaf4/test
# ==================== Secret Path ====================
# secret/data/03fc5c89-6ddd-f1da-9459-0b7fec4dbaf4/test

# ======= Metadata =======
# Key                Value
# ---                -----
# created_time       2023-02-09T16:10:08.367127Z
# custom_metadata    <nil>
# deletion_time      n/a
# destroyed          false
# version            8

# === Data ===
# Key    Value
# ---    -----
# key    yyy111

Note that policy has secret/data/ but cli ignores the data bit when reading/writing, even though it shows it again in the secret path as a response (at least as of version 1.11.5 which is a bit confusing and inconsistent)

In UI you need the full path, including identity part:

http://localhost:8200/ui/vault/secrets/secret/show/03fc5c89-6ddd-f1da-9459-0b7fec4dbaf4/test

Now login as second user user2:

vault login -format=json -method=userpass -path=usrpss username=user2 password=123456 | grep entity_id
# "entity_id": "b1812432-ea9b-0a9d-287a-27a0a894f6cb",

It will fail to read under first users identity path:

vault kv get secret/03fc5c89-6ddd-f1da-9459-0b7fec4dbaf4/test
# Error reading secret/data/03fc5c89-6ddd-f1da-9459-0b7fec4dbaf4/test: Error making API request.

# URL: GET http://127.0.0.1:8200/v1/secret/data/03fc5c89-6ddd-f1da-9459-0b7fec4dbaf4/test
# Code: 403. Errors:

# * 1 error occurred:
# 	* permission denied

But will only work as expected under his own identity path:

vault kv put secret/b1812432-ea9b-0a9d-287a-27a0a894f6cb/test4 key=333
===================== Secret Path =====================
secret/data/b1812432-ea9b-0a9d-287a-27a0a894f6cb/test4

======= Metadata =======
Key                Value
---                -----
created_time       2023-02-11T21:12:28.155534Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3


➜  ~ vault kv get secret/b1812432-ea9b-0a9d-287a-27a0a894f6cb/test4
===================== Secret Path =====================
secret/data/b1812432-ea9b-0a9d-287a-27a0a894f6cb/test4

======= Metadata =======
Key                Value
---                -----
created_time       2023-02-11T21:12:28.155534Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            3

=== Data ===
Key    Value
---    -----
key    333

Please note this feature only available from 0.11+