Closed thomasd- closed 4 years ago
I think the problem here is the trailing glob on line 1 of your policy is confusing the ACL system. If you change your policy to:
path "secrets/" {
capabilities = [ "list" ]
}
path "secrets/+/prefix-*" {
capabilities = [ "create", "update", "delete" ]
}
then everything works, and your script provides the output that you expected to see.
At the end of the docs on policy syntax, it mentions:
When providing
list
capability, it is important to note that since listing always operates on a prefix, policies must operate on a prefix because Vault will sanitize request paths to be prefixes. In other words, policy paths targetinglist
capability should end with a trailing slash.
I'm guessing that's what caused this problem. I'm going to close this issue for now, since I don't think there's much for us to do here, but feel free to reopen it if necessary with additional information.
Thanks!
Thanks for your quick response, but I'm afraid this is not enough.
The list policy is needed, I need to be able to list any folders and sub-folders under /secrets, your solution does block this.
The same documentation page you linked states :
Policy paths are matched using the most specific path match. This may be an exact match or the longest-prefix match of a glob.
It is clear for me that secrets/+/prefix-*
is more specific than secrets/*
and that you have a bug in your prefix resolution.
Please re-open this bug and investigate.
Note : I have updated the test script to add a vault list command.
And here is an aternative test script that does not use the list capability
#!/bin/bash
vault server -dev > vault.log 2>&1 &
VAULT_PID=$!
sleep 2
export VAULT_ADDR=http://127.0.0.1:8200
vault secrets enable -version=1 -path=secrets kv
vault policy write prefix-writer <(echo '
path "secrets/*" {
capabilities = [ "deny" ]
}
path "secrets/+/prefix-*" {
capabilities = [ "create", "update", "delete" ]
}
')
token=$(vault token create -policy=prefix-writer -format=json | jq -r '.auth.client_token')
vault login -no-print "$token"
vault write secrets/alice/prefix-test value="Hello world!"
vault write sys/capabilities-self paths="secrets/alice/prefix-test"
kill "$VAULT_PID"
And the result :
Success! Enabled the kv secrets engine at: secrets/
Success! Uploaded policy: prefix-writer
Error writing data to secrets/alice/prefix-test: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/secrets/alice/prefix-test
Code: 403. Errors:
* 1 error occurred:
* permission denied
Key Value
--- -----
capabilities [deny]
secrets/alice/prefix-test [deny]
@thomasd- Thank you for the additional details. In digging into this further, I've found a few things:
secrets/+/prefix-*
is getting marked as lower priority than secrets/*
because of the +
. Generally speaking, if one path has more +
than another path, the one with more +
is lower priority.I'm going to leave this issue closed because we're tracking this work internally already, but I really appreciate you taking the time to write up your findings. The bash scripts in particular made reproduction of the problem a breeze. Thanks again!
Edit: Nevermind, got it wrong the first time, here's the correct rule application:
According to the documentation on priority matching for the two paths:
secrets/*
secrets/+/prefix-*
we have:
+
or *
) at the same place, so this rule does not apply --> go to next rule*
, rule does not apply --> go to next rule+
wildcard segments --> P2 is of lower priority, P1 is appliedHowever, I have observed that something with priority matching is still fishy. I have the two path with Vault v1.15.4:
ssh/*
--> list, readssh/*/qa
--> list, read, updatewhere according to docs:
+
or *
) at the same place, so this rule does not apply --> go to next rule*
, so it should have lower priority, P2 should get appliedyet it seems that P1 is applied in my case. I cannot update ssh/roles/qa
.
Edit: Nevermind, got it wrong the first time, here's the correct rule application:
According to the documentation on priority matching for the two paths:
- P1:
secrets/*
- P2:
secrets/+/prefix-*
we have:
- Rule one: P1 and P2 have their earliest wildcard (
+
or*
) at the same place, so this rule does not apply --> go to next rule- Rule two: both paths end in
*
, rule does not apply --> go to next rule- Rule three: P2 has more
+
wildcard segments --> P2 is of lower priority, P1 is appliedHowever, I have observed that something with priority matching is still fishy. I have the two path with Vault v1.15.4:
- P1:
ssh/*
--> list, read- P2:
ssh/*/qa
--> list, read, updatewhere according to docs:
- Rule one: P1 and P2 have their earliest wildcard (
+
or*
) at the same place, so this rule does not apply --> go to next rule- Rule two: P1 ends in
*
, so it should have lower priority, P2 should get appliedyet it seems that P1 is applied in my case. I cannot update
ssh/roles/qa
.
Would you be willing to open a new issue for the documentation? I hesitate to resurface this one because the context is so old. Thanks!
Describe the bug A token is associated with a policy that defines two paths : /secrets/ (list only) and /secrets/+/prefix- (write only). When trying to write a secret to /secrets/alice/prefix-test, we get a permission denied.
The capabilities retained for this is path is list only. The doc says that the most specific path should have priority when resolving capabilities, so the capabilities for /secrets/+/prefix- should be used, not /secrets/
To Reproduce Run the following script:
You get the following output :
Expected behavior I expeted the vault write command to succeed and the sys/capabilitites-self to return permissions [write,update,delete] for secrets/alice/prefix-test. Then the vault list command should show the prefix-test key in secrets/alice
Environment:
vault status
): Vault v1.5.4 (1a730771ec70149293efe91e1d283b10d255c6d1)vault version
): Vault v1.5.4 (1a730771ec70149293efe91e1d283b10d255c6d1)Vault server configuration file(s): see self-contained test script
Additional context Add any other context about the problem here.