Vaultic
Command Line

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

FlagDescription
-e, --env <environment>Environment to list
--revealShow real values instead of masked
--jsonMachine-readable output

secrets get

secrets get <key>
FlagDescription
-e, --env <environment>
--revealShow the real value instead of masked
--jsonMachine-readable output
--previousFetch the pre-rotation value instead of the current one — see Rotation providers

secrets set

secrets set <key> [value]

Creates or updates a secret.

FlagDescription
-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-expiryRemove this secret's expiry date
--clear-remindRemove 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 restricted

Reading 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-remind

If 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>
FlagDescription
-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>
FlagDescription
-e, --env <environment>
--reveal

Every write is a new version; this lists them all.

secrets rollback

secrets rollback <key>
FlagDescription
--version <version>Required — the version to roll back to
-e, --env <environment>

secrets rename

secrets rename <oldKey> <newKey>
FlagDescription
-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.

FlagDescription
-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.

FlagDescription
-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.

FlagDescription
--from-file <path>Read the value to search for from a file
--jsonMachine-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.

FlagDescription
-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

DirectiveBehavior
{{.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.

On this page