# Role-based access control (RBAC)
> Understand MotherDuck roles, including preset and custom roles, how platform privileges and data grants combine, and how permissions resolve.
Use roles to control what users can do in the console and which data they can read. Role-based access control (RBAC) gives organization admins a single primitive that governs both dimensions, so you can grant a team its console capabilities and its data access in one place.

## How roles work

A role carries two kinds of permission:

- **Platform privileges**: what a user can do in the console, such as managing users, creating shares, or resetting a Duckling.
- **Data grants**: which Shares a user can read.

These two dimensions live on the same role but do not cascade into each other. Being a Builder does not grant READ on every Share in the organization. It means a Builder has READ access to the Shares that are granted to the Builder role.

Every user is provisioned with a preset role when their account is created. Admins can then create custom roles and assign additional roles on top.

```mermaid
flowchart TD
    Admin["Admin"]:::yellow -->|inherits| Builder["Builder"]:::green
    Builder -->|inherits| Explorer["Explorer"]:::sky
    Finance["finance (custom)"]:::db -->|inherits| Explorer
```

## Preset roles

MotherDuck provides three built-in roles that build on each other: each role includes everything the one below it can do. Admin includes everything Builder can do, and Builder includes everything Explorer can do.

| Role | Purpose | Cannot do |
| --- | --- | --- |
| **Admin** | Full control: billing, user and role management, service accounts, and every platform operation. | Nothing is restricted. |
| **Builder** | Produce data: query, create and manage databases and shares, manage Ducklings, manage service accounts, create Dives and notebooks, and create Flights. | Billing, user management, role management. |
| **Explorer** | Consume data: author and run SQL, attach shared databases, create databases and shares, and create and share owned Dives. | Billing, user management, service accounts, secret management, compute audit, Flight creation. |

Preset roles are not configurable. Only their data grants change, through `GRANT` and `REVOKE`.

## What each role can do

The following table lists platform capabilities for each preset role, where ✅ means the role has the capability and ❌ means it does not. Custom roles start from their preset parent's capabilities.

| Area | Capability | Admin | Builder | Explorer |
| --- | --- | --- | --- | --- |
| Organization | Change organization display name | ✅ | ❌ | ❌ |
| Organization | Set the invite policy | ✅ | ❌ | ❌ |
| Organization | Configure SSO | ✅ | ❌ | ❌ |
| Organization | Configure SCIM | ✅ | ❌ | ❌ |
| Billing | View invoices | ✅ | ❌ | ❌ |
| Billing | Update payment method | ✅ | ❌ | ❌ |
| Billing | Select plan | ✅ | ❌ | ❌ |
| Members | View all members and roles | ✅ | ✅ | ✅ |
| Members | Invite members | ✅ | Depends on invite policy | Depends on invite policy |
| Members | Delete a member | ✅ | ❌ | ❌ |
| Members | Deprovision or reactivate a member | ✅ | ❌ | ❌ |
| Members | Change a member's roles | ✅ | ❌ | ❌ |
| Members | Create a custom role | ✅ | ❌ | ❌ |
| Members | Assign roles to members | ✅ | ❌ | ❌ |
| Databases | View all organization databases | ✅ | ❌ | ❌ |
| Databases | View shared databases | ✅ | ✅ | ✅ |
| Databases | Create a database | ✅ | ✅ | ✅ |
| Databases | Drop an owned database | ✅ | ✅ | ✅ |
| Shares | Create shares | ✅ | ✅ | ✅ |
| Shares | Drop another member's shares | ❌ | ❌ | ❌ |
| Tokens | Create or revoke tokens | ✅ | ✅ | ✅ |
| Secrets | Create or delete secrets | ✅ | ✅ | ❌ |
| Compute | Change Duckling and read scaling size | ✅ | ✅ | ✅ |
| Compute | Change read scaling pool size | ✅ | ✅ | ✅ |
| Compute | Reset a Duckling | ✅ | ✅ | ✅ |
| SQL and Dives | Author and run SQL, create notebooks | ✅ | ✅ | ✅ |
| SQL and Dives | Create, edit, and delete owned Dives | ✅ | ✅ | ✅ |
| SQL and Dives | View and clone Dives | ✅ | ✅ | ✅ |
| Service accounts | Create, delete, or impersonate a service account | ✅ | ✅ | ❌ |
| Service accounts | Update service account Ducklings | ✅ | ✅ | ❌ |
| Flights | Create Flights | ✅ | ✅ | ✅ |
| Flights | Run or clone Flights | ✅ | ✅ | ✅ |
| Flights | Edit or delete another member's Flights | ❌ | ❌ | ❌ |
| Audit | View query history | ✅ | ✅ | ❌ |
| Audit | View Duckling overview | ✅ | ✅ | ❌ |

