vault
vault copied to clipboard
The required_parameters Constraint is Applied on Operations that don't Take Parameters
Describe the bug
When a policy which grants the create
, read
, update
, and delete
capabilities, but also includes a required_parameters constraint is applied for a path. All requests, including read
and delete
must include the required parameters.
To Reproduce Steps to reproduce the behavior:
- Set up the policy file
$ echo 'path "ssh/roles/*" {
capabilities = [ "create", "read", "update", "delete" ]
required_parameters = [ "max_ttl" ]
allowed_parameters = {
"max_ttl" = [ "60m0s" ]
}
}' > my-policy.hcl
- Launch Vault
$ docker run -d --name vault -v $PWD/my-policy.hcl:/my-policy.hcl -e VAULT_TOKEN=root -e VAULT_ADDR=http://127.0.0.1:8200 vault:latest vault server -dev -dev-root-token-id=root
b4e70524e7485bc10be2a611581e9c2f1469532eea63f72a957b6a90530dd7ba
- Mount a KV secrets engine at the path
ssh
$ docker exec vault vault secrets enable -path=ssh kv
Success! Enabled the kv secrets engine at: ssh/
- Write the policy
$ docker exec vault vault policy write my-policy /my-policy.hcl
Success! Uploaded policy: my-policy
- Create a token that has the policy assigned
docker exec vault vault token create -id=token -policy=my-policy
Key Value
--- -----
token token
token_accessor 1CKMLi0nFBJUqioWc9HUaeLj
token_duration 768h
token_renewable true
token_policies ["default" "my-policy"]
identity_policies []
policies ["default" "my-policy"]
- Attempt to read the path
ssh/roles/any
, which is covered by the policy in place
$ docker exec -e VAULT_TOKEN=token vault vault read ssh/roles/any
Error reading ssh/roles/any: Error making API request.
URL: GET http://127.0.0.1:8200/v1/ssh/roles/any
Code: 403. Errors:
* 1 error occurred:
* permission denied
- By including the required parameter
max_ttl
parameter, the request is allowed.
$ docker exec -e VAULT_TOKEN=token vault vault read ssh/roles/any max_ttl=60m0s
No value found at ssh/roles/any
Expected behavior I expected the result of step 6 (above) to be exactly the same as step 7.
Environment:
- Vault Server Version (retrieve with
vault status
):
$ docker exec vault vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 0.11.3
Cluster Name vault-cluster-d3a57a56
Cluster ID e1de44ab-ce64-05d0-4c29-761a4303a45a
HA Enabled false
- Vault CLI Version (retrieve with
vault version
):
$ docker exec vault vault version
Vault v0.11.3 ('fb601237bfbe4bc16ff679f642248ee8a86e627b')
- Server Operating System/Architecture:
$ docker exec vault uname -a
Linux b4e70524e748 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 Linux
$ docker version
Client: Docker Engine - Community
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:47:43 2018
OS/Arch: darwin/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:55:00 2018
OS/Arch: linux/amd64
Experimental: true
$ uname -a
Darwin [hostname] 18.2.0 Darwin Kernel Version 18.2.0: Fri Oct 5 19:41:49 PDT 2018; root:xnu-4903.221.2~2/RELEASE_X86_64 x86_64
Vault server configuration file(s): Used default configuration for Server in dev mode.
Additional context I understand why the request results in a permission denied error. But it seems counter-intuitive that a parameter constraint would be applied to requests that do not take parameters.
I discovered this behaviour when trying to put together a policy that allows operators in charge of administering the instance of the ssh secrets backend. I wanted to have a policy that allows them to create, review, and remove roles, hence the ssh/roles/*
, all the while being assured that no roles are created with a max_ttl other than 60m0s
.
I tried creating two separate rules in the policy, with the same path. One that grants read
and delete
capabilities; and the other that grants create
and update
and has the same constraints as described in the above test case. But that doesn't work because one rule simply supersedes the other.