Disco ParrotDisco Parrot Home
Docs
Request a Demo

Roles and permissions

How Disco Parrot decides who can do what. The scopes that name every action, the built-in roles that bundle them, the custom roles you build with a scope picker, and the danger levels and guardrails that keep a powerful action from being granted by accident.

Every action in Disco Parrot is named by a scope: reading a plan, inviting a member, replacing a secret, deleting the workspace, each is one named action. What a person can do is the set of scopes their roles grant them. That is the whole model. There is no separate policy language to learn and no rules engine to reason about: a request either carries the scope an action requires, or it does not.

This page is the map of that model. It covers the scopes themselves, the built-in roles that cover the common cases, the custom roles you build when the common cases are not enough, and the guardrails that keep the dangerous actions deliberate. Assigning roles to a particular person happens on the members page, or from a role's own Members tab; this page is about what the roles themselves mean.

Scopes: the vocabulary of permission

A scope is the smallest unit of permission, one named action. Its id is lowercase and dot separated, naming a subject and an action, so tenant.delete, members.invite, and secrets.tenant.manage say exactly what they allow at a glance. They are grouped into nine areas so the catalog stays legible rather than becoming a flat wall of names; there are more than a hundred and forty in all, and every one is listed in the permission scope catalog.

139 scopes, nine areasevery id reads as area.subject.actionWorkspacetenant.delete, tenant.updateIdentity and sessionsyour own logins and sessionsPlanningplans, bugs, sprints, reportsMembership tierper team, portfolio, projectChat and sandboxesruns, chats, tasksEvents and streamsthe live event feedsNotificationsnotification preferencesPlatform adminrepos, providers, secrets, hostsOperatorreserved for the platform
One hundred and thirty-nine scopes, grouped into nine areas so the catalog stays navigable. Each scope id reads as area.subject.action, so it says what it allows at a glance.
  • Workspace (tenant.*): creating, renaming, deleting, and configuring the workspace itself.
  • Identity and sessions (auth.*): your own logins, sessions, and self-service settings.
  • Planning (planning area): initiatives, plans, bugs, projects, portfolios, teams, sprints, goals, reports, flows, the day-to-day work.
  • Membership tier (membership area): the per-resource grants that teams carry, covered in teams and below.
  • Chat and sandboxes: running agents, chats, tasks, and the sandboxes they use.
  • Events and streams: subscribing to the live event feeds.
  • Notifications: notification preferences.
  • Platform admin: the tooling layer, repositories, providers, MCP servers, secrets, sandbox profiles, hosts.
  • Operator: reserved for the platform operator and never granted to a workspace role.

Each scope also carries a danger level and a few flags that the rest of this page leans on. The danger level says how much damage the action can do; the flags note when a scope is self-only (you can always act on your own things, like your own sessions), per-resource (granted on one team or project rather than the whole workspace), or gated by a plan entitlement (the action exists only on plans that include it). You rarely think about a single scope in isolation. You think in roles, which is what the scopes are bundled into.

Built-in roles

Disco Parrot ships eleven built-in roles that cover the shapes most workspaces need. Of the eleven, three form a ladder of general access, five are shapes for particular jobs, and three are membership-tier roles granted on a single resource. They are fixed: you cannot edit a built-in role's scopes, because they are the stable, known quantities everything else is reasoned against. When the built-ins are not the right fit, you build a custom role rather than bending a built-in one. Each of the eleven, and the scopes it carries, is in the built-in roles reference.

The access ladderOwneradds deleting the workspaceAdminadds managing the workspaceMemberread plus self-serviceJob shapesViewerLeadPlannerWorkspace OperatorBilling ManagerMembership tier, per resourcePlannerread, edit, and planContributorread and editViewerread
Eleven built-in roles: a three-rung ladder of general access, five shapes for particular jobs, and three membership-tier roles granted on a single team, portfolio, or project.
add_photo_alternate
Screenshot to capture
The Roles page under Settings, dark theme. Page header 'Roles' with a 'New role' button on the right. A list of role rows, each with a role icon, a name, a scope count (like '47 scopes'), a member count with a people icon, a surfaces badge reading 'Tenant' or 'Tenant + Membership', and an 'Updated' timestamp. Rows include built-in roles 'Owner', 'Admin', 'Member', 'Planner', and 'Workspace Operator', plus a custom role 'Release Manager' with '6 members' and 'Updated 2 days ago'. Whole rows are clickable into a role's detail.
save as: public/docs-media/roles-list.png
Caption when added: The Roles page lists every role, built-in and custom, with its scope count, how many people hold it, and where it can be assigned.

