Browse docs All docs
Docs / Role and permission matrix
Docdeploymill://docs/role-matrix

Role and permission matrix

Every DeployMill organisation has three roles, scoped per organisation. A user can be an owner in one org and a member in another.

RoleDescription
ownerFull control. Can do everything an admin can, plus transfer or delete the org and change other members' roles (including granting/revoking owner). There must always be at least one owner.
adminManages members, invites, and SSO, and can view billing (only an owner manages billing). Can drive all deploy-lifecycle actions. Cannot demote or remove an owner.
memberDeploys and operates apps. Cannot manage membership or access workspace-administration pages.

Deploy lifecycle (MCP tools + API)

Any role can authenticate an MCP client (or /api/v1) and drive the deploy lifecycle. The first unit of access control is which org the token belongs to. Within that, most deploy-lifecycle actions are open to every role, but a few privileged ones are gated to admin/owner: managing the org secret vault, deleting an app, and deleting a preview. A member calling one of those gets a not_authorized error (HTTP 403 over /api/v1).

Capabilityowneradminmember
Deploy, redeploy, rollback
Create apps
Delete apps
Create / redeploy previews
Delete previews
Set / delete env vars
Request / bind / delete org secrets
List org secrets (names only)
Attach / detach domains
Set app protection
Set app resources / sleep policy
Start / stop apps
Push files / get clone credentials

Workspace administration (dashboard + API)

These are workspace-management capabilities, not deploy-lifecycle capabilities. They live primarily in the dashboard (/account/org) and are gated to admin/owner.

Capabilityowneradminmember
View org member list
Invite members
Remove members
Change a member's role✓¹
Transfer / delete org
View audit log
Export audit log (CSV/JSON)
Configure SIEM webhook
View backup evidence
View / manage SSO
Require organization protection (org-wide)
View billing & plan

¹ Admins can change roles for members only. Only an owner can grant or revoke the owner role.

The Require organization protection mandate is gated by its own org.protection capability (owner/admin by default). When on, every app is force-gated behind organization sign-in on its next reconcile and protection can't be removed per-app. See the site-protection guide.

Per-member permission overrides

The role columns above are defaults, not hard limits. On top of a member's role bundle, anyone holding the member.manage permission can grant or revoke individual capabilities per member, so two admins can differ (revoke secret.write from one), or a single member can be trusted with app.delete without being promoted to admin.

Capabilities come from a fixed catalog: app.deploy, app.stop, app.manage, app.delete, preview.delete, domain.attach, secret.read, secret.write, code.export, backup.download, member.manage, org.settings, org.protection, org.billing.

A member's effective permissions are (role bundle ∪ grant) ∖ revoke, where a revoke always wins over a grant. Two guardrails apply: you can only grant a capability you hold yourself (no privilege escalation), and ownership changes stay owner-only (overrides never change who is an owner). get_account returns the caller's effective permission set, so an agent can see what it may do before it tries.

Last-owner guard

DeployMill enforces that every org always has at least one owner. An owner cannot demote themselves or be removed if they are the last owner. This prevents orgs from becoming ownerless.

Role assignment API

Roles are managed through the Better Auth organisation API:

  • POST /api/auth/organization/update-member-role: change a member's role (owner-only for owner role changes)
  • POST /api/auth/organization/remove-member: remove a member
  • POST /api/auth/organization/invite-member: invite with a role (admin/owner only)

Per-member permission overrides and the per-member app cap are managed through the dashboard API:

  • PATCH /api/ui/org/members/:id/permissions: set a member's grant/revoke overrides (member.manage-gated, escalation-guarded, audit-logged)
  • PATCH /api/ui/org/members/:id/limits: set or clear a member's active-app cap ({ maxActiveApps: number | null })
  • GET /api/ui/permissions/catalog: the capability catalog (labels + descriptions) the dashboard renders its toggles from

See also: Subprocessors for the data flows relevant to compliance.