Skip to content

Commit 58aeb56

Browse files
authored
vault_client: add support to 'vault kv get' for the vault_client (#642)
This commit adds support to 'vault kv get' for the 'vault_client' extension to make the consumption of secrets from Vault K/V version 2 convenient. There is a difference in the JSON structure of K/V version 1 (a.k.a 'generic') and K/V version 2 responses returned when reading secrets. Version 1 ``` { "auth": null, "data": { "foo": "bar", "ttl": "1h" }, "lease_duration": 3600, "lease_id": "", "renewable": false } ``` Version 2 ``` { "data": { "data": { "foo": "bar" }, "metadata": { "created_time": "2018-03-22T02:24:06.945319214Z", "custom_metadata": { "owner": "jdoe", "mission_critical": "false" }, "deletion_time": "", "destroyed": false, "version": 2 } } } ``` Note the nested 'data.data' in version 2's response. This difference makes the usability of 'vault read' impractical for version 2 secrets when compared to 'vault kv get'. As 'vault kv get' knows how to unwrap the nested 'data' blocks, we can access the values of secrets directly. ``` vault kv get -mount=<MY-MOUNT> -field=<MY-FIELD> <MY-PATH> <MY-SECRET-VALUE> ``` However, when reading the same secret with 'vault read', we get the following structure. ``` ❯ vault read <MY-MOUNT>/data/<MY-PATH> Key Value --- ----- data map[<MY-FIELD>:<MY-SECRET-VALUE>] metadata map[created_time:2025-08-06T13:23:08.155132764Z custom_metadata:<nil> deletion_time: destroyed:false version:2] ❯ vault read -field=data <MY-MOUNT>/data/<MY-PATH> map[<MY-FIELD>:<MY-SECRET-VALUE>] ``` To be able to the the actual value of '<MY-SECRET-VALUE>' we need to parse the output from 'vault read' and that's far from being convenient. References: * https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#sample-response-1 * https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v1#sample-response Signed-off-by: Diogo Kiss <[email protected]>
1 parent c9b1032 commit 58aeb56

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ All extensions have been vetted and approved by the Tilt team.
5959
- [`tests`](/tests): Some common configurations for running your tests in Tilt.
6060
- [`tilt_inspector`](/tilt_inspector): Debugging server for exploring internal Tilt state.
6161
- [`uibutton`](/uibutton): Customize your Tilt dashboard with [buttons to run a command](https://blog.tilt.dev/2021/06/21/uibutton.html).
62-
- [`vault_client`](/vault_client): Reach secrets from a Vault instance.
62+
- [`vault_client`](/vault_client): Retrieve secrets from a Vault instance.
6363
- [`wait_for_it`](/wait_for_it): Wait until command output is equal to given output.
6464
- [`base64`](/base64): Base64 encode or decode a string.
6565
- [`yarn`](/yarn): Create Tilt resources from package.json scripts in a yarn workspace.

vault_client/README.md

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,46 @@
22

33
Author: [Ismael Fernandez](https://github.com/ismferd)
44

5-
The purpose of this extension is to easily fetch secrets from a [Vault](https://www.vaultproject.io/) instance
5+
Contributors:
66

7-
You will be able to reach vault and get your secrets using a token
7+
- [Diogo Kiss](https://github.com/diogokiss)
8+
9+
The purpose of this extension is to easily fetch secrets from a [Vault](https://www.vaultproject.io/) instance.
10+
11+
It allows you to reach Vault and read your secrets using a Vault token.
812

913
## Requirements
1014

11-
- `Vault cli`
15+
- [Vault CLI](https://developer.hashicorp.com/vault/install)
1216

1317
## Functions
1418

1519
### `vault_set_env_vars(vault_addr: str, vault_token: str)`
1620

17-
Set up the `VAULT_ADDR`and the `VAULT_TOKEN` as envvars.
21+
Set up the `VAULT_ADDR` and `VAULT_TOKEN` environment variables.
1822

1923
### `vault_read_secret(path: str, field: str) return str`
2024

21-
Return the value of your secret.
25+
> [!IMPORTANT]
26+
> This function is not recommended for use with Vault's KV secrets engine version 2.
27+
28+
Return the value of the secret field specified by the given `path` and `field`.
29+
This function is a wrapper around the `vault read` command.
30+
31+
### `vault_kv_get(path, field, mount=None) return str`
2232

23-
Under the hood, it is doing te command `vault read -field=$fiel $path"`
33+
> [!IMPORTANT]
34+
> Prefer this function if you are using Vault's KV secrets engine.
35+
> In particular, if you are using K/V version 2.
36+
37+
Return the value of the secret field specified by the given `field`, `path`, and `mount`.
38+
This function is a wrapper around the `vault kv get` command.
2439

2540
## Example Usage
2641

27-
```
28-
load('ext://vault_client', 'vault_read_secret', 'vault_set_env_vars')
42+
```python
43+
load('ext://vault_client', 'vault_read_secret', 'vault_set_env_vars', 'vault_kv_get')
2944
vault_set_env_vars('https://localhost:8200','mytoken')
30-
my_foo = vault_read_secret('path/myfoo', 'value')
31-
my_bar = vault_read_secret('path/mybar', 'foobar')
45+
my_foo = vault_read_secret('path/myfoo', 'secret')
46+
my_bar = vault_kv_get('path/mybar', 'secret', mount='mymount')
3247
```
33-

vault_client/Tiltfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
def vault_read_secret(path, field):
22
return local("vault read -field={} {}".format(field, path), quiet=True)
33

4+
def vault_kv_get(path, field, mount=None):
5+
mount_param = "-mount={}".format(mount) if mount else ""
6+
return local("vault kv get {} -field={} {}".format(mount_param, field, path), quiet=True)
7+
48
def vault_set_env_vars(vault_addr, vault_token):
59
os.putenv('VAULT_ADDR', vault_addr)
610
os.putenv('VAULT_TOKEN', vault_token)

0 commit comments

Comments
 (0)