## Custom roles

:::note
Custom roles are available on the Enterprise plan.
:::

Admins create custom roles to give a team scoped data access on top of the preset hierarchy. You create a role with `CREATE ROLE`, then establish inheritance with `GRANT ROLE`. A custom role:

- Inherits from one or more roles, each of which can be a preset role or another custom role. A custom role with no inherited role carries no platform privileges until you grant it one.
- Is additive on top of a user's preset role.
- Passes its grants down to any role that inherits it. When you grant READ on a Share to a custom role, every user who holds that role gets access, including members of other roles that inherit it.

You change what a role inherits at any time with `GRANT ROLE` and `REVOKE ROLE`, so a role is never permanently tied to a parent. MotherDuck rejects grants that would create a cycle or exceed the maximum hierarchy depth. To keep permission resolution predictable, keep custom role hierarchies shallow, ideally two to three levels.

Role names must be at least three characters, start with a letter, and contain only letters, numbers, hyphens, and underscores. Names are case-insensitive and stored in lowercase. `admin`, `builder`, and `explorer` are reserved and cannot be created or dropped.

For the commands, see [CREATE ROLE](/sql-reference/motherduck-sql-reference/access-control/create-role/) and [GRANT ROLE](/sql-reference/motherduck-sql-reference/access-control/grant-role/).

## How data access grants flow

When you grant READ on a Share to a preset role, everyone at that trust level and above receives access. Because the preset roles are concentric, a grant to a lower role is inherited by every role above it. A grant to a custom role reaches everyone who holds that role, including members of any role that inherits it.

| Grant target | Who gets access |
| --- | --- |
| `GRANT READ ON SHARE ... TO ROLE explorer` | Explorer, Builder, Admin, and any custom role that inherits from Explorer |
| `GRANT READ ON SHARE ... TO ROLE builder` | Builder, Admin, and any custom role that inherits from Builder |
| `GRANT READ ON SHARE ... TO ROLE admin` | Admin, and any custom role that inherits from Admin |
| `GRANT READ ON SHARE ... TO ROLE finance` | Everyone who holds `finance`, plus any role that inherits `finance` |

A useful rule: grant to the lowest role that should have access, and every role that inherits it receives access automatically.

## Users with multiple roles

A user can hold several roles at once. Their permissions resolve as the union of all assigned roles:

- **Data access** is the union of every grant across all of their roles.
- **Platform privileges** come from the highest preset role in the set. A user with both Explorer and Builder gets Builder platform privileges.

Revoking a role removes only the access that role provided. A user who has data through another assigned role keeps it.

## Users with no roles

A user becomes roleless if all their roles are revoked. A roleless user can sign in but sees an empty state and cannot access any data until an admin assigns a role.

## Public share links

Public share links ("anyone with the link") sit outside the role model. They grant access regardless of the role grants on that Share.

## Migration from the earlier role model

Organizations created before role-based access control keep their access:

- Existing admins remain **Admin**, with no change.
- Existing members become **Explorer**, with no change to what they can do.

## Related

- [Manage roles and access for your organization](/key-tasks/managing-organizations/managing-roles/)
- [Managing organizations](/key-tasks/managing-organizations/)
- [Access control SQL reference](/sql-reference/motherduck-sql-reference/access-control/)
- [Sharing data](/key-tasks/sharing-data/sharing-overview/)


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `GET https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

URL-encode query parameter values and send a GET request:

```text
GET https://motherduck.com/docs/api/feedback/agent?page_path=%2Fconcepts%2Froles-and-access-control%2F&page_title=Role-based%20access%20control%20%28RBAC%29&text=<url-encoded user feedback, max 2000 characters>
```

Optionally append `&source=<url-encoded interface identifier>` such as `claude.ai` or `chatgpt`.

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed query parameters, and `429` when rate-limited.
