Vault Policy Question

I am working with a vault dev server, and am attempting to make a policy for a kv-v2 secret engine. The policy must allow the user to list the (data field) key of a secret but not it’s value. Anyone know if that is possible?

Cheers
-winn

Unfortunately not. Policies are applied to a request, not a response. Because there is no KV-V2 parameter to only retrieve keys, I don’t think we can write a policy that permits retrieving only keys. The Vault policy language does permit required_parameters or denied_parameters, but there is not any parameter to a KV-V2 secret that does what you want.

You could break up the secret into multiple K/V secrets to achieve the same goal. Suppose you had the secret secret/data/credentials

username=mark password=foo tfa=12345

You could instead lay out the contents as three secrets:

secret/data/credentials/username value=mark (or even username=mark)
secret/data/credentials/password value=foo
secret/data/credentials/tfa tfa=12345

Then your policy could permit list on secret/data/credentials but not permit reads on any of the paths.

1 Like

Three more questions;

  1. Is there a kv-v1 parameter to retrieve only keys?
  2. is there a way to enforce the data key must match the path?
  3. Is there a way to retrieve the Value of the data using without specifying the Key data?

e.g.
secret in array form (easy for reading)

website = {Key: database-connection, Value: supersecret}

Possible code to retrieve secret

vault kv get product/website -field=Value

Actual secret

vault kv get product/website
====== Metadata ======
Key              Value
---              -----
created_time     2020-12-08T18:47:49.888816562Z
deletion_time    n/a
destroyed        false
version          1
=========== Data ===========
Key                    Value
---                    -----
database-connection    supersecret

Thanks again
-winn

K/V v1 does not give any additional functionality. There is really no control in the K/V store about portions of a secret or what is included in the response. The -field flag on the “kv get” command only affects output. You can find the complete API here: https://www.vaultproject.io/api-docs/secret/kv/kv-v2. The only parameter accepted by “read secret” is a version number.

You could write your own secret engine that provided additional functionality, if this was a key need for your application; it should be feasible to fork the kv-v2 implementation at https://github.com/hashicorp/vault-plugin-secrets-kv

You might be able to force a match between path and key using Sentinel (an enterprise feature) which allows you to write code using the Sentinel policy language. Sentinel policies can access both the data and the path of a request (see https://www.vaultproject.io/docs/enterprise/sentinel/properties) and so you could probably write an EGP policy that restricted the keys that were used in a K/V secret. I haven’t ever done so, however.

1 Like

Thank you so much again for your input.

To restate the goal here: I wish simply to restrict the decryption (READ) function to only those who need it. Mitigating any threat where a user’s account is compromised giving an attacker the ability to decrypt every secret the user has access to.

Would there be another secret engine type built into vault that can do this natively without creating our own engine or using Sentinel?

-winn

As mentioned previously with the k/v engine each path is treated as a single atomic unit.

Therefore you can only apply permissions on a per-path basis - a user can either see the contents (which is actually a JSON data structure) as a whole (keys and values) or not, as well as being able to adjust the whole structure or not.

It is possible that a user is able to list and see paths that they then can’t read.

So it should be totally possible to restrict access to paths the user doesn’t need to be able to see. If currently a path contains both values a user should see plus ones they should not, you would need to split it into multiple paths.

In general access permissions are based on the path rather than anything more granular. There are a few situations where required_parameters/denied_parameters can be used, but even with those the majority of the permissions are per-path (for example with most engines you’d need multiple roles [which are represented as paths] instead of being able to have a single one with required_parameters able to fully control granular access).

While you could create a custom engine to do anything you wanted, I’d recommend sticking with the standard k/v/ engine. Instead make sure you treat each path as a single unit, where all keys have access controlled together. Where there are existing paths which need different permissions per-key split that into multiple paths.

1 Like

Is it possible in the vault to create a policy to give read access only to some keys on a certain path? for eg.
on path secret/hello there are two key-value pair

  1. kibana-user : 12345
  2. aws-user : 23455
    I want to create a policy only to give access to kibana-user key-value pair and generate a token so by using the token the user will only get kibana-user credentials.