Paths, plans & roles
The canonical secret path, the plans that unlock DevOps Secrets, and the permission codes that gate each action.
The canonical path#
Every secret has one canonical path:
acme-web / prod / product/web / db/password
| | | |
| | | +-- Secret path (folder + leaf, ≥ 2 segments)
| | +---------------- Namespace (free hierarchy, up to 5 segments)
| +--------------------------- Environment (controlled vocabulary)
+------------------------------------ Project (slug)The full path is {project}/{env}/{namespace}/{secret}. The organization is implicit — derived
from the authenticated identity, never in the path.
- Allowed characters: lowercase
a–z, digits,_,-, and.(secret paths only), separated by/. - No uppercase, whitespace, leading/trailing slash, or double slashes.
- Environment is the highest-security discriminator — cross-environment access requires an explicit policy.
This exact string is the AES-GCM additional authenticated data (AAD) for every secret value. A value encrypted at one path cannot be decrypted at another, so a secret can never be silently relocated or replayed under a different identity.
That is why {project}/{env} is an immutable mount — neither a project slug nor an environment
code can ever be renamed. The namespace and secret paths beneath them can be renamed, because the
console re-encrypts every affected value under the new path.
Every secret lives under a folder#
The secret portion of the path is always at least two segments — a folder and a leaf. db/password
is valid; a bare password directly at the namespace root is not:
pulsvault set acme-web/prod/product/web/password "$V" # rejected — no folder
pulsvault set acme-web/prod/product/web/db/password "$V" # ok — folder 'db', leaf 'password'The namespace path may be up to 5 segments, and the combined {namespace}/{secret} remainder up to
8 — roughly three or four folder levels beneath the namespace.
The environment is the first path segment. Where that is usually a naming convention everyone
agrees to follow, here it is a validated controlled vocabulary. Writing to prd/… by typo is
rejected — prd isn't a registered environment, so the mistake fails at the write rather than
quietly creating a parallel tree nobody is watching.
A path is a directory or a secret — never both#
Within a namespace, every path is exactly one of two things:
- a directory (it contains sub-paths), or
- a secret leaf (it holds one or more secrets directly).
A path can never be both at once. So once redis holds a secret directly (e.g. redis/host), you
cannot create a sub-path under it — and once redis has sub-paths (e.g. redis/replica/host), you
cannot write a secret directly at redis. This keeps the tree unambiguous: a node is a folder you
drill into, or a bucket of values you read — the reader never has to guess.
The rule is enforced on both planes and at every depth, so it also rejects the case where a single
deep write would turn a parent into a mix. For example, if redis/host already exists:
# 409 Conflict — 'redis' already holds a secret, so it cannot also contain sub-paths.
pulsvault set acme-web/prod/product/web/redis/replica/host "$VALUE"To fix it, choose one shape: keep the values flat under redis (redis/host, redis/port), or
move them one level deeper so redis is purely a directory (redis/primary/host,
redis/replica/host). The console blocks the invalid action in the UI; the CLI/CI plane returns
409 Conflict with the same explanation.
Plans#
DevOps Secrets is gated by the DEVOPS_SECRETS entitlement:
| Plan | DevOps Secrets |
|---|---|
| Free / Premium / Family | — not available |
| Developer (Solo Professional) | ✓ personal space; the owner has every permission |
| Team / Business / Enterprise | ✓ organization space; access via roles & permissions |
Roles & permissions (organization plans)#
Organization admins (ADMIN, BUSINESS_ADMIN) can do everything. Other members need the specific
secrets:* permission codes, granted through their role — the same way team:* / business:*
authorities are granted.
| Permission code | Gates |
|---|---|
secrets:environment:manage |
create/edit/disable environments, delete one that never held secrets, manage integrations |
secrets:namespace:manage |
create/archive namespaces, rotate encryption keys |
secrets:service_account:manage |
create/edit service accounts |
secrets:api_key:manage |
issue/revoke API keys |
secrets:policy:manage |
attach/detach policies |
secrets:validation:configure |
configure validation on a secret, alert routes and probe templates |
secrets:validation:trigger |
run validation on demand; acknowledge or snooze an alert |
secrets:validation:view-history |
view validation history & alerts; end a snooze early |
On the Developer plan there are no roles to manage — the personal-space owner implicitly holds all of the above.
Machine authorization#
Machines don't use these console permissions. A service account's access is governed entirely by its policies, evaluated against the full path for each action (read / write / delete / list / rotate).