Secrets
vaultic secrets — the core read/write command group.
vaultic secrets <subcommand> is the core read/write surface. Values are masked
(•••••••• + last 4 chars) everywhere except --reveal, which is audited as its own event
separate from list/read — except where a secret's own
visibility overrides that:
unmasked secrets always print their real value, and restricted secrets never do (they print
[RESTRICTED] in table output, null in --json, and --reveal fails with a 403 for a
logged-in session — only a service token can retrieve them).
secrets list
| Flag | Description |
|---|---|
-e, --env <environment> | Environment to list |
--reveal | Show real values instead of masked |
--json | Machine-readable output |
secrets get
secrets get <key>| Flag | Description |
|---|---|
-e, --env <environment> | |
--reveal | Show the real value instead of masked |
--json | Machine-readable output |
--previous | Fetch the pre-rotation value instead of the current one — see Rotation providers |
secrets set
secrets set <key> [value]Creates or updates a secret.
| Flag | Description |
|---|---|
-e, --env <environment> | |
--from-file <path> | Read the value from a file |
--expires-in <duration> | Set expiry relative to now, e.g. 90d, 12h |
--expires-at <date> | Set an absolute expiry date |
--remind-every <duration> | Set a rotation-reminder cadence, e.g. 30d |
--clear-expiry | Remove this secret's expiry date |
--clear-remind | Remove this secret's rotation reminder |
--visibility <tier> | masked (default) | unmasked | restricted — see Visibility |
vaultic secrets set STRIPE_KEY sk_live_xxx --expires-in 90d --remind-every 30d
vaultic secrets set SIGNING_KEY sk_xxx --visibility restrictedReading the value from stdin
Pass - as value, or pipe input and omit value entirely, to read the secret from stdin
instead of argv — keeps it out of shell history and process listings:
cat tls_cert.pem | vaultic secrets set TLS_CERT
echo "$SECRET" | vaultic secrets set STRIPE_KEY -Interactive mode
Omitting value in an interactive terminal (no pipe, no --expires-*/--remind-every flags)
instead drops you into a prompt. Type the value and finish with a line containing only .:
$ vaultic secrets set API_KEY
Enter your secret value
When finished, type a newline followed by a period
Run 'vaultic secrets set --help' for more information
———————————————————— START INPUT ————————————————————
0ffb75cc-61fa-445a-84ea-941ac976e633
.
————————————————————— END INPUT —————————————————————Metadata-only update
Omit value and pass one of --expires-in/--expires-at/--remind-every/--clear-expiry/
--clear-remind to update that metadata without touching the stored value:
vaultic secrets set STRIPE_KEY --clear-expiry --clear-remindIf the target environment is locked, set creates a pending change proposal instead of
applying immediately — see env lock and
env proposals.
secrets delete
secrets delete <key>| Flag | Description |
|---|---|
-e, --env <environment> |
Same locked-environment → pending-proposal behavior as set. Deleted secrets go to a 30-day
trash, restorable from the web app.
secrets history
secrets history <key>| Flag | Description |
|---|---|
-e, --env <environment> | |
--reveal |
Every write is a new version; this lists them all.
secrets rollback
secrets rollback <key>| Flag | Description |
|---|---|
--version <version> | Required — the version to roll back to |
-e, --env <environment> |
secrets rename
secrets rename <oldKey> <newKey>| Flag | Description |
|---|---|
-e, --env <environment> |
secrets rotate
secrets rotate <key> [value]Sets a new value while keeping the old one fetchable via secrets get KEY --previous during an
optional grace window. Pass - as value to read from stdin, or omit value entirely when
using --provider to have a rotation plugin compute it. See
Rotation providers for the full provider docs.
| Flag | Description |
|---|---|
-e, --env <environment> | |
--from-file <path> | Read the new value from a file |
--grace <duration> | How long the previous value stays fetchable, e.g. 1h, 30m (omit = fetchable indefinitely) |
--provider <name> | Compute the new value via a rotation plugin — run vaultic rotation-providers to list them |
--role <role> | (postgres/mysql/redis) Role/user to rotate — defaults to the connection string's user |
--admin-conn-string <url> | (postgres/mysql/redis) Connect with different credentials than the value being rotated |
--new-password <password> | (postgres/mysql/redis) Use this password instead of a random one |
--option <key=value> | Extra provider-specific option (repeatable) — e.g. --option host=% (mysql), --option endpoint=... (generic-webhook), --option gitlabUrl=... (gitlab) |
A secret.rotated webhook always fires on rotation, regardless of --grace.
secrets override set / secrets override clear
secrets override set <key> [value]
secrets override clear <key>Personal, server-side value overrides — visible only to you, never to teammates or service
tokens. Service-token reads (export/run, as used by deploys and CI) never consult overrides
at all.
| Flag | Description |
|---|---|
-e, --env <environment> | |
--from-file <path> | (set only) |
secrets search-by-value
secrets search-by-value [value]Finds every secret in the whole workspace — any project, any environment you have access to,
not just the one selected with -e — whose current value exactly matches value. Unlike every
other secrets subcommand, this isn't scoped to one environment, since a value can live anywhere.
Prints project/environment KEY for each match, or a message if nothing matches.
| Flag | Description |
|---|---|
--from-file <path> | Read the value to search for from a file |
--json | Machine-readable output |
vaultic secrets search-by-value "sk_live_xxx"
vaultic secrets search-by-value --from-file ./leaked-key.txt
echo -n "sk_live_xxx" | vaultic secrets search-by-value -Matching is exact (whitespace included), computed server-side via a keyed hash — the server never
decrypts a secret to check it, and the response never contains anyone's value, only which
project/environment/key matched. See Secrets Health → Search by Value
for the full design notes, including why
restricted secrets never show
up as a match.
secrets substitute
secrets substitute [template]Renders a template file — or stdin, if [template] is omitted — against this environment's
secrets and prints the result to stdout (or writes it to --output). Unlike export, which
only produces flat KEY=value-style files, substitute fills secrets into an arbitrary text
file: a Kubernetes manifest, an nginx config, anything with placeholders in it.
| Flag | Description |
|---|---|
-e, --env <environment> | |
-o, --output <path> | Write rendered output to a file instead of stdout |
vaultic secrets substitute config.tmpl.yaml --output config.yaml
kubectl apply -f <(vaultic secrets substitute k8s-secret.tmpl.yaml)Template syntax
| Directive | Behavior |
|---|---|
{{.NAME}} | Substitutes the secret NAME. Required — fails the whole render (naming every missing key) if NAME doesn't exist in this environment. |
{{/* comment */}} | Stripped from the output. |
{{with .NAME}}...{{end}} | Renders the block only if NAME exists and is non-empty; otherwise skips it. Use this for optional secrets instead of a bare {{.NAME}}. Inside the block, {{.}} is NAME's value. |
{{tojson .NAME}} | JSON-encodes NAME's raw value onto a single escaped line — for dropping a multiline secret (a PEM key, a cert) into a JSON/YAML value. |
{{with fromjson .NAME}}...{{end}} | Parses NAME as JSON and binds it as . inside the block, so {{.field}} reads a property of it. Skipped (not an error) if NAME is missing or isn't set. |
# config.tmpl.yaml
host: {{.DB_HOST}}
private_key: {{tojson .TLS_PRIVATE_KEY}}
{{with .LOG_FILE}}
logging:
file: {{.}}
{{end}}
{{with fromjson .S3_CREDENTIALS}}
s3:
access_key: {{.accessKeyId}}
secret_key: {{.secretAccessKey}}
{{end}}A direct {{.NAME}} reference is required — Vaultic fails loudly rather than silently emitting
a blank value, since a missing secret in a rendered config file is usually a bug. Wrap the
reference in {{with .NAME}}...{{end}} for any secret that's genuinely optional.
vaultic rotation-providers
Top-level command (not under secrets) — lists available secrets rotate --provider plugins
and their descriptions. No options.