Roles & Permissions
Envpilot uses a two-tier role-based access control system. Organization roles set the baseline, project roles can restrict access further, and per-variable permissions provide fine-grained control.
Organization roles#
Every team member has one organization-level role.
Admin#
- Full access to every project and variable in the organization
- Create, edit, and delete projects
- Roll back variable versions
- Manage all team members and their roles
- Grant and revoke per-variable permissions
- Approve or deny variable access requests
- Export audit logs
- Manage billing, plan upgrades, and organization settings
- Delete the organization
Team Lead#
- Create and manage projects
- Create, edit, and delete variables
- Grant and revoke per-variable access for Members
- Approve variable access requests
- View project-scoped audit logs
- Cannot manage billing or delete the organization
Member#
- Read-only access to projects they are assigned to
- Can only view variables they have explicit per-variable permission for
- Submit new variables for approval (creates a pending request)
- Request access to variables they need
- Cannot directly create, edit, or delete variables
- Cannot manage other team members
Project roles#
Projects support an additional layer of access control. These roles can restrict (but never expand) the access granted by the organization role.
| Role | Pull variables | Push directly | Push for approval | Manage project members |
|---|---|---|---|---|
| Manager | All variables | Yes | — | Yes |
| Developer | All variables | No | Yes | No |
| Viewer | Permitted variables only | No | No | No |
When a Developer pushes via the CLI, the changes are saved as pending requests that a Manager, Team Lead, or Admin must approve.
When a Viewer runs envpilot pull, they only receive variables they have been explicitly granted access to. All other variables are omitted from the response.
Per-variable permissions#
Beyond roles, access can be granted on individual variables. This is how Members and Viewers get access to specific secrets they need for their work.
A permission grant includes:
- Target variable — the specific variable being shared
- Permission level —
readorwrite - Expiration date (optional) — automatically revokes access after the date passes
- Granted by — the Admin or Team Lead who approved the access
Requesting access#
When a Member or Viewer needs a variable they cannot see:
- They run
envpilot list variablesand see the variable is access-restricted - They submit a request from the dashboard, CLI, or VS Code extension (
Envpilot: Request Variable) - A Team Lead or Admin receives the request and approves or denies it
- If approved, the variable appears in the user's next
pull
All requests and approvals are recorded in the audit log.
Machine-filed requests#
Requests don't only come from people. An API key with the requests resource — used by an AI agent over the MCP server — can file a variable request too. These land in the same reviewer queue and are governed by the same project.requests.review capability: an Admin, a Manager, or a Team Lead can review them. As with human requests, the approver supplies the value — a machine credential never proposes one. See Architecture for the "agent requests, human approves" model.
How push behavior changes by role#
# Admin or Team Lead — push succeeds immediately
envpilot push
# ✓ 3 variables created, 2 updated
# Developer — push creates pending requests
envpilot push
# ⚠ You have Developer access. Push will create pending requests
# that require Manager/Admin approval.
# ✓ 5 variable requests submitted for approval
# Viewer — push is blocked entirely
envpilot push
# ✗ Error: You have Viewer access. Push is not available.Permission inheritance#
- Organization role sets the maximum access level
- Project role can restrict access within a project (a Member with Developer project role can push for approval, but a Member with Viewer project role can only read permitted variables)
- Per-variable permissions override project-level defaults (a Viewer can be granted write access to a specific variable)
- When tier enforcement is disabled (pre-alpha mode), all feature gates return allowed — but RBAC roles are always enforced
Security Hold#
Security Hold freezes a member's access across the entire organization without removing them — their membership, role, project assignments, and permission grants all stay exactly as they are. It exists for the moment access needs to stop immediately but the decision to actually remove someone hasn't been made yet.
What it does. The moment a hold is applied, every authorization check in the system denies that member — reads and writes alike, everywhere. All of their active CLI tokens and VS Code extension sessions are revoked in the same action, and the resulting revocation events tell the extension to delete its locally synced .env files. In effect, a held member is indistinguishable from a suspended member: they can sign in and see that they're suspended (with the date), but nothing else — not who suspended them or why. Lifting the hold restores the exact prior shape; nothing needs to be reconfigured, since role and grants were never touched.
Who can apply or lift it. Applying a hold requires the same capability as removing a member, plus the same hierarchy rule: you can only suspend someone strictly below your own role, and owners can never be suspended (transfer ownership first if an owner's access is the incident). Nobody can suspend themselves. Lifting a hold requires the same hierarchy check.
Credential sweep. Applying a hold also surfaces any organization API keys the held member created that are still active, so the admin can review and revoke them — this is opt-in, not automatic, since a shared credential might still be powering CI for the rest of the team.
When to use it. Security Hold is Pro-gated and suited to two situations: an offboarding pause (access frozen while the removal decision is finalized) and incident response (a compromised device or credential — cut access instantly, investigate, then either lift the hold or remove the member for good).
Custom roles#
Beyond the four built-in roles above, Envpilot has a role registry backed by capability maps — each role, system or custom, is a named set of granular capabilities (project.variables.create, org.members.invite, and so on) rather than a hardcoded branch of logic. Two non-system roles, Editor (project-scoped create/edit, no member or approval powers) and Viewer (read-only), ship seeded into every organization on top of the four system roles.
Today, custom roles are managed by the Envpilot team, not self-serve by organization owners: creating a role, editing its capability set, and activating or deactivating it are all done from the internal admin panel, which is gated to a platform-staff allowlist — not exposed anywhere in the organization dashboard. There is no self-serve custom-role UI for organizations yet.