Core concepts
The workspace → project → environment → secret hierarchy, and how inheritance, versioning, and references fit together.
Everything in Vaultic hangs off one hierarchy:
Workspace
└── Project
└── Environment (development, staging, production, dev-alice, preview-pr-142, ...)
└── Secret (key + versioned, encrypted values + metadata)Workspaces
A workspace is your team's top-level container — members, roles, service tokens, webhooks, and the audit log are all workspace-scoped. Every project lives inside exactly one workspace.
Projects
A project maps to one codebase, typically. It has a slug (used by the CLI and API,
e.g. acme/backend-api) and contains the environments that hold its actual secrets. New projects
are created with development, staging, and production by default.
Environments
An environment is where secrets actually live. Beyond the three defaults, you can create as many
as you need — qa, ci, demo, or even a per-developer environment like dev-alice.
Inheritance
An environment can declare a parent. Keys it doesn't set fall through to the parent; keys it
does set shadow it. dev-alice might inherit from development and override just one or two
values.
Duplication
Clone an environment as a copy (values included), keys-only (values left blank), or in link mode — which is inheritance instead of a copy, with nothing duplicated.
Promotion
env promote <from> <to> diffs two environments and copies the added/changed values up a
chain — the usual staging → production motion.
Locking
A locked environment rejects direct writes — they become pending change proposals requiring approval instead. See Locking & change requests.
Environments can also be ephemeral: created with a TTL (or spawned automatically by a Git integration for preview deploys), and auto-expired once their time is up.
Secrets
A secret is a key, a versioned encrypted value, and metadata: an optional type hint (string,
json, url, boolean, certificate, ...), tags, an owner, an expiry date, and a
rotation-reminder cadence.
- Every write is a new version. Old versions stay fetchable — view history, diff, or roll back with one command.
- Masked by default, everywhere. Listing, getting, or viewing history shows
••••••••plus the last 4 characters. Seeing the real value requires an explicit--reveal(CLI) or Reveal click (web app), and that reveal is audited as its own event, separate from the read itself. - Personal overrides. A developer can set a value that only they see, scoped to themselves
and one environment — never visible to teammates, and never consulted by service-token reads
(
export/run), so a personal override can't accidentally leak into a deploy.
Secret references
A secret's value can reference another secret, resolved at fetch time — not at storage time, so rotating the referenced secret automatically flows to everything that points at it:
${KEY} # another key in the same environment
${environment/KEY} # a different environment, same project
${workspace/project/environment/KEY} # fully qualified, cross-projectValues can mix literal text with references, so a connection string can be composed from parts:
DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/appCross-environment and cross-project references are resolved with the requesting actor's own access checked against the target — so a token scoped to one environment can't read a sibling environment's secrets just by pointing a reference at it. Reference cycles are detected and rejected rather than looping forever.