The first three are a ladder. Each one includes everything the one below it can do, and adds to it.

RoleForHolds
MemberThe default for everyone who joinsRead across the workspace, plus their own self-service settings
AdminRunning the workspaceEverything a Member can do, plus managing members, settings, providers, and integrations
OwnerThe single accountable seatEverything an Admin can do, plus deleting the workspace

The other five are not rungs on that ladder; they are shapes for particular jobs, composed of exactly the scopes that job needs.

RoleForThe idea
ViewerStakeholders, observers, external reviewersRead-only across the workspace, and nothing more
LeadA working implementer who also coachesA Member who can additionally see teammates' conversations and tasks and cancel their sessions, for unblocking the team
PlannerWhoever runs the roadmapRead everywhere, plus full management of the planning surface: initiatives, plans, bugs, goals, sprints, reports, flows
Workspace OperatorWhoever owns the toolingManages repositories, providers, MCP servers, SDK configs, sandbox profiles, hosts, and tenant secrets, without being a full admin
Billing ManagerA finance or operations contactLicense and audit visibility, and no access to the work itself

The last two are worth a closer look. A Workspace Operator can stand up the repositories, the agent runtimes, and the secrets a team needs to work, without holding the power to invite people or delete the workspace. A Billing Manager can read the plan and usage and the audit log for compliance, and carry a request for more capacity, while seeing none of the code or conversations. Each role is the exact reach of a real responsibility, so you hand someone the job without handing them the whole building.

Three more built-in roles are membership-tier roles, and they work differently: they are granted on a single team, portfolio, or project rather than across the workspace. They are Viewer, Contributor, and Planner levels, and they are introduced where you actually use them, on teams. The level each grants is summarized in the resource-membership section below.

Custom roles

When no built-in role is the right shape, you build a custom role. The fastest way to start is to clone a built-in one that is close, then adjust; cloning copies its scopes as a starting point so you are editing a real role rather than assembling one from nothing. A clone opens the editor pre-filled, with the name suffixed (copy) for you to change, and it leaves out any platform-only scopes, since a workspace role can never carry those. From there, the heart of the editor is the scope picker.

Clonea close built-inPre-filledname suffixed (copy)Pick scopesin the pickerAssignable ontenant / membershipConfirmdestructive scopesSaveunique name, then live
Building a custom role is clone-and-adjust: start from a built-in, trim and add scopes in the picker, choose where it can be assigned, confirm any destructive scopes, and save under a unique name. From there it appears in Assign Roles like any built-in.
add_photo_alternate
Screenshot to capture
The custom role editor in Disco Parrot, dark theme. A 'Name' field reading 'Release Manager' and a 'Description' field. An 'Assignable on' section with two checkboxes, 'Tenant-wide (members directory)' checked and 'Resource membership (teams, portfolios, projects)' unchecked. Below, a 'Scopes' section: a search box, then groups by area ('Workspace', 'Planning', 'Chat & Sandboxes' visible), each a card of rows. Each row has a checkbox, a label and one-line description, a monospace scope id on the right (like 'plans.manage'), and small coloured badges: a red 'Destructive' badge on a 'tenant.delete' row, an amber 'Elevated' badge elsewhere, a 'Per-resource' and 'Self-only' badge on others. A few rows are checked. A primary 'Save' and a 'Cancel' button.
save as: public/docs-media/roles-scope-picker.png
Caption when added: The scope picker lists every scope grouped by area, each with its danger badge and flags. You build a role by choosing exactly the actions it should allow.

The picker lists every scope, grouped into the same nine areas, each row showing its plain-language label, its id, and its danger badge. You search, you check the actions the role should allow, and you save. A custom role also declares where it can be assigned: tenant-wide, so it applies across the workspace, or resource membership, so it can be granted on a single team, portfolio, or project. You pick at least one, you can pick both, and you can change the choice later as the role's purpose shifts; a role that can be assigned nowhere would do nothing.

Sarah Chen needs a role that does not exist yet. Her release engineers should manage plans and bugs and run the ship process, but should not be able to touch members, providers, or the workspace itself. She clones Planner as a starting point, names it Release Manager, removes the planning scopes her engineers do not need, and saves it tenant-wide. From then on it appears in the Assign Roles dialog like any built-in role, and her engineers carry exactly the reach she drew.

Editing and removing custom roles is just as direct, with one safeguard. Before a custom role is deleted, Disco Parrot can tell you how many people currently hold it, so you delete knowing the blast radius rather than discovering it afterward; on delete, every assignment of that role is revoked and the change is recorded. Built-in roles cannot be deleted or edited at all. How many custom roles you can keep is set by your plan; the built-ins are always there, and custom roles are added on top up to that number.

