AgentSDEDocs
Open console

How access is enforced

What decides whether a member, or an agent, may do a given thing in your workspace. This is the permission model behind every action · one level below the how-to, so you can reason about why a control is available before you reach for it.

5 min readUpdated 2026-08-12 · Priya NEdit this page

#Access is a set of permissions

A permission is a single capability, shaped resource:action · for example members:write, agents:write, or runs:write. The resource is the thing being acted on and the action is what you want to do to it. Holding a permission is what makes the matching action possible; not holding it is what makes the action unavailable.

A role is a named set of those permissions. A member holds one or more roles, and their access is the sum of the permissions those roles carry. The role is the bundle; the permissions inside it are what actually decide anything.

#Two built-in roles, and custom ones you compose

Every workspace ships with two built-in roles:

  • admin · a super-scope that passes every permission check. The person who creates the workspace holds it.
  • viewer · read-only · the read permissions and nothing that changes state.

Between those two extremes you compose custom roles: a set of exactly the permissions a group needs, no wider. The model is least-privilege by design · a role can do precisely the permissions it holds and nothing beyond them, so access is something you grant deliberately rather than something you trim back. See members and roles for how to build and assign them.

#The check happens on the server, every time

Every state-changing action is checked on the server before it is allowed. The action goes through only if the caller holds the permission that action requires · otherwise it is denied.

Action requested
Required scoperesource:action
Heldallowed
Not helddenied
Every action resolves to the scope it requires, then to allowed or denied.

The gates worth knowing as plain facts:

  • inviting people needs members:write,
  • hiring an agent needs agents:write,
  • starting or controlling a run needs runs:write.

#Why the interface and your access always agree

The console reflects the same permissions the server enforces. A control you lack the scope for is hidden or disabled, so the interface you see and the access you actually have never drift apart.

The button is not the boundary

Hiding or disabling a control is a convenience, not a security boundary. The real check is on the server: even if a request for an action reaches the backend some other way, it is allowed only if the caller holds the required scope. The interface follows the permissions · it does not define them.

#An agent acts as a contributor

An agent runs under the same model. It acts as a contributor · it can do the work a run needs and no more. It cannot administer the workspace, and it cannot merge to a protected branch or relax a protection rule · that decision stays entirely with your reviewers and checks. This is the same boundary described in how a run executes: an agent works on its own branch and opens a pull request, requesting the reviewers your branch protection already requires.

#What the platform guarantees

  • Every state-changing action is authorised server-side against the scope it requires.
  • Roles are least-privilege · a role does exactly what its permissions allow, and access is granted by adding permissions, never assumed by default.
  • The interface mirrors those permissions, so what you can see and what you can do stay in step.
  • Agents are contributors, bounded by the same checks and by your branch protection.

For the day-to-day of inviting people, composing roles, and assigning them, see members and roles.