Core Concepts
The varsafe mental model — teams, projects, environments, secrets, context resolution, and how injection works.
Organizational Model
Four things nest, each one inside the one before it: a team owns projects, a project has environments, and an environment holds secrets. Every secret has exactly one home — the same key name in three environments means 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
The top-level unit. Owns projects, holds the members and their roles, and carries billing.
Projects
An application or repository that needs secrets. Belongs to exactly one team.
Environments
A deployment stage within a project — development, staging, production, or your own.
Secrets
An encrypted key-value pair living in one environment, versioned on every change.
Teams
A team is a group of people who collaborate on the same projects.
- Teams own projects
- Teams have members with roles — and a user can belong to multiple teams
- Access to secrets flows through team membership
- Billing is managed at the team level
- Teams on the Team plan can configure SSO (SAML 2.0 / OIDC) for domain-based login
Projects
Each project has:
- A name (typically matching your repository)
- An owning team
- Multiple environments
- Its own secret history
Environments
Every project has environments for different deployment stages:
| Environment | Purpose | Default Protected |
|---|---|---|
development |
Local development | No |
staging |
Pre-production testing | No |
production |
Live systems | Yes |
You can also create custom environments for specific needs (e.g., qa, demo, feature-x), and protect or unprotect any environment in its settings.
Each environment also has a server-managed keypair used to produce encrypted .env exports — files that are useless to anyone who obtains them without access to your team. The private key is held and KMS-protected by varsafe, not by you, so this is not end-to-end encryption; see the access model.
Secrets
Secrets are key-value pairs stored securely:
- Key: starts with an uppercase letter, then uppercase letters, digits, and underscores (e.g.,
DATABASE_URL); up to 255 characters - Value: encrypted, up to 64 KB
- Version: auto-incremented on each change
- History: full change history with rollback capability
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}, forever, on every
read.
This matters when secrets hold templates as data: a Grafana dashboard, a Kubernetes manifest, another tool’s config file. Those pass through untouched.
Composed secrets
A secret can opt in to being a pointer instead of a value:
DATABASE_URL = postgres://${DB_USER}:${DB_PASS}@db.internal/app
This is a different kind of secret, marked as such when you create it — never inferred from what the
value happens to look like. Rotating DB_PASS changes every secret that references it, so a password
lives in one place rather than in every connection string that embeds it. Reads return the resolved
value; only an explicit request returns the source.
Secrets created before composition existed are literal, and stayed literal — nothing was reinterpreted. See Composed Secrets.
CLI-First Architecture
varsafe is designed around the CLI workflow:
Under the hood, a single varsafe run does four things:
- Authenticate — CLI presents your session token or API token over TLS
- Fetch — API retrieves your secrets from the vault, where they are encrypted at rest (vault + KMS)
- Return — Secrets travel back to the CLI over TLS
- Inject — CLI sets secrets as environment variables in the spawned process — nothing is written to disk
The dashboard exists for management tasks (creating teams, inviting members, viewing audit logs) but the primary developer interaction is through the CLI.
Context Management
Most commands need to know which project and environment you mean. Four sources, checked in order — the first that answers wins.
1
Explicit flags
`-p` and `-e` always win, and never change what is saved.
-p / -e
2
Local .varsafe file
A small context file in your repository, found by searching from the current directory up to the git root.
./.varsafe
3
Global saved context
Set with `varsafe use`, stored in the CLI’s local database.
varsafe use
4
Auto-selection, or a prompt
Selected automatically when only one option exists; otherwise the CLI asks rather than guessing.
interactive
# Set your working context
varsafe use -p my-api -e development
# Now these commands use that context automatically
varsafe list
varsafe run -- npm run dev
varsafe export -o .env
When you run varsafe use inside a git repository, the context is written to a .varsafe file in the repo — teammates and future shells in that repo pick it up automatically. Outside a repository, the context is saved globally.
Override context anytime with flags:
varsafe list -p my-api -e staging
Ephemeral Injection
Secrets are never written to disk by default. Instead, they’re injected directly into your process’s environment:
varsafe run -- npm run dev
Four steps between your keystroke and a running process. On your machine the values live only in process memory — the CLI’s and the child’s — and are never written to disk.
1
Authenticate
The CLI presents its credential to the varsafe API over an encrypted connection.
TLS
2
Fetch
The API reads the secrets for the resolved project and environment — they are encrypted at rest in the vault and decrypted server-side — and returns them over the same encrypted connection.
encrypted at rest
3
Spawn the child
The command after `--` is executed directly with the secrets in its environment — no shell in between, so nothing lands in shell history.
execve
4
Exit with the child
When your process ends the environment goes with it, and `varsafe run` returns the child’s own exit code.
no files
When your app terminates, the secrets are gone — no files left behind.
Access Control Model
Access follows this hierarchy:
Six roles exist: owner, admin, developer, operator, viewer, and billing. Owners and admins manage the team and write everywhere; developers write to non-protected environments; operators and viewers are read-only; billing members manage billing without secret access. The full permissions matrix lives in the roles reference.
API Tokens
Use API tokens instead of user sessions for non-interactive access:
- CI/CD pipelines — Inject secrets during build and deploy
- Automation scripts — Scheduled jobs, cron tasks, infrastructure tooling
- Server-side applications — Backend services that need secrets at startup
- Development tooling — Custom scripts, internal CLIs, or IDE integrations
Token properties:
- Scoped to a specific team
- Prefixed
vs_at_so scanners can recognize them - Separate audit trail (shows as a service account)
- Optional expiration date; revocable at any time
See API tokens for creation and usage.
Version History
Every secret change is tracked. Operation types include:
create— New secrets addedupdate— Secret values changeddelete— Secrets removedrotate— Secret rotated
Rollback
You can roll back an environment to any previous state via the dashboard:
- Go to Secrets → History
- Select the operation to roll back
- Review the preview showing what will change
- Confirm rollback
Audit Trail
Every action is logged. An audit event looks like this (illustrative):
{
"action": "secret.accessed",
"actor": "alice@example.com",
"project": "api-backend",
"environment": "production",
"secretKeys": ["DATABASE_URL", "API_KEY"],
"ip": "192.168.1.100",
"source": "cli",
"timestamp": "2026-02-15T10:30:00Z"
}
Audit logs are:
- Append-only — Events are added, never edited
- Complete — Every action is logged
- Queryable — Filter by team, project, actor, or time range
- Exportable — Download for compliance reviews
Audit retention is plan-gated:
- Developer plan: 7 days
- Team plan: 90 days
Session Management
varsafe uses opaque session tokens for authentication:
- High-entropy tokens generated with secure randomness
- Hashed before storage — the raw token is never stored server-side
- Instantly revocable — no waiting for token expiry
- Session metadata includes IP, user agent, and timestamp
When you revoke a session, it’s immediately invalid everywhere. See the security model for the full picture.
Related Documentation
- CLI Reference — Command details
- Roles — Full permissions matrix
- Dashboard Guide — Full dashboard features
- API Tokens — Service accounts
- MCP Server — AI agent access via Model Context Protocol
- Security Model — Security architecture
- Operations — Operational workflows