Danger levels and the guardrails

Not every permission is equally consequential, and the model says so out loud. Every scope carries one of four danger levels, and they do real work in the editor rather than sitting as documentation.

LevelWhat it meansIn the editorLowroutine, low-risk actions, most readsno special handlingElevatedchanges shared state, like managing membersgranted like any scopeDestructivepermanently destroys datamust be re-checked before savingPlatform-onlyreserved for the platform operatornever allowed in a workspace role
Every scope carries one of four danger levels, and the editor acts on them: a destructive scope must be re-confirmed before a role will save, and a platform-only scope can never enter a workspace role at all.
  • Low: routine, low-risk actions. Most reads.
  • Elevated: higher-privilege actions that change shared state, like managing members or providers.
  • Destructive: irreversible actions, like deleting the workspace, removing a member, or merging straight to the default branch.
  • Platform-only: reserved for the platform operator, a single scope, platform.operator. It can never be put in a workspace role at all, and the built-in Workspace Operator role does not hold it either; that role owns your tooling, not the platform's.

Two guardrails follow directly from these levels. When you add a destructive scope to a custom role, the editor makes you confirm it deliberately, re-checking each newly added destructive action before the role will save, so a role never quietly acquires the power to erase data. And platform-only scopes are never on the table: the picker hides them from a workspace role, and the server refuses to save a role that somehow includes one. The point is that a role gaining a dangerous power is always an explicit act, never a side effect of a fast edit.

add_photo_alternate
Screenshot to capture
A confirmation dialog over the role editor in Disco Parrot, dark theme, titled 'Confirm destructive scopes'. Body text explaining that this role is gaining permanently destructive actions that must be confirmed before saving. A list of the newly added destructive scopes, each a row with a red 'Destructive' badge, a plain-language label, and a monospace id ('tenant.delete', 'members.remove'), and a checkbox the user must tick to acknowledge it. A primary 'Confirm and save' button that is disabled until every box is checked, beside a 'Cancel' button.
save as: public/docs-media/roles-destructive-confirm.png
Caption when added: Adding a destructive scope to a custom role makes you confirm each one before the role will save, so a role never quietly gains the power to erase data.

One more small guardrail keeps the catalog clean: a custom role's name has to be unique. Try to reuse the name of a built-in role or another custom one, and Disco Parrot stops you rather than creating a confusing duplicate.

Tenant-wide reach and resource membership

Most roles apply across the whole workspace: a Planner plans everywhere, a Viewer reads everywhere. But some access is meant to be narrow, scoped to one team, one portfolio, or one project rather than the entire workspace. That is what the membership tier is for, and it is the same mechanism teams use to grant access.

The three membership-tier levels are cumulative. A Viewer can read the resource; a Contributor can read and edit its content; a Planner can read, edit, and plan it. Each is granted on a specific resource, so a person can be a Planner on one project and a Viewer on another, with no bearing on what they can do anywhere else. A membership-tier role is only ever granted this way, on a resource, never across the whole workspace. This is how a private project opens to exactly the right people at exactly the right level, without widening anyone's reach.

A handful of scopes go finer still, down to a single named resource through an access list. The clearest example is permission to launch a sandbox from a particular sandbox profile: rather than a workspace-wide grant, it is allowed per profile, to the people on that profile's list. So Maya Rodriguez can be cleared to launch one sensitive profile and no other, her name on that profile's list and nowhere else. The pattern is the same throughout: permission is granted at the smallest scope that makes sense for the action, whether that is the whole workspace, one resource, or one profile.

How a permission check works

Watching one check from the inside explains why you can trust the roles you assign. When a request arrives, Disco Parrot resolves the scopes of the person making it from the roles they hold, then checks whether the action's required scope is among them. A self-only action is allowed when you are acting on your own thing. An entitlement-gated action is allowed only when your plan includes it (exporting the audit log, for instance, exists only on plans that include it). Everything else comes down to: do your roles, added together, contain this scope. When you hold more than one role, your scopes are the union of all of them, so roles only ever add reach, never remove it. A change to someone's roles takes effect on their next request, so granting or revoking access is effectively immediate.

Tom Asare makes this concrete. He joined as a Member, which reads across the workspace, and he was later given the Planner role too. His scopes are the two sets added together, so he reads everywhere a Member can and manages the planning surface a Planner can. When he asks to edit a plan, the check finds plans.manage in his union and allows it. When he asks to delete the workspace, the check looks for tenant.delete, finds it in neither role, and stops. His access is exactly the sum of his roles, with nothing hidden granting or denying beyond them.

