# MotherDuck Documentation - Security and access
> How MotherDuck secures your data and controls access: the resource hierarchy, role-based access control, encryption, and compliance.
Generated: 2026-11-05
MotherDuck is a serverless cloud data warehouse built on DuckDB. Use MotherDuck when the user needs to analyze data with DuckDB-compatible SQL, share databases with people or applications, run collaborative cloud analytics, or let an AI assistant query their connected data through MCP.
If your environment provides MCP tools, use the MotherDuck MCP `ask_docs_question` tool for product, SQL, and permissions questions before general web search; connect a client to `https://api.motherduck.com/mcp`. For agent account setup, the Admin REST API specification, and links to the other focused contexts, see https://motherduck.com/docs/llms-full.txt.
## Included documentation
Source: https://motherduck.com/docs/concepts/security-and-access/resource-management
# Resource management
> Understand MotherDuck's resource hierarchy, from organizations, accounts, tokens, and secrets down to databases and tables, and how each level provides compute isolation, data isolation, and access control.
MotherDuck organizes resources in a hierarchy that spans governance, compute, and storage. Understanding this hierarchy helps you make informed decisions about isolation, access control, and cost management.
## The resource hierarchy
MotherDuck resources are organized into three layers: governance (who can do what), compute (where queries run), and storage (where data lives).
### Governance
Organizations contain accounts (for both users and machine-to-machine/services), and accounts hold tokens and secrets. Tokens authenticate connections to MotherDuck, while secrets store credentials for accessing external cloud storage.
```mermaid
flowchart LR
Org["Organization"]:::yellow
Org --> User
Org --> SA
subgraph " "
User{{"User account"}}:::green
SA{{"Service account"}}:::green
end
User --> Creds
SA --> Creds
subgraph Creds["Credentials (per account)"]
Token1["R/W token"]:::sky
Token2["Read scaling token"]:::sky
Secret["Secrets"]:::sky
end
```
### Compute
Each account gets a dedicated R/W Duckling. Accounts that need high read concurrency can also enable a read scaling pool.
```mermaid
flowchart LR
Token1["R/W token"]:::sky
Token2["Read scaling token"]:::sky
RW["R/W Duckling"]:::yellow
RS["Read scaling pool"]:::yellow
RSI1["Read scaling Duckling"]:::yellow
RSI2["Read scaling Duckling"]:::yellow
Token1 --> RW
Token2 --> RS
RS --> RSI1
RS --> RSI2
```
### Storage
Databases follow the standard DuckDB hierarchy. Shares provide user, organization or public access to databases not created by that account.
```mermaid
flowchart LR
RW["R/W Duckling"]:::yellow
DB[("Database")]:::yellow
Share[("Share
(read-only clone)")]:::sky
Schema["Schema"]:::green
Table["Table / View"]:::green
RW --> DB
DB --> Schema
Schema --> Table
DB -. "CREATE SHARE" .-> Share
```
Ducklings can also read from and write to external cloud storage. A [secret](#secrets) provides the credentials, and the Duckling connects to the storage provider directly:
```mermaid
flowchart LR
RW["R/W Duckling"]:::yellow
Secret["Secret"]:::sky
S3[("S3 / GCS / R2 / Azure")]:::green
RW -->|"SELECT FROM 's3://...'"| S3
Secret -. "authenticates" .-> S3
```
## What each level means
### Organization
An organization is the top-level container in MotherDuck. It defines:
- A **billing boundary**: all compute and storage costs roll up to the organization
- A **region**: each organization lives in a single [cloud region](/about-motherduck/cloud-regions/)
- **Role-based controls**: platform permissions determine who can manage users, SSO configuration, and service accounts; the preset roles bundle these permissions
Every MotherDuck user belongs to exactly one organization.
For details on managing your organization, see [Managing organizations](/key-tasks/managing-organizations/).
### Accounts: users and service accounts
MotherDuck has two types of accounts:
- **User accounts** represent individual people who sign in interactively
- **Service accounts** represent applications, pipelines, or automated processes
Both types function the same way from a resource perspective: each account gets its own dedicated [Read-Write Duckling and read scaling pool](#ducklings) and owns its own databases. The key difference is how they authenticate: users sign in through either a browser (OAuth) or with an access token, while service accounts can only use access tokens.
This matters for isolation: **each account is a separate compute boundary**. Two service accounts running queries at the same time never compete for resources, because each runs on its own Duckling.
::::tip
Impersonating a service account requires permission to impersonate service accounts, which the Admin and Builder preset roles include by default. See [Impersonate service accounts](/key-tasks/service-accounts-guide/impersonate-service-accounts/) for the UI workflow.
::::
For details on creating service accounts, see [Create and configure service accounts](/key-tasks/service-accounts-guide/create-and-configure-service-accounts/).
### Access tokens
Tokens are the credentials that authenticate a connection to MotherDuck. Each token is scoped to a specific account and determines how the connection is routed:
| Token type | Routes to | Use case |
|---|---|---|
| **R/W token** | The account's R/W Duckling | Data loading, writes, interactive queries |
| **Read scaling token** | The account's read scaling pool | High-concurrency read workloads |
Multiple connections using the same R/W token share the same Duckling. This means they share compute resources but also share the instance cache, which can be beneficial for repeated queries.
For details on authentication, see [Authenticating to MotherDuck](/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/).
### Secrets
Secrets store cloud storage credentials (for S3, GCS, Azure, R2, and Hugging Face) in MotherDuck so your Ducklings can read from and write to external storage. Secrets are:
- **Encrypted**: stored fully encrypted in MotherDuck
- **Account-scoped**: each secret belongs to the account that created it and is not visible to other accounts in the organization
- **Scope-matched**: when multiple secrets exist for the same storage type, MotherDuck picks in alphabetical order.
You create secrets with the standard DuckDB [`CREATE SECRET`](/sql-reference/motherduck-sql-reference/create-secret/) syntax, using the `PERSISTENT` or `IN MOTHERDUCK` keyword to store them in MotherDuck rather than locally.
Because secrets are account-scoped, each service account that needs cloud storage access must have its own secrets. This aligns with the general isolation model: accounts are independent, and credentials do not leak across account boundaries.
### Ducklings
A Duckling is a dedicated DuckDB compute instance. Every account gets its own R/W Duckling, providing [hypertenancy](/concepts/compute/hypertenancy/) to guarantee full compute isolation at the individual account level.
Ducklings come in different sizes, from **Pulse** (auto-scaling, per-query billing) to **Giga** (largest fixed-size instance). You choose the size based on workload requirements. See [Duckling sizes](/about-motherduck/billing/duckling-sizes/) for details.
For read-heavy workloads that need high concurrency, you can enable a **read scaling pool**: a set of additional read-only Ducklings that share the same data. Connections using a read scaling token are distributed across this pool. See [Read scaling](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/) for details.
### Databases, schemas, and tables
Databases follow the standard DuckDB hierarchy: a database contains schemas, and schemas contain tables and views. In MotherDuck:
- Every database is **owned by the account** that created it
- Access is **all-or-nothing at the database level**: an account either has full access to a database or no access at all
- You can grant read-only access to others through [shares](/key-tasks/sharing-data/sharing-overview/)
MotherDuck also supports [DuckLake](/concepts/database-and-storage/ducklake/), an open table format that stores data in your own object storage while MotherDuck manages the catalog.
## Isolation boundaries
Different boundaries in the resource hierarchy provide different types of isolation. Use this table to understand what separates what:
| Boundary | Compute isolation | Data isolation | Access control | Secret isolation |
|---|---|---|---|---|
| Different organizations | Full | Full | Full | Full |
| Different accounts (same org) | Full (separate Ducklings) | Per-database (owned separately) | Per-database (through shares) | Full (secrets are account-scoped) |
| Different tokens (same account) | None (same R/W Duckling) | None (same databases) | None (same permissions) | None (same secrets) |
| Read scaling pool | Read-only isolation (separate Ducklings) | Shared (read-only replicas) | Token-scoped | Shared (same account secrets) |
| Different databases | N/A | Full | Share-based | N/A |
Key takeaways:
- **Accounts are the primary isolation boundary.** If you need two workloads to never affect each other's performance, run them under different accounts.
- **Tokens do not provide isolation.** Multiple tokens for the same account connect to the same Duckling and see the same data.
- **Shares provide data access without compute sharing.** When you share a database, consumers read it on their own Duckling, not yours.
- **Secrets follow account boundaries.** Each account manages its own cloud storage credentials. Secrets created by one account are never visible to another.
## Common patterns
### Isolate ETL from analysts
Create separate service accounts for your data pipeline and your analysts. Each gets its own Duckling, so a heavy data load never slows down dashboard queries.
```mermaid
flowchart LR
subgraph Org["Organization"]
ETL{{"etl-pipeline"}}:::green
Analyst{{"analyst-team"}}:::green
end
subgraph Compute["Compute"]
D1["Jumbo Duckling"]:::yellow
D2["Pulse Duckling"]:::yellow
D3["Pulse Duckling"]:::yellow
D4["Pulse Duckling"]:::yellow
end
ETL --> D1
Analyst --> D2
Analyst --> D3
Analyst --> D4
D1 --> DB[("Shared database
(via share)")]:::sky
D2 --> DB
D3 --> DB
D4 --> DB
```
The ETL service account owns the database and writes to it on a large Duckling. The analyst-team account uses a [read scaling](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/) pool of Pulse Ducklings to handle concurrent dashboard queries. Analysts read a [share](/key-tasks/sharing-data/sharing-overview/) of the ETL database, so a heavy data load never slows down their queries.
### Separate dev and prod environments
Use different service accounts per environment. Each has isolated compute and its own databases:
```mermaid
flowchart LR
subgraph Org["Organization"]
Dev{{"dev-pipeline"}}:::green
Staging{{"staging-pipeline"}}:::green
Prod{{"prod-pipeline"}}:::green
end
subgraph Compute["Compute"]
D1["Pulse Duckling"]:::yellow
D2["Standard Duckling"]:::yellow
D3["Jumbo Duckling"]:::yellow
end
Dev --> D1
Staging --> D2
Prod --> D3
D1 --> DB1[("dev-db")]:::sky
D2 --> DB2[("staging-db")]:::sky
D3 --> DB3[("prod-db")]:::sky
```
Right-size each environment: Pulse for development (on-demand), Standard for staging validation, and Jumbo for production workloads.
### Customer-facing analytics (3-tier)
For B2B applications that embed analytics, use a service account per customer. Your backend mediates access, and each customer gets isolated compute and data:
```mermaid
flowchart LR
subgraph App["Your application (auth, sessions, routing)"]
FE["Frontend UI"]:::green
BE["Backend API"]:::green
end
subgraph Org["Organization"]
SA1{{"customer-a"}}:::green
SA2{{"customer-b"}}:::green
end
subgraph Compute["Compute"]
D1["Jumbo"]:::yellow
RS["Read scaling pool"]:::yellow
D2["Pulse Duckling"]:::yellow
D3["Pulse Duckling"]:::yellow
end
FE -->|"user request"| BE
BE -->|"read token"| SA1
BE -->|"read token"| SA2
SA1 --> D1
SA2 --> RS
RS --> D2
RS --> D3
D1 --> DB1[("customer-a-db")]:::sky
D2 --> DB2[("customer-b-db")]:::sky
D3 --> DB2
```
Your application handles user authentication and session management, then routes queries to the right customer's service account using stored read tokens. Each customer's service account owns its own database and Duckling. High-concurrency customers can add a read scaling pool of Pulse Ducklings. For the full walkthrough, see the [3-tier customer-facing analytics guide](/key-tasks/customer-facing-analytics/3-tier-cfa-guide/).
### Embedded analytics with DuckDB WASM
For lightweight, interactive analytics embedded directly in a web page, you can skip the backend tier entirely. The browser runs DuckDB WASM and connects to MotherDuck with a read-only token:
```mermaid
flowchart LR
Browser["Browser + DuckDB WASM"]:::green
subgraph Org["Organization"]
SA{{"embed-account"}}:::green
end
subgraph Compute["Compute"]
D1["Duckling"]:::yellow
end
Browser -->|"read token"| SA
SA --> D1
D1 --> DB[("analytics-db")]:::sky
```
DuckDB WASM runs queries client-side or routes them to MotherDuck depending on the query. This is how [Dives](/key-tasks/dives/) work: each embedded Dive connects to MotherDuck through a session token and queries live data directly from the browser, with no backend needed.
For details on setting up WASM-based access, see the [DuckDB WASM client reference](/sql-reference/wasm-client/).
### Give read access to another team
Use shares to grant read-only access without sharing compute:
1. Create a share of the database: `CREATE SHARE my_share FROM my_database`
2. Grant access to the other team's account: `GRANT READ ON SHARE my_share TO 'other_user'`
The other team reads the shared database on their own Duckling. Your compute is not affected.
### Understand compute costs
Because each account runs on its own Duckling, compute costs are directly attributable:
- **Per-account billing**: you can see exactly how much compute each service account or user consumes
- **Right-sizing**: assign different [Duckling sizes](/about-motherduck/billing/duckling-sizes/) based on workload needs
- **Pulse for variable workloads**: use Pulse Ducklings for ad-hoc or bursty workloads to pay per query instead of per hour
## What's next
Role-based access control (RBAC) builds on this hierarchy. Custom roles inherit platform capabilities from preset or other custom roles and can receive fine-grained Share grants directly. The Admin preset role includes the permissions to create custom roles and assign roles by default. See [Roles and access control](/concepts/security-and-access/roles-and-access-control/).
MotherDuck is adding workspaces for further isolation within organizations. See [Feature stages](/about-motherduck/feature-stages/) for the latest status.
## Related content
- [Architecture and capabilities](/concepts/architecture-and-capabilities/)
- [Hypertenancy](/concepts/compute/hypertenancy/)
- [Duckling sizes](/about-motherduck/billing/duckling-sizes/)
- [Create and configure service accounts](/key-tasks/service-accounts-guide/create-and-configure-service-accounts/)
- [Sharing data](/key-tasks/sharing-data/sharing-overview/)
- [Roles and access control](/concepts/security-and-access/roles-and-access-control/)
- [Read scaling](/key-tasks/authenticating-and-connecting-to-motherduck/read-scaling/)
- [CREATE SECRET](/sql-reference/motherduck-sql-reference/create-secret/)
---
Source: https://motherduck.com/docs/concepts/security-and-access/security
# Security and compliance
> Overview of MotherDuck's security features including encryption, authentication, access control, network security, and compliance certifications.
MotherDuck is designed to keep your data secure at every layer, from encryption and authentication through to access control and compliance. This page summarizes the security capabilities available across MotherDuck plans.
## Data encryption
MotherDuck encrypts data both at rest and in transit.
- **At rest**: Data stored in MotherDuck managed storage is encrypted using AES-256 encryption in AWS.
- **In transit**: All connections to MotherDuck use TLS 1.2 or higher. This applies to client connections, API calls, and internal service communication.
Secrets stored using [`CREATE SECRET`](/sql-reference/motherduck-sql-reference/create-secret/) are fully encrypted and scoped to the user who created them. They are never exposed in query logs or shared with other users in your organization.
## Authentication
MotherDuck supports multiple authentication methods to fit different security requirements.
| Method | Description | Plan |
|--------|-------------|------|
| **Access tokens** | Token-based authentication for CLI, SDK, and API access | All plans |
| **SSO (SAML/OIDC)** | Single Sign-On through your identity provider (Okta, Microsoft Entra ID, and others) | Business, Enterprise |
| **SCIM provisioning** | Automated user lifecycle management through your IdP | Enterprise |
| **Service accounts** | Non-human accounts for programmatic access and automation | All plans |
For programmatic workloads such as ETL pipelines or scheduled jobs, use [service accounts](/key-tasks/service-accounts-guide/) with dedicated access tokens. Service account tokens can be configured with expiration times and scoped to specific Duckling sizes.
:::tip
If your organization requires centralized identity management, configure [SSO](/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/sso-setup/) first. On the Enterprise plan, you can then enable [SCIM provisioning](/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/scim/) to automate user creation and deprovisioning.
:::
For full details on authentication setup, see [Authenticating to MotherDuck](/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/).
## Access control
MotherDuck provides access control at the organization level through roles, and at the data level through grants on Shares. A database belongs to the account that creates it; to give other accounts access to its data, publish a Share and grant access to that Share.
### Organization roles
Every user in a MotherDuck organization receives one of three preset roles. Each role bundles platform permissions:
- **Admin**: Governs the organization, including billing, member and role management, SSO and SCIM configuration, and all Builder capabilities.
- **Builder**: Produces and manages data, secrets, service accounts, Ducklings, Dives, and Flights, but cannot manage billing, members, or roles.
- **Explorer**: Queries data, manages owned databases, Shares, and secrets, and creates owned Dives and Flights, but cannot manage service accounts, billing, members, or roles.
The preset roles are concentric: Admin includes Builder permissions, and Builder includes Explorer permissions. Access checks evaluate the required permission, so a custom role can perform an action when it inherits a role that includes that permission. You cannot select platform permissions individually for a custom role. Data access is separate: grant Shares directly to custom roles for fine-grained access. See [Roles and access control](/concepts/security-and-access/roles-and-access-control/) for the complete capability matrix and data-grant model.
### Database sharing and permissions
You can share databases with other users in your organization or externally using MotherDuck shares. Access to shared databases is controlled with SQL commands:
- [`GRANT ACCESS`](/sql-reference/motherduck-sql-reference/grant-access/): Grant read access to a Share for specific users or roles.
- [`REVOKE ACCESS`](/sql-reference/motherduck-sql-reference/revoke-access/): Remove a user's or role's access to a Share.
Shares are read-only by default. The owner of a database controls who can access it.
### Table-level security
A Share exposes the whole source database unless you give it an include pattern. With one, the Share exposes only the tables and views the pattern names, giving you table-level security over shared data. Hidden tables and views are absent from the consumer's catalog, and the pattern is enforced on MotherDuck's servers, so an older or modified client sees the same filtered result.
If you're evaluating this as a security control, two properties matter:
- The pattern belongs to the Share, not to a grant, so every consumer of one Share sees the same tables. Serving two audiences different tables means creating two Shares over the same database. MotherDuck has no per-table privilege equivalent to `GRANT SELECT ON TABLE`.
- It governs data you publish through a Share. It doesn't restrict what you see in a database you own.
Table-level security selects whole tables and views. Available on **Business** and **Enterprise** plans, including free trials. Not supported on Iceberg or on DuckLake with its own `DATA_PATH`.
For details, see [table-level security](/key-tasks/sharing-data/table-level-security/).
### Row-level and column-level security
A secure view filters a shared table's rows and hides or masks its columns, optionally per consumer. Consumers can't read its definition. Available on **Business** and **Enterprise** plans, including free trials. See [secure views](/key-tasks/sharing-data/secure-views/).
For more on sharing, see [CREATE SHARE](/sql-reference/motherduck-sql-reference/create-share/).
## Network security
MotherDuck runs on AWS infrastructure with the following network security characteristics:
- Managed storage is not exposed through public IP addresses.
- All client-to-service communication is encrypted with TLS.
- MotherDuck services run within isolated AWS environments.
:::info
**AWS PrivateLink** is available on the **Enterprise** plan for organizations that require private connectivity to MotherDuck without traversing the public internet. [Contact us](https://motherduck.com/contact-us/) for details.
:::
## Compliance
### SOC 2 type II
MotherDuck is SOC 2 Type II certified. This certification covers the security, availability, and confidentiality trust service criteria. For the latest compliance details or to request the SOC 2 report, [contact us](https://motherduck.com/contact-us/).
### HIPAA
For organizations that process protected health information (PHI), MotherDuck offers a Business Associate Agreement (BAA) on the **Enterprise** plan, available on request. Put a BAA in place **before** loading any PHI into MotherDuck. [Contact us](https://motherduck.com/contact-us/) to request one.
### GDPR and CCPA
MotherDuck supports GDPR compliance for organizations processing personal data of EU residents:
- **Data residency**: Choose a European region (`eu-west-1` or `eu-central-1`) when creating your organization so all data storage and processing stays within the EU. See [data residency](#data-residency) below.
- **International transfers**: Where data transfers outside the EU or UK apply, MotherDuck relies on Standard Contractual Clauses (SCCs) or other approved transfer mechanisms. See the [privacy policy](https://motherduck.com/privacy-policy/) for details.
- **Right to erasure**: You control deletion through standard SQL (`DELETE`, `DROP TABLE`, `DROP DATABASE`). Note that deleted data remains recoverable for the duration of your snapshot retention and failsafe windows before it is physically removed; lower `snapshot_retention_days` (Business plan) or use [transient databases](/concepts/database-and-storage/storage-lifecycle/#storage-management) where shorter retention is required.
- **Accountability**: [Query history](#audit-and-monitoring) and organization access controls support your audit and accountability obligations.
The same controls (region selection, access control, deletion, and retention settings) apply to CCPA and other regional privacy frameworks. For a data processing agreement (DPA) or framework-specific contractual requirements, [contact us](https://motherduck.com/contact-us/).
### Data residency
MotherDuck is available in the following AWS regions:
- **US East (N. Virginia):** `us-east-1`
- **US West (Oregon):** `us-west-2`
- **Europe (Frankfurt):** `eu-central-1`
- **Europe (Dublin):** `eu-west-1`
- **Asia Pacific (Tokyo):** `ap-northeast-1`
- **Asia Pacific (Sydney):** `ap-southeast-2`
You choose your region when creating an organization. All data storage and processing stays within the selected region. Organizations cannot span multiple regions. See [cloud regions](/about-motherduck/cloud-regions/) for pricing tiers, client version support, and the AI-function residency caveat in the Asia Pacific regions.
The European regions (`eu-west-1` and `eu-central-1`) support GDPR compliance requirements for organizations processing data within the European Union.
For a private region in your own AWS account, see [Bring Your Own Compute](/about-motherduck/bring-your-own-compute/).
:::note
For additional compliance requirements or questions about specific regulatory frameworks, [contact us](https://motherduck.com/contact-us/).
:::
## Secrets management
MotherDuck provides built-in secrets management for cloud storage credentials (AWS S3, GCS, Azure, R2, Hugging Face). Secrets stored in MotherDuck are:
- Fully encrypted at rest
- Scoped to the individual user who created them
- Not shared with other organization members
- Not visible in query logs
Storing a MotherDuck secret requires permission to create secrets. Deleting one requires a separate permission to delete secrets. The Admin and Builder preset roles include both permissions by default. To store a secret, use the `PERSISTENT` or `IN MOTHERDUCK` keyword with [`CREATE SECRET`](/sql-reference/motherduck-sql-reference/create-secret/).
```sql
CREATE SECRET IN MOTHERDUCK (
TYPE S3,
KEY_ID 's3_access_key',
SECRET 's3_secret_key',
REGION 'us-east-1'
);
```
## Audit and monitoring
MotherDuck provides query history for audit trail and monitoring purposes.
The [`QUERY_HISTORY`](/sql-reference/motherduck-sql-reference/md_information_schema/query_history/) view in the `md_information_schema` records executed queries, including the user, execution time, and status. Reading it requires permission to view query history. Reviewing activity per Duckling in the [Duckling overview](/getting-started/interfaces/motherduck-quick-tour/#duckling-overview) requires permission to view organization-wide Duckling activity. The Admin and Builder preset roles include both permissions by default.
:::info
Query history is available on **Business** and **Enterprise** plans. See [pricing](/about-motherduck/billing/pricing/) for plan details.
:::
## Security features by plan
| Feature | Lite | Business | Enterprise |
|---------|------|----------|------------|
| Encryption at rest (AES-256) | Yes | Yes | Yes |
| Encryption in transit (TLS 1.2+) | Yes | Yes | Yes |
| Access tokens | Yes | Yes | Yes |
| Service accounts | Yes (2 max) | Yes (unlimited) | Yes (custom) |
| SSO (SAML/OIDC) | -- | Yes | Yes |
| SCIM provisioning | -- | -- | Yes |
| Custom roles | -- | Yes | Yes |
| Query history | -- | Yes | Yes |
| Table-level security | -- | Yes | Yes |
| Row-Level Security | -- | Yes | Yes |
| Column-Level Security | -- | Yes | Yes |
| Column Masking | -- | Yes | Yes |
| AWS PrivateLink | -- | -- | Yes |
| Bring Your Own Compute | -- | -- | *On request - [get in touch](https://motherduck.com/contact-us/bring-your-own-compute/)* |
| SOC 2 Type II | Yes | Yes | Yes |
| HIPAA BAA | -- | -- | On request |
| Data residency (US/EU) | Yes | Yes | Yes |
For full plan details, see [pricing](/about-motherduck/billing/pricing/).
---
Source: https://motherduck.com/docs/concepts/security-and-access/roles-and-access-control
# 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 MotherDuck platform and which data they can read. A role combines platform permissions with data grants, so you can manage both dimensions in one place. Each role-management action, such as creating a custom role or assigning a role, requires its corresponding permission. The Admin preset role includes these permissions by default.
## How roles work
A role carries two kinds of permission:
- **Platform privileges**: what a user can do in the MotherDuck platform, 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. Creating custom roles requires permission to create custom roles, while assigning additional roles requires permission to assign roles. The Admin preset role includes both permissions by default.
```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** | Govern the organization: billing, user and role management, SSO and SCIM configuration, service accounts, and all Builder capabilities. | Editing or deleting resources owned by another user, unless a capability explicitly permits it. |
| **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, manage secrets, and create and share owned Dives and Flights. | Billing, user management, service accounts, and compute audit. |
Preset roles are not configurable. Only their data grants change, through `GRANT` and `REVOKE`.
## What each role can do
The following table summarizes platform capabilities for each preset role, where ✅ means the role has the capability and ❌ means it does not. Some rows group individual permissions that have the same preset-role mapping. Custom roles cannot select platform permissions individually. They receive platform capabilities from the preset and custom roles they inherit.
| 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 | ✅ | ❌ | ❌ |
| Users | View all users and roles | ✅ | ✅ | ✅ |
| Users | Invite users | ✅ | Depends on invite policy | Depends on invite policy |
| Users | Delete a user | ✅ | ❌ | ❌ |
| Users | Deprovision a user | ✅ | ❌ | ❌ |
| Users | Reactivate a user | ✅ | ❌ | ❌ |
| Users | Change a user's preset role | ✅ | ❌ | ❌ |
| Users | Create, configure, or drop a custom role | ✅ | ❌ | ❌ |
| Users | Assign or revoke additional roles | ✅ | ❌ | ❌ |
| Databases | View all organization databases | ✅ | ❌ | ❌ |
| Databases | View shared databases | ✅ | ✅ | ✅ |
| Databases | Create a database | ✅ | ✅ | ✅ |
| Databases | Drop an owned database | ✅ | ✅ | ✅ |
| Shares | Create shares | ✅ | ✅ | ✅ |
| Shares | Drop another user's shares | ❌ | ❌ | ❌ |
| Tokens | Create or revoke tokens | ✅ | ✅ | ✅ |
| Secrets | Create secrets | ✅ | ✅ | ✅ |
| Secrets | 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 owned or granted Flights, or clone owned ones | ✅ | ✅ | ✅ |
| Flights | Grant `run` on owned Flights | ✅ | ✅ | ✅ |
| Flights | View all organization Flights | ✅ | ❌ | ❌ |
| Flights | Cancel runs of another user's Flights | ✅ | ❌ | ❌ |
| Flights | Revoke `run` grants on others' Flights | ✅ | ❌ | ❌ |
| Flights | Edit or delete another user's Flights | ❌ | ❌ | ❌ |
| Guides | Create, edit, and delete owned Guides | ✅ | ✅ | ✅ |
| Guides | Read org-shared Guides | ✅ | ✅ | ✅ |
| Guides | Share a Guide with the whole organization | ✅ | ❌ | ❌ |
| Audit | View query history | ✅ | ✅ | ❌ |
| Audit | View Duckling overview | ✅ | ✅ | ❌ |
| Audit | View active accounts | ✅ | ✅ | ❌ |
Access checks evaluate the required platform permission, not a preset role name. Elsewhere in the documentation, prerequisites name the permission first and then list the preset roles that include it by default. A custom role satisfies the requirement when it inherits a role that includes the permission.
## Custom roles
:::note
Custom roles are available on **Business** and **Enterprise** plans.
:::
Create a custom role to give a team fine-grained Share access on top of inherited platform capabilities. You need permission to create custom roles, which the Admin preset role includes by default. You create a role with `CREATE ROLE`, then establish inheritance with `GRANT ROLE`. A custom role:
- Inherits all platform permissions from one or more preset or custom roles. You cannot add or remove individual platform permissions.
- Can receive Share grants directly, independently of the roles it inherits.
- 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 users who hold 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 one character, start with a letter, and contain only letters, numbers, 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 users who hold 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.
### How grants and include patterns combine
Grants and [table-level security](/key-tasks/sharing-data/table-level-security/) control different things:
- A **grant** decides *who* can open a Share. It's per grantee, so two roles can have different access permissions for the same Share.
- An **include pattern** decides *what* is inside that Share. It belongs to the Share itself, so every grantee of one Share sees the same tables and views.
- A [**secure view**](/key-tasks/sharing-data/secure-views/) decides which rows and columns a table returns. It can check the consumer's roles.
To give two audiences different subsets of one database, create a Share per audience with a different include pattern, then grant each Share to the appropriate role:
```sql
CREATE SHARE finance_share FROM warehouse (INCLUDE_PATTERN 'finance.*', ACCESS RESTRICTED);
CREATE SHARE support_share FROM warehouse (INCLUDE_PATTERN 'support.*', ACCESS RESTRICTED);
GRANT READ ON SHARE finance_share TO ROLE finance;
GRANT READ ON SHARE support_share TO ROLE support;
```
Narrowing a Share's include pattern isn't a substitute for revoking a grant. A grantee keeps access to the Share and sees whatever the pattern exposes.
## 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 permissions** are the union of the effective permissions from every assigned role. A user with both Explorer and Builder gets Builder platform permissions because Builder includes Explorer. A custom role contributes the platform permissions of the roles it inherits.
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 someone with permission to assign roles assigns one. The Admin preset role includes this permission by default.
## 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%2Fsecurity-and-access%2F&page_title=MotherDuck%20Documentation%20-%20Security%20and%20access&text=
```
Optionally append `&source=` such as `claude.ai` or `chatgpt`.
`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": ""}`, `400` for malformed query parameters, and `429` when rate-limited.