Skip to content
Esc
↑↓navigate↵open⌘Jpreview
On this page

Core concepts

The ideas behind how varsafe works, and the terms the rest of these docs use.

CLI v7.8.1

Three ideas carry the whole product:

  • One place for every secret. A secret lives in exactly one environment of one project, and everyone reads it from there, so there is no copy to drift or leak.
  • Access scoped to the work. People get a role, pipelines get a token, agents get a grant you approve. Each reaches only what its job needs.
  • A record of every read and change. Who, which client, from where, and when.

This page explains each in turn. If you have not used varsafe yet, getting started is five minutes.

How secrets are organized

Four things nest, each inside the one before it: a team owns projects, a project has environments, and an environment holds secrets. The same key name in three environments is three separate values under three separate access rules.

Team

acme

Project

api-backend

development

DATABASE_URL
JWT_SECRET
REDIS_URL

staging

DATABASE_URL
JWT_SECRET
REDIS_URL

production

DATABASE_URL
JWT_SECRET
REDIS_URL

Project

web-dashboard

Teams

A team is the people who work on the same projects, and the boundary around everything they share.

  • Members join by invitation and each has a role. One person can belong to several teams.
  • One team’s data is invisible to another’s. Every request is checked by the application, and the most sensitive tables (secrets, tokens, agent grants, invitations, single sign-on settings and the audit log) are also protected by row-level security in the database. The security model has the details.
  • Billing and the plan are per team. On the Team plan, members can sign in through your identity provider with SSO (SAML 2.0 or OIDC).

Projects

A project is usually one application or repository. It has its own environments, its own secrets and its own history. Signing up creates a starter project; add one for each application you run.

Environments

Every new project starts with three environments:

Environment Purpose Protected
development Local development No
staging Pre-production testing No
production Live systems Yes

Add your own (qa, demo, preview) whenever you need another stage. The slug, the name you pass to -e, is fixed when the environment is created; you can rename an environment freely, and only its display name changes.

Secrets

A secret is a key and a value:

  • Key: starts with an uppercase letter, then uppercase letters, digits and underscores (e.g. DATABASE_URL), up to 255 characters
  • Value: up to 64 KB, encrypted at rest in a dedicated secrets vault hosted in the EU
  • Versions: every change creates a new version, and the last 10 are kept so you can roll back

Values are stored, not interpreted

A secret’s value is bytes. varsafe stores what you give it and returns exactly that: it does not expand ${...}, read your shell environment, or substitute anything into a value. A secret whose value is ${DB_PASS} is a secret whose value is the eight characters ${DB_PASS}, on every read.

So secrets that hold templates as data, such as a Grafana dashboard, a Kubernetes manifest or another tool’s config file, pass through untouched.

Composed secrets

When you do want one secret built from others, create it as a composed secret:

DATABASE_URL = postgres://${DB_USER}:${DB_PASS}@db.internal/app

Composition is something you choose when you create the secret (varsafe set --template in the CLI), never inferred from what a value happens to look like. Rotate DB_PASS and every secret built from it follows, so a password lives in one place instead of inside every connection string. Reads return the resolved value; you get the template only when you ask for it with --source. See composed secrets.


Who can reach what

People, pipelines and agents each reach varsafe with a credential of their own, and each is limited to its job.

Role CLI login API token Agent grant
For Each member of a team You, through varsafe login Something that is not a person: a CI pipeline, a cron job, a backend service, an internal tool A coding agent, connected over MCP
Access One of six roles, which decides what the member can do in each environment Read only, Standard (runs and reads values) or Full access, chosen when you approve it; never more than your role One team, optionally narrowed to chosen projects and environments; read-only, or read and write A team, and optionally projects and environments; an access level from Read only (names and comparisons, no values) up to levels that also read values and create, change or delete secrets; never more than your role
When it ends Removing the member revokes their CLI logins, agent grants and the API tokens they created, in one step Revoked when you are removed; a revoked login is refused on its next request Always expires: up to 90 days on the Developer plan, up to 365 on Team. Revocable at any time, and revoked when its creator is removed Revoked from Agents in the dashboard, or when you are removed

People: roles

Each member of a team has one role, and the role decides what they can do in each environment:

Owner

Non-protectedRead and write

ProtectedRead and write

Admin

Non-protectedRead and write

ProtectedRead and write

Developer

Non-protectedRead and write

ProtectedRead-only

Operator

Non-protectedRead-only

ProtectedRead-only

Viewer

Non-protectedRead-only

ProtectedNo access

Billing

Non-protectedNo access

ProtectedNo access

Six roles exist: owner, admin, developer, operator, viewer and billing. Owners and admins manage the team and can change secrets everywhere. Developers change non-protected environments and read protected ones. Operators read everything and change nothing. Viewers read non-protected environments only. Billing members manage the subscription and never see a secret. The full matrix is in the roles reference.

Your CLI login is a credential of its own: when you approve varsafe login, you choose what it may do (Read only, Standard, which runs and reads values, or Full access), and it can never exceed your role.

Pipelines and scripts: API tokens

An API token (vs_at_…) is a credential for something that is not a person: a CI pipeline, a cron job, a backend service reading its configuration at startup, an internal tool.

  • It belongs to one team and can be narrowed to chosen projects and environments.
  • It is read-only or read and write. The dashboard form starts on read and write, so choose read-only unless the job changes secrets.
  • It always expires: up to 90 days on the Developer plan, up to 365 on Team.
  • Its reads and changes appear in the audit log under the token’s name, so give each pipeline its own.
  • It is stored only as a salted hash, shown once at creation, and revocable at any time.

See API tokens and CI/CD pipelines.

