Reading secrets
Safe-by-default output, the two ways to reach one value, extracting a JSON field, and reading many paths in a single call.
Commands on this page: get · bulk-get
On an interactive terminal get prints a masked preview (pv••••••t (41 chars)). Piped output stays
raw, so scripts keep working unchanged. Pass --reveal (alias --full-text, short -r) to print the
full value, or --copy to put it on the clipboard without ever showing it.
That rule in full — the behaviour depends on where the output is going, which is what makes it safe without making it annoying:
| Situation | What you get |
|---|---|
| Interactive terminal, no flags | Masked preview + a hint naming the version |
Terminal + --reveal / --full-text |
Full value, and a scrollback warning naming the version |
Terminal + --copy |
Clipboard only — nothing sensitive on screen |
| Piped or redirected | Raw value, no newline, no warning |
-o json |
Full record including the value and versionNumber |
pulsvault get acme-web/prod/product/web/db/password # masked preview
pulsvault get acme-web/prod/product/web/db/password --reveal # full plaintext
pulsvault get acme-web/prod/product/web/db/password | psql … # piped → raw value
export DB=$(pulsvault get acme-web/prod/product/web/db/password)The piped form is why $( … ) works without any flag: the CLI detects that stdout is not a terminal and
emits the raw value with no trailing newline.
Two ways to reach one value#
Name the full path, or name the folder and pick the entry. They are equivalent, so a path copied from the console works either way:
pulsvault get acme-web/prod/product/web/postgres/url # by path
pulsvault get acme-web/prod/product/web/postgres --field url # by entryOn a JSON secret, --field extracts one key instead:
$ pulsvault get acme-web/prod/product/web/db/creds --field username
ad••••••n (7 chars)
hint: v2 (current) — value masked; pass --reveal (or --full-text) to print it, or --copy to copy it
$ pulsvault get acme-web/prod/product/web/db/creds --field username --full-text
adminBoth readings obey the same masking rules, and there is no ambiguity between them: a path is either a
folder or a secret, never both, so a folder has no JSON value for --field to index into. See
the branch-or-leaf rule.
get <folder> --field creds returns the whole creds secret. To then pull one key out of it, chain the
path: get <folder>/creds --field username.
Which version am I holding?#
Every read says so. There is no flag for asking — reading the secret tells you:
$ pulsvault get acme-web/prod/product/web/db/password
pv••••••t (41 chars)
hint: v3 (current) — value masked; pass --reveal (or --full-text) to print it, or --copy to copy it(current) means the server chose the version for you, so it is the newest by definition. That line
goes to stderr and is skipped entirely when the output is piped or -o json, so $( … ) is
unaffected and no script sees it.
To see every key's version at once without reading any value, use
list — the v2 column there is each secret's current version.
Reading an older version#
--version N reads a specific one. It selects a version; it does not ask what the version is:
$ pulsvault get acme-web/prod/product/web/db/password --version 1
ol••••••d (33 chars)
hint: v1 (pinned) — value masked; pass --reveal (or --full-text) to print it, or --copy to copy itIt means you chose this version rather than letting the server pick, so do not assume it is the
latest. The CLI deliberately does not claim otherwise: a single read returns only the version you
asked for, and checking whether a newer one exists would cost a second read in your audit log to
produce a hint. When you need to know, versions answers it
properly.
Version history and how to compare or restore one is covered in Versions & rotation.
Many paths in one call#
bulk-get reads up to 100 paths per request and chunks automatically beyond that — one round trip
instead of N, and one audit entry for the whole logical operation:
pulsvault bulk-get acme-web/prod/product/web/db/password \
acme-web/prod/product/web/api/key
pulsvault bulk-get -f paths.txt -o json-f/--file reads newline-separated paths from a file, which is the practical form in CI. Values are
masked unless --reveal, exactly as with get.
To load an entire namespace or folder as environment variables rather than naming paths individually,
use export or run — they are built for that and never write values to
disk.
When the path is not a secret#
Naming a container instead of a secret is a common slip, especially with a path pasted from the explorer. It says so, rather than failing obscurely:
$ pulsvault get acme-web/prod/product/web/postgres
error: acme-web/prod/product/web/postgres is a folder, not a secret — list what it holds with `pulsvault list acme-web/prod/product/web/postgres`The same applies to a namespace. Both point you at list, which is almost always what you wanted next.
Related#
- Finding secrets — locating a path first
- Using in CI — loading many values into a process
- Command reference — exact flags