Need clarification on policies

I have this policy for “db”:

path "secret/*" {
  capabilities = ["list"]
}

path "secret/db/*" {
  capabilities = ["list", "read"]
}

I create a token with this policy via:

vault token create -policy db -period 72h -orphan -renewable=true -format=json

If I log in using this policy, I can click on and view sercret/ and secret/db/. But when I click on the link for secret/db/config, I am told:

“You don’t have access to secret/. If you think you’ve reached this page in error, please contact your administrator.”

According to the docs here: Policies | Vault by HashiCorp

# Permit reading everything under "secret/bar". An attached token could read
# "secret/bar/zip", "secret/bar/zip/zap", but not "secret/bars/zip".
path "secret/bar/*" {
  capabilities = ["read"]
}

Why can my token read secret/db but not secret/db/config? From reading the priority rules, the longer path should have higher priority, so I should have read/list on anything under secret/bar/*.

Pointers appreciated!

I found that if I did this:

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

path "secret/db/*" {
  capabilities = ["list", "read"]
}

I could reach secret/db/config with my db token…but I don’t want that token to have ‘read’ on secret/*

I got this to work…rather unintuitively.

path "secret/*" {
  capabilities = ["read"]
}

path "secret/db/*" {
  capabilities = ["list", "read"]
}

But that still gives me pause because it I could still guess at other paths and acquire so secrets.

What is the proper way to do this? How do I say (in file system terms, which the docs try to use as an analogy), “let this token walk down the tree, but only showing folders to which they have access?”

Thanks.

OK, this makes NO sense. I did this as my policy:

path "secret/*" {
  capabilities = ["list"]
}

path "secret/db/config" {
  capabilities = ["list", "read"]
}

EXPLICITLY gave it read/list permissions on secret/db/config

But when I go to /ui/vault/secrets/secret/show/db/config it tells me “You don’t have access to secret/.”

What!? That makes no sense! I give it DIRECT permissions on that very object.

I even tried this (which I should not have to do):

path "secret/*" {
  capabilities = ["list"]
}

path "secret/db/*" {
  capabilities = ["read"]
}

path "secret/db/config" {
  capabilities = ["list", "read"]
}

And I’m still denied permission.

The solution to this was pointed out here: Problem getting vault secrets in a Nomad job - #10 by Just-Insane

In short:

path "secret/*" {
  capabilities = ["list"]
}

path "secret/data/db/config" {
  capabilities = ["list", "read"]
}

Note the “data” in the path.

1 Like

Hey,

I noticed in your first message you mentioned “clicked”, so I’m making an assumption that you are using the UI, and possibly the “vault” cli - it is much more convenient.

I kept getting tripped up with the paths when implementing policies as well - I still do. I recommended you review the API’s. The policies map to the API’s, but the UI and CLI hid it from you. For example the kv-v2 path ( from the API ) starts at the “root” path - so in your case “secret”. It then splits into a few branches: config, data, metadata, delete, undelete, destroy. config holds the config information about the kv store itself, data holds the actual secrets, metadata holds the information about your data (in kv2, this is where version information is kept), delete/undelete are really action (post - or write/update) and destroy is also an action that removes everything about the data.

The CLI ( vault kv put secret/db password=test ) will make a call to secret/data/db - which is why you need the /data/ in the path.

The same for the UI - to show you the list of secrets, it needs the list permissions on that path.

I recommend you get comfortable reading the API - even though it is not straight forward if you are not use to HTTP C.R.U.D API’s.

1 Like

@alain Thank you. It was a long way around, but yes, I finally figured out the policies are bound to the API, while the UI is “disconnected” from the API, at least semantically.

This needs to be called out more in the docs. :slight_smile:

Thanks for the pointers!