Agents: grants you approve

A coding agent such as Claude Code, Cursor, Codex or VS Code connects over MCP. The first time, your browser shows a consent screen and you decide what the agent may do:

  • Which team, and optionally which projects and environments.
  • What it may do: an access level, from Read only (names and comparisons, no values) up to levels that also read values and create, change or delete secrets. Values stay out of reach unless you approve a level that includes them.

A grant can never exceed your own role. Every secret operation the agent makes is checked against your role as it stands at that moment, so a downgrade or a removal takes effect at once, and every one is recorded with the agent as the client. You can see and revoke each grant from Agents in the dashboard, where it is listed as a connection.

An agent that runs shell commands can also use the CLI. It then acts with the CLI login on that machine, limited to what you approved for that login, which the agent’s grant does not narrow. Agent safety covers keeping both narrow. varsafe run hands the values to the command it starts, not to the agent, so the agent sees only what that command prints.

When someone leaves

Removing a member revokes their CLI logins, their agent grants and the API tokens they created, in one step. Values they already revealed stay revealed, so rotate those at their source.


How varsafe run delivers secrets

varsafe run is the everyday workflow, for people, pipelines and agents alike:

varsafe run -- npm run dev
  1. varsafe CLI → varsafe APIAsk for the environmentauthenticated, over TLS
  2. varsafe API → Secrets vaultFetch the values
  3. Secrets vault → varsafe APIValues
  4. varsafe API → varsafe CLIValues, over TLSthe read is audited
  5. varsafe CLI → Your appStart your app with them in its environmentvarsafe writes nothing to disk

What that gives you:

  • Nothing on disk. On your machine the values exist only in the memory of the CLI and of your process. When the process exits, they are gone.
  • Only what the command needs. --include 'API_*' passes a subset of keys to your command; --prefix renames them on the way in. The CLI still fetches the whole environment, and the audit log records every key it fetched.
  • Not the token. An API token in VARSAFE_API_TOKEN or VARSAFE_TOKEN is removed from your command’s environment, so the script you run gets the secrets but not the credential that fetched them (unless you pass --pass-credential).
  • Your command, unchanged. It runs directly, with no shell in between unless you ask for one with --shell, and varsafe run exits with its exit code.
  • A record. The read is logged with the key names that were fetched, who asked, and from which client.

The values are encrypted in transit and at rest. The varsafe API decrypts them to serve an authorized request; this is a server-side secrets manager, and the security model explains exactly what that means.

When a tool needs a file

If a tool will only read a file, varsafe export writes one. By default a .env export is encrypted, value by value, to its environment, so the file is safe to commit; --plain writes plaintext, and --tmpfs keeps it in RAM. JSON, YAML and Docker formats are always plaintext. See exporting and encrypted .env files.

Each environment has its own keypair for these files. varsafe holds the private key, protected by a managed key service, and opens a file itself for anyone allowed to read the environment (varsafe run --env-file), so an encrypted export is not end-to-end encryption; see the access model.


Which project and environment a command uses

Most commands need a project and an environment. The CLI checks four sources in order, and the first that answers wins:

1

Explicit flags

-p and -e always win. Give only one inside a repository and the other comes from its .varsafe file (CLI 7.8.1 and later).

-p / -e

2

Local .varsafe file

A small file in your repository, found by searching from the current directory up to the git root.

./.varsafe

3

Saved context

Set with varsafe use outside a repository, and kept for your user.

varsafe use

4

Auto-selection, or a prompt

Selected automatically when only one option exists; otherwise the CLI asks rather than guessing.

interactive

# Choose once
varsafe use -p my-api -e development

# Every command after that uses it
varsafe list
varsafe run -- npm run dev

# Flags override it for one command
varsafe list -p my-api -e staging

Run varsafe use inside a git repository and the choice is written to a .varsafe file at the repository root. It holds only project and environment IDs, no secrets, so you can commit it and everyone who clones the repository starts in the same project. Outside a repository, the choice is saved for your user. varsafe use --clear resets it, and varsafe status shows what the next command will use.


History and rollback

Every save to an environment, of one secret or many, creates a new version of it, and each environment keeps its last 10. A value can be restored while the version that saved it is still among them. In the dashboard you can:

  • Restore one secret from its history. Restoring creates a new version with the old value, so nothing is lost.
  • Roll back a whole environment from its Environment history: pick a change, preview the result, and undo that change and everything after it.

Each restore and rollback is recorded in the audit log, like any other change.


Audit trail

Every value read and every change is recorded, along with sign-ins, role changes, token and agent activity. An event looks like this (illustrative):

{
  "action": "secret.accessed",
  "actor": "alice@example.com",
  "source": "cli",
  "project": "api-backend",
  "environment": "production",
  "secretKeys": ["DATABASE_URL", "API_KEY"],
  "ip": "203.0.113.24",
  "timestamp": "2026-02-15T10:30:00Z"
}

The audit log is:

  • Append-only: the application can add events but never edit or delete them.
  • Searchable: filter by team, action, target and date in the dashboard’s Audit log.
  • Exportable: owners and admins on the Team plan can export it for a compliance review.

How long events are kept depends on the plan: 7 days on Developer, 90 days on Team.


Signing in and sessions

You sign in to the dashboard with email and password, GitHub, GitLab, Google or Bitbucket, or a passkey, and can add TOTP two-factor; Team plans add SSO. The CLI signs in through the browser with varsafe login, and its credential is stored only as a salted hash on our side.

Your profile lists your active sessions, and you can revoke any of them. A revoked dashboard session stops working within 30 seconds; a revoked API token or CLI login is refused on its next request. See authentication and the security model.