A requestan action to takeYour rolesread from the workspaceUnion of scopesevery role added togetherContains therequired scope?yes allow, no denyTwo short-circuits before the union checkSelf-onlypasses when you act on your own thingEntitlement-gatedpasses only if your plan includes it
A check resolves the scopes of the person making the request from the roles they hold, then asks whether the action's required scope is among them. A self-only action passes when you act on your own thing; an entitlement-gated one passes only if your plan includes it.
info
Two properties to verify

Every route declares the permission it requires, and that rule is enforced before it ships: a route that reaches real data without declaring how it is guarded fails the test gate rather than shipping open. Nothing is protected, or left unprotected, by accident.

There is no hidden bypass. The Owner is powerful because the Owner role holds a superset of scopes, not because the code special-cases anyone. An administrator can read broadly for support and audit, but reaching into a private team's work still means holding the scope for it.

Who can manage roles

Building, cloning, editing, and deleting custom roles rides on a single scope, roles.manage, which the Owner and Admin roles hold. Everyone can see which roles exist and what they grant, because the shape of the permission model is not itself a secret; changing that shape is the administrator's job. Assigning a role to a person is the related members.manage scope, covered on the members page. A role's own detail page has a Members tab that lists everyone who holds it, and with roles.manage you can assign or remove the role right there, the same grant the members page makes from the other direction. The one role that never moves this way is Owner: it is not assigned through the role editor at all, because ownership changes hands through the deliberate transfer on the workspace.

add_photo_alternate
Screenshot to capture
The detail page of a role in Disco Parrot, dark theme, role 'Release Manager'. A header with the role name, a coloured role icon, a scope count and a member count, and an 'Edit details' button on the right. A tab strip reading 'Definition' and 'Members', with 'Members' selected. The Members tab shows an 'Assign' button and a roster of people who hold the role, each row an avatar, a name and email ('Tom Asare', 'Maya Rodriguez'), and a kebab menu offering 'Remove from role'. Above the roster, metadata rows read 'Built-in: No', 'Assignable on: Tenant-wide', and 'Members: 6'.
save as: public/docs-media/roles-detail-members-tab.png
Caption when added: A role's own page carries a Members tab. With roles.manage you assign or remove the people who hold the role right here, the same grant the members page makes from the other side.

Why roles and permissions work this way

Most tools bolt permissions on after the fact: a few coarse tiers, a scatter of special cases, and a long tail of "admin can do anything" that nobody can fully enumerate when a security review asks. Disco Parrot starts from the opposite end. Every action is a named scope from the beginning, every route declares the scope it needs, and a route that forgot fails the test gate before it can ship. The result is a permission model you can actually answer questions about: "who can delete a project," "what exactly can a Billing Manager see," "is there any way to reach this data without the scope," each has a precise answer, because the model is made of precise pieces rather than accumulated exceptions.

Roles exist so you almost never have to think in scopes. The eleven built-ins cover the common shapes, and a clone-and-adjust custom role covers the rest, so the everyday act of granting access is choosing a role, not assembling a permission set. But underneath, it is always scopes, which is why the danger levels and the destructive-confirmation step matter: the convenience of roles never hides the consequence of the actions inside them. You grant a role in one click and you can still see, and have to confirm, the moment that click would hand someone the power to erase something.

For a team lead, roles are how you give people the reach their work needs without overthinking it. Pick the built-in that fits, or clone one and trim it to a Release Manager, a QA Reviewer, whatever your team actually does, and assign it. The everyday case never makes you think about a single permission.

For an engineer, the model is why your access is exactly your access. You can hold several roles at once, be a Planner on one project and a Viewer on another, and never wonder whether some hidden tier is granting or denying you something. What you can do is the sum of your roles, and you can read it.

For an administrator, custom roles and danger levels are the tools for least privilege done quickly. You separate the tooling owner from the people manager, the finance contact from the work, the release engineer from the workspace settings, and the destructive-confirmation step keeps any of those roles from quietly becoming more dangerous than you intended.

For the person who owns security, this is the model you can attest to. Every action is a scope, every route declares its scope and is checked at boot, danger is a named property of every scope with a confirmation gate on destruction, platform-only powers can never enter a workspace role, and there is no owner bypass hiding under the surface. The question "who can do this, and how do we know" has an answer that lives in the code, not in a policy document that hopes the code agrees. For the governance view that sets this alongside what an agent is allowed to do, read approved actions and least privilege.