Using approles in vault

The most used way to login to opanbao/hashicorp vault is by using approles. This is a token based login with limited functionality (by using policies) per login.

Each approle should have limited acces, only to secrets/functions the role needs, this adds to your security.

First we start by creating policies (in this case some policies for signing login certificates).

In our case we need certificates signed for hosts and users.

The host signing just needs a signing period of a few days, renewing this certificate regularly lessens the chance of leaks. So the lifetime is set to 2 days, and we renew these every day.

The user certificates have 2 separate lifetimes:

  • 1) a standard user, needs a certificate with a lifetime long enough to login to a system (2 mins)
  • 2) the automation user (ansible) needs a certificate that is valid for a entire automation run (max 1 hour)

To create a policy in openbao:

  • Log in to the UI of openbao/hashicorp vault
  • From the manu select "Policies"
  • Select "Create ACL policy"
  • Fill in a the fields for the policy
  • Name for the policy 'hostcert'
  • Policy: path "/v1/ssh-host-signer/sign/*" { capabilities = ["update"] }
  • Save the policy

Repeat this for the usercert policy - Select "Create ACL policy" - Fill in a the fields for the policy - Name for the policy 'usercert' - Policy: path "/v1/ssh-client-signer/sign/*" { capabilities = ["update"] } - Save the policy

As we now have the policies, we can create the approles using these policies:

  • Log in the the server running the openbao container as the user running the container.
  • Start a session to enter the container docker exec -it openbao /bin/sh
  • Set the environment variables:
  • export VAULT_TOKEN=
  • export VAULT_ADDR=http://127.0.0.1:8200
  • now create the approle for signing the hostcertificate:
bao write auth/approle/role/hostcert \
    secret_id_ttl=0 \
    secret_id_max_uses=0 \
    token_num_uses=10 \
    token_ttl=20m \
    token_max_ttl=30m \
    token_policies="default,hostcert"

bao read auth/approle/role/hostcert/role-id

bao write -f auth/approle/role/hostcert/secret-id

## create approle user

bao write auth/approle/role/user \
    secret_id_ttl=0 \
    secret_id_max_uses=0 \
    token_num_uses=0 \
    token_ttl=2m \
    token_max_ttl=10m \
    token_policies="default,usercert"

bao read auth/approle/role/user/role-id
bao write -f auth/approle/role/user/secret-id

## create approle ansible

bao write auth/approle/role/ansible \
    secret_id_ttl=0 \
    secret_id_max_uses=0 \
    token_num_uses=0 \
    token_ttl=30m \
    token_max_ttl=60m \
    token_policies="default,usercert"

bao read auth/approle/role/ansible/role-id
bao write -f auth/approle/role/ansible/secret-id

Output:

/ $ bao write auth/approle/role/ansible \
>     secret_id_ttl=0 \
>     secret_id_max_uses=0 \
>     token_num_uses=0 \
>     token_ttl=30m \
>     token_max_ttl=60m \
>     token_policies="usercert"
Success! Data written to: auth/approle/role/ansible
/ $ 
/ $ bao read auth/approle/role/ansible/role-id
Key        Value
---        -----
role_id    4c3a1ea8-c8e2-2817-0159-a60ef8feab63
/ $ bao write -f auth/approle/role/ansible/secret-id
Key                   Value
---                   -----
secret_id             577c2aee-5f65-d2d5-a20e-391e50324641
secret_id_accessor    7bbf6543-a562-7ea5-1857-5c11f6862a4b
secret_id_num_uses    0
secret_id_ttl         0s

Copy and save the role_id and secret_id, these are needed for authentication.