Getting Started
Envpilot is a secure environment variable manager for teams. Instead of passing .env files through Slack, email, or Git, your secrets live in an encrypted vault with per-variable access control, and every project's variables are organized around three fixed environments. This page builds the mental model first, then walks through creating your first secret from each of the three surfaces, and finally invites a teammate.
Concepts#
Organization#
Everything in Envpilot starts inside an organization — the top-level container for your team. An organization has a name, a URL-friendly slug, and a set of members, each with exactly one role. If you're the first person on your team to sign up, you'll create one from Create Organization before anything else exists.
Project#
A project lives inside an organization and holds a set of environment variables — typically one project per app or service (api, web, worker-jobs). Projects have their own name, slug, and optional description, and support role-based access at the project level (see Roles & Permissions).
Environment#
Every project has exactly three fixed environments: development, staging, and production. Every variable is scoped to one or more of these — a variable can live in just development, in staging and production together, or in all three. There's no way to add a fourth custom environment; the three-environment model is fixed across the CLI, extension, dashboard, and public API.
The same key can exist as two separate variables as long as their environment sets don't overlap —
DATABASE_URLscoped to[development]and a differentDATABASE_URLscoped to[production]are independent values. Overlapping environments for the same key are rejected.
Variables vs. secrets#
Envpilot doesn't have a separate "secret" object type — every variable can optionally be marked sensitive. When you create or edit a variable, there's a "Mark as sensitive" checkbox with the note "masks value by default" — checking it means the value is masked (••••••••) in the dashboard until someone explicitly reveals it.
This is a display setting, not an encryption setting: every variable's value, sensitive or not, is stored in WorkOS Vault and encrypted at rest — Convex only ever holds a vault reference ID, never plaintext. Marking a variable sensitive just controls who casually sees it scroll by on a screen.
Roles, briefly#
Every member has one role that determines what they can do — from read-only access up to full organization administration — and whether a write lands immediately or has to wait as a pending request for someone else to approve. See Roles & Permissions for the complete breakdown, including how per-variable access grants and Security Hold work.
Your first secret#
Pick whichever surface you're already in. All three read and write the same underlying data — a variable created in the dashboard shows up on your next envpilot pull and in the VS Code sidebar.
From the dashboard#
- Create an organization (skip if you already have one) — go to Create Organization, give it a name (e.g.
Acme Inc.) and slug (e.g.acme-inc). - Create a project — from the dashboard, Create Project, name it (e.g.
My Awesome Project) and give it a slug. The new-project flow also offers a framework template (Next.js, T3 Stack, Django, Rails, and more) that pre-fills a starter set of variables for you to fill in. - Open the project and pick an environment tab (
development,staging, orproduction). - Click Add Variable (this reads Request Variable instead if your role can't write directly — see Roles & Permissions). Fill in:
- Key — e.g.
DATABASE_URL - Value
- Description (optional)
- Environments — pick one or more; each is color-coded (green for development, yellow for staging, red for production)
- Mark as sensitive if it should be masked by default
- Key — e.g.
- Submit. The variable appears in the project's variable table immediately (or as a pending request in the Requests inbox, if your role required approval).
There's also a Bulk Paste tab in the same drawer for pasting a whole .env block at once instead of adding variables one at a time.
From the CLI#
npm install -g @envpilot/cli
envpilot syncenvpilot sync chains login, project selection, and a pull into one flow — the fastest way to get a working .env file locally. Under the hood it authenticates, walks you through picking an organization, project, and default environment, writes a local .envpilot config file, and adds .env to your .gitignore automatically.
Whether a subsequent envpilot push writes directly or files a pending request depends entirely on your role:
| Role | Behavior |
|---|---|
| Admin / Team Lead | Push succeeds immediately |
| Developer | Creates pending requests for approval |
| Viewer | Blocked with an error |
To set a single secret without a full pull/push round-trip:
envpilot secrets set STRIPE_KEY -e productionThe value is typed into a masked prompt, never your shell history. To inject secrets straight into a running process without ever writing a .env file to disk:
envpilot run -- bun devSee the full CLI reference for every command, output format, and flag.
From the VS Code extension#
- Install Envpilot from the VS Code Marketplace (also works in Cursor).
- Open the command palette and run Envpilot: Sign In — your browser opens to authenticate, then the extension picks up the session automatically.
- Run Envpilot: Link Project, choose your organization, project, and which environments to sync.
- Variables are pulled to your target file (
.env.localby default) immediately, and stay in sync automatically while the workspace is open.
Full details, including the commit guard and multi-directory sync, are in the VS Code Extension reference.
Invite a teammate#
From your organization's Members page, open the invite panel:
- Type an email — Envpilot autocompletes against existing users and flags whether they're already a member or have a pending invite.
- Pick a role from the list (roles are described inline as you pick).
- For roles that aren't org-wide, choose which projects to assign them to.
Envpilot emails an Accept Invitation link (envpilot.dev/invitations/<token>) that expires after 7 days by default. The invite only becomes a membership once the invitee signs in with the same email address the invite was sent to and clicks accept — a stray forwarded link can't be redeemed by anyone else. Pending invitations can be resent (issues a fresh token and expiry) or canceled from the same page at any time before they're accepted.
Where to go next#
- Web Dashboard — the full page-by-page tour: variable requests, diffs, trash, sharing, tags, and more
- CLI Tool — every command, flag, and output format
- VS Code Extension — real-time sync, commit guards, multi-directory linking
- Roles & Permissions — the full role and permission model, including Security Hold
- Security — how secrets are encrypted, audited, and revoked
- API Quickstart — pull variables over REST for CI/CD or an AI agent