Hashicorp Vault - ACL Policies
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:
Capability | Associated HTTP verbs |
---|---|
create | POST/PUT |
read | GET |
update | POST/PUT |
delete | DELETE |
list | LIST |
sudo | The sudo capability allows access to paths that are root-protected (Refer to the Root protected endpoints section). |
deny | The 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:
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: