Skip to main content

Hashicorp Vault - ACL Policies

Shenzhen, China

Every Vault operation performed through the command-line interface (CLI), API, or web UI require that the authenticated client is granted access; access defined through policies. Everything in Vault is stored at different paths, like a filesystem, and every action in Vault has a corresponding path and capability. Policies provide a declarative way to grant or forbid access to paths and the capabilities at each path.

E.g. have all the rights to add and delete secrets under the path sys/auth and be allowed to read them:

path "sys/auth/*" {
  capabilities = ["create", "update", "delete", "sudo"]
}

path "sys/auth" {
  capabilities = ["read"]
}

Write a Policy using API

Write a policy

An admin user must be able to:

  • Read system health check
  • Create and manage ACL policies broadly across Vault
  • Enable and manage authentication methods broadly across Vault
  • Manage the Key-Value secrets engine enabled at secret/ path

Define the admin policy in the file named admin-policy.hcl:

tee admin-policy.hcl <<EOF
# Read system health check
path "sys/health"
{
  capabilities = ["read", "sudo"]
}

# Create and manage ACL policies broadly across Vault

# List existing policies
path "sys/policies/acl"
{
  capabilities = ["list"]
}

# Create and manage ACL policies
path "sys/policies/acl/*"
{
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Enable and manage authentication methods broadly across Vault

# Manage auth methods broadly across Vault
path "auth/*"
{
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Create, update, and delete auth methods
path "sys/auth/*"
{
  capabilities = ["create", "update", "delete", "sudo"]
}

# List auth methods
path "sys/auth"
{
  capabilities = ["read"]
}

# Enable and manage the key/value secrets engine at `secret/` path

# List, create, update, and delete key/value secrets
path "secret/*"
{
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Manage secrets engines
path "sys/mounts/*"
{
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# List existing secrets engines.
path "sys/mounts"
{
  capabilities = ["read"]
}
EOF

A policy define one or more paths and a list of permitted capabilities. Most of these capabilities map to the HTTP verbs supported by the Vault API:

CapabilityAssociated HTTP verbs
createPOST/PUT
readGET
updatePOST/PUT
deleteDELETE
listLIST
sudoThe sudo capability allows access to paths that are root-protected (Refer to the Root protected endpoints section).
denyThe deny capability disables access to the path. When combined with other capabilities it always precedence.

Create a policy

Create a policy named admin with the policy defined in admin-policy.hcl:

vault policy write admin admin-policy.hcl
Success! Uploaded policy: admin

Display a policy

List all the policies:

vault policy list

admin
default
root

Read the admin policy:

vault policy read admin

The output displays the paths and capabilities defined for this policy.

Apply a Policy to an Auth Token

Creating the Policy

Start by enabling a secret engine for your policy:

vault secrets enable -path=secret/ kv
Success! Enabled the kv secrets engine at: secret/

Write the policy:

tee test-elastic.hcl <<EOF
# Create/Read Elastic login
path "secret/login/elastic"
{
  capabilities = ["create", "read"]
}
EOF

Create the policy:

vault policy write elastic_login test-elastic.hcl

Attaching an Auth Token

vault token create -policy="elastic_login"

Key                  Value
---                  -----
token                s.GZHF5D5zYJk1zmzxLmxivPY8
token_accessor       lfJsAlfKqZEALqv2Yyw7SlNP
token_duration       768h
token_renewable      true
token_policies       ["default" "elastic_login"]
identity_policies    []
policies             ["default" "elastic_login"]

Testing the Token

Since I am logged in to Vault with my environment I first have to unset my token before I can use the new one to login with:

unset VAULT_TOKEN

vault login

Token (will be hidden): s.GZHF5D5zYJk1zmzxLmxivPY8
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                s.GZHF5D5zYJk1zmzxLmxivPY8
token_accessor       lfJsAlfKqZEALqv2Yyw7SlNP
token_duration       767h58m43s
token_renewable      true
token_policies       ["default" "elastic_login"]
identity_policies    []
policies             ["default" "elastic_login"]

Verify that you have all the rights assigned to you by the policy:

vault token capabilities secret/login/elastic
create, read

Now I am logged in with the created token and should have the right to add a secret to secret/login/elastic:

vault kv put secret/login/elastic password="Hzo3aku+S37JDzeXGUxZX+H5WE"
Success! Data written to: secret/login/elastic

And also read it:

vault kv get secret/login/elastic

====== Data ======
Key         Value
---         -----
password    Hzo3aku+S37JDzeXGUxZX+H5WE

Vault UI

You can also use the user interface to access the secret:

Hashicorp Vault

Updating a Policy

Here I noticed a problem with my policy - I am allowed to read secret/login/policy. But the UI forces me to click on secret/ then secret/login/ to get there - and I don't have access to those. I will have to update the policy accordingly:

tee test-elastic.hcl <<EOF
# Read everything stored under secret/
path "secret/*" {
  capabilities = ["read", "list"]
}

# Create/Update Elastic login
path "secret/login/elastic"
{
  capabilities = ["create", "update", "read"]
}
EOF

Update the policy (remember to re-login with the root token):

vault policy write elastic_login test-elastic.hcl 
Success! Uploaded policy: elastic_login

Verify:

vault policy read elastic_login

# Read everything stored under secret/
path "secret/*" {
  capabilities = ["read", "list"]
}

# Create/Update Elastic login
path "secret/login/elastic"
{
  capabilities = ["create", "update", "read"]
}

And I am able to access and edit the variable:

Hashicorp Vault