Browsing secrets & folders
The drill-down path browser, nested folders, and the List ⇄ JSON view that lets you read or edit every secret at a path as one document.
A namespace is not a flat list. Secrets live in folders, and the console browses them the way a file manager does — one level at a time.
Open a namespace and choose Manage secrets → to enter the browser. The current folder is in the URL, so any path can be bookmarked, shared with a colleague, or opened straight from a runbook.
Finding a path#
The browser has two panes. On the left is the folder tree. On the right is the folder you have open, with its sub-folders and the secrets it holds directly.
- The folder tree shows folders only. Expand a folder to see the folders inside it. The number beside a folder counts the secrets directly in it, not those in its sub-folders. When you open a bookmarked path, the tree expands down to it. You can use the keyboard: ↑ and ↓ move, → expands and ← collapses, and Enter opens the folder.
- Go to path… sits above the tree. Type the start of a folder path, such as
prod/pay, then pick a match to jump there. It suggests folders, not individual keys. - Long folders load in pages. A folder with many sub-folders or secrets shows the first page. Load more at the end of the list fetches the next page.
On a narrow screen the tree moves into a Folders panel, opened from the button beside the breadcrumb.
Some actions need every key in the folder, not just the first page: Use this path, the masked JSON view and the duplicate-name check when you add keys. These wait until the whole folder has loaded. You never get a command or a pipeline block built from part of a folder.
Folders#
A folder is a real object, not just a naming convention in a path. That means you can create an empty folder before you have anything to put in it, and it stays where you left it.
- Folders nest:
db/replica/credentialsis three levels under the namespace. - Renaming or moving a folder brings its secrets with it. Because every value is bound to its full path, this decrypts and re-encrypts each affected secret, so the engine must be unsealed.
- Version history survives a rename — you do not lose the audit trail by reorganising.
Every secret must sit inside a folder; you cannot store a value directly at the namespace root. See Paths, plans & roles for that rule and the depth limits, and for why a path is either a folder or a secret but never both.
The List ⇄ JSON view#
At any path you can flip between two views of the same data:
- List — one row per secret, with its version and validation badge.
- JSON — every secret at that path as a single JSON document.
The JSON view is the fast way to read a whole credential set at once, or to author several related values together instead of clicking through a form per key.
The JSON view opens masked. Revealing is a deliberate, re-authenticated action, and the revealed values are wiped from the screen automatically after a short window — so an unlocked laptop does not leave production credentials on display. Each reveal is recorded in the audit log.
Adding and editing in the List view#
Add and Edit are the same form, opened in place under the breadcrumb rather than in a dialog over the table. Add starts with one empty row and + Add another appends more, so a credential set goes in as one atomic write instead of one form per key. Edit opens that same form on a single row, with the key locked and the current value and format already loaded.
The key is fixed once a secret exists because the value is encrypted against its full path — a rename is a re-encryption, which is why it belongs to Path settings and not to an edit box. To change a name here, add the new key and delete the old one.
Filling the box with the current value means decrypting it, so Edit re-authenticates exactly as Reveal does, is audited the same way, and puts what it loaded on the same auto-hide clock — the form closes with the rest of the plaintext when the window runs out. If values are already revealed, Edit reuses that window instead of asking twice.
Reveal and write are separate permissions. With permission to write but not to reveal, the form still opens — with an empty box and a note saying that whatever you save replaces the current value.
Saving writes a new version under the version the form loaded. If someone else wrote to that key in between, the save is refused rather than applied over their change, and you are told to reopen it.
Editing as JSON#
Edit the document and the Save button tells you which of two things it will do.
Adding keys saves directly. Authoring a path for the first time, or dropping a new key into an existing one, writes nothing over and deletes nothing — there is no diff worth reading, so you go straight to the password prompt.
Overwriting or removing a key says "Verify changes" instead. That opens a review panel above the editor listing what was added, changed, and removed, with removals called out — they soft-delete the secret, recoverable from history. The editor stays open beside it, so you can answer "is this removal right?" by looking at the JSON rather than at a summary of it. Keep typing and the review updates as you go; Keep editing dismisses it without undoing anything.
That step exists because a JSON edit is a blunt instrument: deleting two lines deletes two secrets. Restricting it to the saves that actually destroy something is what keeps it worth reading — a confirmation shown every time is one people learn to click through.
Saving applies the whole document atomically: either every change lands, or none does. You will never get a half-applied edit that leaves one credential rotated and its partner stale.
Clearing a value to "" forces the review panel, which lists those keys under Will be stored empty
behind a tick confirming you mean it. Deleting the value while keeping the key is almost always a
slip, and in this view one slip overwrites a live credential with nothing — so it is never something
you do by not noticing.
This is the same opt-in as the List view's Store an empty value on purpose checkbox and the CLI's
--allow-empty; a JSON document just has no row to hang a checkbox on, so the review panel asks
instead. It travels per key, so consenting to one blank value never lets another through in the
same save, and introducing a second blank key un-ticks it and asks again.
The panel reads the changes, not the document, so a secret that is already deliberately empty still
shows as "key": "" and its folder saves without a word about it — an untouched key is not a change.
Typing "" into a Text value box does not store an empty value — it stores two quote characters,
and the application that reads the secret gets both. So a value wrapped in quotes, or padded with
spaces, raises a Store it exactly as typed checkbox under its row and holds the save until you
tick it.
Switch the row's format to Number/JSON and the quotes stop being characters and become syntax:
there "s3cr3t" really is the string s3cr3t, so no checkbox appears — but "" is then genuinely an
empty value and gets the Store an empty value on purpose tick instead, and null is refused
outright, because deleting the key is how you have no secret.
Nothing is stripped or refused. "s3cr3t" is a real password if that is genuinely the password, and a
form that quietly removed the quotes would store something other than what you typed. The checkbox
only makes sure the two of you agree about which one you meant.
Same rule per row, and cleared whenever you edit the value, so consent always belongs to the characters actually on screen. Editing an existing secret says nothing until you change its value — a value that was already stored this way was agreed to when it was written.
The CLI warns about the same three shapes when you type a value at a terminal; see Writing secrets.
A key is a path segment, so it is lowercase a–z, digits, _, . and - — MY_KEY and My Key are
not keys. Both views refuse them in the browser with the rule spelled out, rather than sending a save
that comes back as a rejection. In the JSON view that matters twice over: the save is atomic, so one
bad key used to take the whole document's changes down with it.
Version retention#
Every write creates a new immutable version, so an actively rotated secret accumulates history. A namespace can cap that: set max versions per secret on the namespace overview, and each write prunes the oldest versions beyond the cap. The current version is never pruned. Leave it unset for unlimited history.
An administrator can destroy one non-current version's ciphertext from the versions drawer. It disappears from the history at once and cannot be revealed or rolled back to; the ciphertext itself is erased 30 days later, so a mistake is recoverable within that window and a leaked value is still genuinely erased. Purging skips the window. Both are restricted to space administrators, refuse the current version, and are audited.
Use it to purge a value that should never have been stored, not for routine cleanup — retention caps handle that.
Doing the same thing from a machine#
You do not have to work the command out yourself. A path holding secrets offers Use this path in the toolbar, and every row offers Use — both open a panel carrying that exact path's canonical address, its API path, and the commands that read it, ready to copy.
The panel answers two different questions depending on where you opened it. On a path, it is
"load this whole folder into my job": list, export, and run. On a single secret, it is
"read this one value": get, versions, and a version-locked set.
Its Set up in CI section is generated from the secrets actually at the path, not a template with blanks — the GitHub Actions and GitLab CI blocks come out already naming every key and the environment variable your job will receive. It also checks, before you paste anything, whether a machine identity can actually read that path, because a pipeline pointed at a path nothing may read fails in a way that looks like a broken config rather than a missing permission.
Everything below is what that panel hands you, if you would rather type it.
The CLI walks the same tree, one level at a time. The path this explorer's copy button gives you is
exactly what pulsvault list takes — no rewriting, no dropping the folder off the end:
pulsvault list acme-web/prod/product/web # the folders you see here
pulsvault list acme-web/prod/product/web/postgres # the keys inside one of them
pulsvault list acme-web/prod/product/web -R # the whole subtree, as full pathsexport and run accept a folder prefix too, so a namespace holding several unrelated groups of
credentials can be loaded one group at a time. pulsvault import writes a whole file of key-values in
atomic batches of up to 100 keys — the same all-or-nothing guarantee the JSON view gives you, applied
per batch.
See Finding secrets for the full tree walk, and
Using in CI for import, export and run.