3

I have a Hashicorp Vault server configured and everything is running great, except for my "deny" policies.

I have a 2 level grouping for the majority of secrets, so they follow the structure of:

secret/client/environment/*

Not all secrets follow the client / environment structure, but for the ones that do, I have a "restricted" node that I don't want users of this policy to be able to access.

Based on the above requirements, I've ended up with a policy that looks like:

# Allow access to non client / environment secrets
path "secret/"
{
  capabilities = ["create", "read", "update", "list"]
}

path "secret/+/"
{
  capabilities = ["create", "read", "update", "list"]
}

path "secret/+/+/*"
{
  capabilities = ["create", "read", "update", "list"]
}

# No access to restricted secrets
path "secret/+/+/restricted"
{
  capabilities = ["deny"]
}

path "secret/+/+/restricted/*"
{
  capabilities = ["deny"]
}

If I create a token using the policy and use that token in a "vault token capabilities" command, it returns what I'd expect:

$vault token capabilities $(cat token.txt) secret/client/environment/blah
create, list, read, update

$vault token capabilities $(cat token.txt) secret/client/environment/restricted
deny

$vault token capabilities $(cat token.txt) secret/client/environment/restricted/blah
deny

The problem comes when I login using that token, I can not only list the contents of the restricted node, but can also get the details of any key within it (at all levels below). This is true through both the CLI and through the Web UI.

I did try with a simpler policy of allowing secret/* and then denying the secret/+/+/restricted/*, but this didn't even work correctly with the "vault token capabilities" command.

When I login using the token, it shows the correct policy (as well as default, but default has no permissions to secret/).

secret/ is setup as a kv store, so I'm accessing them through the CLI using "vault kv list|get ..."

Is there another step that I have to take to "force" the policy rules on a logged in user?

PhilHalf
  • 71
  • 1
  • 6

1 Answers1

4

It turns out that because I was using the KV v2 backend for secret storage, the policy structures are slightly different.

I ended up having to specify secret/metadata/ for listing permissions and secret/data/ for create/update/read

e.g:

# Allow listing of all secret branches
path "secret/metadata/"
{
  capabilities = ["list"]
}
path "secret/metadata/+/"
{
  capabilities = ["list"]
}

path "secret/metadata/+/+/"
{
  capabilities = ["list"]
}

# Allow management of all keys under secret/<client>/<environment> structure
path "secret/data/+/+/+"
{
  capabilities = ["create", "read", "update"]
}

And instead of putting a "deny" on the restricted node, the only other node at that level (at the moment) is the "unrestricted" node and so I added:

path "secret/metadata/+/+/unrestricted/"
{
  capabilities = ["list"]
}

path "secret/data/+/+/unrestricted/*"
{
  capabilities = ["create", "read", "update"]
}

As Vault policies are deny by default, this had the desired effect.

I found the details for the KV2 policy setup at: https://www.vaultproject.io/docs/secrets/kv/kv-v2.html#acl-rules

PhilHalf
  • 71
  • 1
  • 6