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.
- Workspace (
tenant.*): creating, renaming, deleting, and configuring the workspace itself. - Identity and sessions (
auth.*): your own logins, sessions, and self-service settings. - Planning (
planningarea): initiatives, plans, bugs, projects, portfolios, teams, sprints, goals, reports, flows, the day-to-day work. - Membership tier (
membershiparea): 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 first three are a ladder. Each one includes everything the one below it can do, and adds to it.
| Role | For | Holds |
|---|---|---|
| Member | The default for everyone who joins | Read across the workspace, plus their own self-service settings |
| Admin | Running the workspace | Everything a Member can do, plus managing members, settings, providers, and integrations |
| Owner | The single accountable seat | Everything 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.
| Role | For | The idea |
|---|---|---|
| Viewer | Stakeholders, observers, external reviewers | Read-only across the workspace, and nothing more |
| Lead | A working implementer who also coaches | A Member who can additionally see teammates' conversations and tasks and cancel their sessions, for unblocking the team |
| Planner | Whoever runs the roadmap | Read everywhere, plus full management of the planning surface: initiatives, plans, bugs, goals, sprints, reports, flows |
| Workspace Operator | Whoever owns the tooling | Manages repositories, providers, MCP servers, SDK configs, sandbox profiles, hosts, and tenant secrets, without being a full admin |
| Billing Manager | A finance or operations contact | License 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.
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.
- 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.
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.
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.
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.