Only allow listing specific Secrets

Hey,

I created several Database Engines with paths like:

mysql/dev/my-instance-1
mysql/staging/my-instance-2
mysql/prod/my-instance-3

Now I want to configure a Policy which allows Users only to list a specific path via vault secrets list.
For example here without prod:

vault secrets list
Path                                                                   Type         Accessor              Description
----                                                                   ----         --------              -----------
mysql/dev/my-instance-1 [...]
mysql/staging/my-instance-2 [...]

I am currently only able to allow access to list all secrets which is in my case way too permissive:

path "sys/mounts" {
  capabilities = ["list", "read"]
}

Hi,

Then you want an acl policy that’s something like:

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

create that policy and attach to to your user/auth method

Hey,

I removed now the sys/mounts policy and attached a new Policy to my User with your example, then I still receive a error:

Error listing secrets engines: Error making API request.

URL: GET https://my.vault.example.com/v1/sys/mounts
Code: 403. Errors:

* 1 error occurred:
	* permission denied

So my User now has only the Default and my custom Policy attached with:

path "mysql/dev/*" {
  capabilities = ["list"]
}

As per your error message, it looks like you’re trying to list secret engines.

If you’re trying to list (I’m assuming key-value) secrets, it’d be something like:

vault kv list mysql/dev/path/to/secret

Yeah I would like to list secret engines and not key-value secrets.
I am using the Database Engines to dynamically create credentials for the MySQL instances.
For that I would like to allow a User to list his available set of secret engines, but not all of them.

I see…

I misunderstood your initial question, but for what you’re asking for exactly, I’m afraid that’s not possible. What I might recommend instead is to create a separate policy for each environment/endpoint that that user would be reading from to get a dynamic credential:

i.e. (for db engine secrets path: mysql/dev/my-instance-1/)

path "mysql/dev/my-instance-1/creds/myrole" {
  capabilities = ["list", "read"]
}

i.e. (for db engine secrets path: mysql/staging/my-instance-2/)

path "mysql/staging/my-instance-2/creds/myrole" {
  capabilities = ["list", "read"]
}

etc. (as you’re going to have 1 DB secrets engine mount for each of your DBs) and name those policies accordingly:

i.e.

  • db-dev-my-instance-1
  • db-staging-my-instance-2
  • etc.

You can then attach those individual policies to your users/DBAs and after they auth to Vault, they can run:

vault token lookup

and get an output similar to the following:

Key                 Value
---                 -----
accessor            IBgtEgKe3FoLVHfIvXaxVdYe
creation_time       1632762020
creation_ttl        768h
display_name        userpass-testuser
entity_id           949f08f3-6d39-c23b-040c-4b6d124d79b5
expire_time         2021-10-29T13:00:20.648943591-04:00
explicit_max_ttl    0s
id                  s.v1fdpO0CYxwfMJAqdQjGAcAd
issue_time          2021-09-27T13:00:20.648976628-04:00
meta                map[username:testuser]
num_uses            0
orphan              true
path                auth/userpass/login/testuser
policies            [default db-staging-my-instance-2]
renewable           true
ttl                 767h57m24s
type                service

With the main takeaway being the policies, so they can look at the policy name and determine what dynamic secrets they can generate.

1 Like

Thanks for your input. I have to admit that both solutions are not really helpful for my use case, but that it’s currently not achievable how I would love to see it.