Skip to content
Solo ProTeamBusinessEnterprise

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

Values are masked on a terminal

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
bash
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:

bash
pulsvault get acme-web/prod/product/web/postgres/url             # by path
pulsvault get acme-web/prod/product/web/postgres --field url     # by entry

On a JSON secret, --field extracts one key instead:

bash
$ 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
admin

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

`--field` on a folder is spent selecting the secret

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:

text
$ 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:

text
$ 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 it
`(pinned)` does not mean stale

It 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:

bash
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:

text
$ 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.

Was this page helpful?