vault kv put: Usage, Options & Common CI Errors
Write or overwrite a secret in Vault’s key/value engine.
vault kv put writes a secret to the KV engine, creating a new version (KV v2). In CI you typically feed values from stdin or a file rather than the command line to keep them out of process listings and logs.
What it does
vault kv put <path> key=value writes the given keys to the KV path, replacing all existing keys at that path (KV v2 keeps prior versions). To merge rather than replace, use vault kv patch. Reading a value from stdin with key=- avoids exposing it in shell history or the process table.
Common usage
# Write a secret (replaces all keys at the path)
vault kv put secret/myapp/db username=app password=s3cr3t
# Read a value from stdin (key=-) to avoid leaking it
cat token.txt | vault kv put secret/myapp/api token=-
# Merge a single key without replacing others
vault kv patch secret/myapp/db rotated_at=2026-06-25Common error in CI: permission denied / check-and-set required
put fails with "permission denied" (policy lacks create/update on the path) or "check-and-set parameter required for this call" when the mount enforces CAS. Fix: grant the token create+update on <mount>/data/<path> and, when CAS is enabled, pass -cas=<current_version> (use -cas=0 to create only if absent). Prefer kv patch to update one key so you do not accidentally drop the others that kv put replaces.
Key options
| Option | Purpose |
|---|---|
| key=value | Set a key (replaces all keys) |
| key=- | Read the value from stdin |
| -cas=N | Check-and-set against version N |
| -mount=MOUNT | Specify the KV mount |
| patch | Merge keys instead of replacing |
Using this in CI
Cloud CLIs behave differently on a runner than on your laptop. They assume no interactive terminal, no cached credentials, and no browser for device-code flows, so the same command that works locally can hang or fail on a runner.
- Authenticate with a short-lived OIDC token rather than a long-lived static key. GitHub Actions can exchange
id-token: writefor cloud credentials with no stored secret. - Always pass the non-interactive flag. Most cloud CLIs will otherwise prompt and hang until the job times out.
- Pin the CLI version. Cloud CLIs change output formats between minor releases, and any script parsing that output will break silently.
- Set the output format explicitly (
--output json) rather than relying on the default, which can differ by version and configuration profile.