> For the complete documentation index, see [llms.txt](https://docs.e6data.com/query-engine/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.e6data.com/query-engine/guides/security/identity-and-rbac/control-plane-vs-compute-plane-permissions.md).

# Control Plane vs Compute Plane permissions

The two permission grammars in e6data - Control Plane named permissions and Compute Plane resource-and-action rules - and how roles and bindings compose them.

e6data uses **two permission grammars**. The Control Plane and Compute Plane protect different surfaces, so they keep separate vocabularies. This page explains both grammars, the built-in roles, and how a permission decision is made.

## Two grammars at a glance

|                | Control Plane                                                                    | Compute Plane                                             |
| -------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------- |
| Grammar        | `<verb>:<resource>`                                                              | `<resource>` × `<action>`                                 |
| Example        | `write:groups`, `read:invitations`                                               | catalogs × `read`, clusters × `scale`                     |
| Where defined  | Built-in, managed through the Management API                                     | Workspace roles you define                                |
| Built-in roles | Admin, Manager, Viewer                                                           | A small set of built-ins                                  |
| What it gates  | Org management: users, groups, workspaces, SSO, invitations, service credentials | Data operations: queries, catalogs, schedules, governance |

A user can be a Control Plane Admin (full org control) while having no Compute Plane permissions in a given workspace - and vice versa. A request always hits exactly one plane, and only that plane's check applies.

## Control Plane permissions

Control Plane authorization uses a fixed set of named permissions. Each is a literal `<verb>:<resource>` string, checked against the exact value - there are no wildcards.

| Resource family  | Permissions                                                                  |
| ---------------- | ---------------------------------------------------------------------------- |
| Workspaces       | `read:workspaces`, `write:workspaces`, `delete:workspaces`                   |
| Users            | `read:users`, `write:users`, `delete:users`                                  |
| Groups           | `read:groups`, `write:groups`, `delete:groups`                               |
| Service Accounts | `read:service-accounts`, `write:service-accounts`, `delete:service-accounts` |
| Roles            | `read:roles`, `manage:roles`                                                 |
| Invitations      | `read:invitations`, `write:invitations`                                      |
| Organization     | `manage:organization`                                                        |

The complete lookup, with a description of each permission, lives in the [Permissions matrix](/query-engine/reference/platform-reference/permissions-matrix.md) reference.

### Built-in roles

Every organization starts with three built-in roles:

| Role    | Intended use                                              | Permissions held                                                                                                                                                                             |
| ------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Admin   | Full org control. The first user gets this automatically. | All Control Plane permissions.                                                                                                                                                               |
| Manager | Manage workspaces and invite users.                       | `read:workspaces`, `write:workspaces`, `read:users`, `read:roles`, `read:invitations`, `write:invitations`, `read:groups`, `write:groups`, `read:service-accounts`, `write:service-accounts` |
| Viewer  | Read-only across the organization.                        | `read:workspaces`, `read:users`, `read:groups`, `read:service-accounts`, `read:roles`, `read:invitations`                                                                                    |

## Compute Plane permissions

The Compute Plane uses a more granular **resource × action** grammar, because data operations are more varied than org management. A **role** is a named bundle of **rules**, and each rule pairs one or more resources with one or more actions.

### Resources

Compute Plane resources are the things you operate inside a workspace - your catalogs, clusters, scheduled refreshes, data governance policies, service accounts, and access tokens. A wildcard (`*`) covers every resource type.

### Actions

| Family      | Actions                                                  |
| ----------- | -------------------------------------------------------- |
| CRUD        | `create`, `read`, `update`, `delete`, `list`             |
| Lifecycle   | `suspend`, `resume`, `scale`, `run`, `stop`, `configure` |
| Maintenance | `refresh`, `sync`, `compact`, `upgrade`, `revoke`        |
| Wildcard    | `*`                                                      |

Granting `*` for an action means "every defined action on the listed resources." At decision time the platform always tests a concrete action (for example, a cluster `scale`), so wildcards never cause ambiguity.

### Roles and role bindings

A role by itself grants nothing. A **role binding** attaches a role to a subject - a user, group, or service account - and optionally scopes it to a specific resource.

| Binding shape         | Scope                                       | Effect                                                                    |
| --------------------- | ------------------------------------------- | ------------------------------------------------------------------------- |
| Workspace-wide        | No scope set                                | The role applies to all resources of all matching types in the workspace. |
| Resource-type scoped  | A resource type (for example, all catalogs) | The role applies to every resource of that type, but no others.           |
| Resource-named scoped | One named resource                          | The role applies to exactly that one resource.                            |

**Why scoping matters.** Without scoping, "give the BI team read-only access to one catalog" would need a custom role that mentions only that catalog. With scoping, you reuse a generic `catalog-reader` role and create a binding whose scope names that catalog - far fewer roles to maintain.

**Expiring bindings.** A binding can carry an expiry time. After it passes, the binding is excluded from permission evaluation automatically - you don't have to delete it. This is useful for time-bound access, such as a contractor engagement.

## How a permission decision is made

On the **Compute Plane**, the authorization service evaluates every request as follows:

1. **Authenticate** - identify the caller and the groups they belong to.
2. **Gather bindings** - collect every role binding that references the caller or any of their groups.
3. **Expand to permissions** - resolve each binding's role to its resource + action rules.
4. **Filter by scope** - keep only bindings whose scope matches the target resource. A workspace-wide binding always matches; otherwise the resource type and name must match.
5. **Match the requirement** - the required permission is `<resource>.<action>`. If the granted set contains it (expanding any wildcards), allow; otherwise return `403`.

The **Control Plane** is simpler - there is no scoping, only the named-permission check: authenticate, collect the caller's permissions from their direct roles and group roles, and allow if the required permission string is in that set.

### Permissions are additive

Effective permissions are the **union** of a subject's direct role bindings and the bindings of every group they belong to. There are **no deny rules** - to restrict access, remove or narrow a binding rather than adding a negative one. Overlapping grants are harmless; the decision is simply "is the required permission in the union?"

## Subjects

Every Compute Plane binding attaches to one of three subject kinds:

| Kind            | `name` is…                          | Where the identity comes from                                        |
| --------------- | ----------------------------------- | -------------------------------------------------------------------- |
| User            | An email address (`alice@acme.com`) | Propagated from the Control Plane, or created locally on first login |
| Group           | A group name (`analytics`)          | Synced from the Control Plane, or created on the workspace           |
| Service Account | A service account identifier        | Created on the workspace; exists only there                          |

The match key is `<Kind>:<name>`, so a user binding never collides with a group of the same name.

## See also

* [Roles and permissions](/query-engine/guides/security/identity-and-rbac/roles-and-permissions.md) - built-in and custom roles in detail.
* [Permissions matrix](/query-engine/reference/platform-reference/permissions-matrix.md) - the complete permission lookup.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.e6data.com/query-engine/guides/security/identity-and-rbac/control-plane-vs-compute-plane-permissions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
