> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datazone.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Policy

> Role-based access control with hierarchical permissions for fine-grained authorization

<Frame>
  <img src="https://mintcdn.com/datazone/LOvxkfnigbE8tu9y/images/covers/policy.png?fit=max&auto=format&n=LOvxkfnigbE8tu9y&q=85&s=f3128ee52f9e2331647e00447f8ba0a1" alt="Policy Cover" width="1920" height="741" data-path="images/covers/policy.png" />
</Frame>

Datazone's policy system provides flexible, fine-grained access control through role-based permissions. Policies define what actions users can perform on resources, supporting both flat and hierarchical resource patterns with explicit allow/deny rules.

### Key Features

* **Role-based**: Policies are bound to roles, not individual users
* **Hierarchical**: Support for project-scoped resources (e.g., `project:<id>:dataset:*`)
* **Explicit deny**: Deny statements override allow statements
* **Extra constraints**: Resource-specific restrictions (row-level security, column filtering, path prefixes)
* **Wildcard support**: Use `*` for flexible matching across resources and actions
* **Branch-aware**: Optional branch specification for version control

<Frame>
  <img src="https://mintcdn.com/datazone/Iq1Sp2O_esAW9egQ/images/light/development/policy_diagram.png?fit=max&auto=format&n=Iq1Sp2O_esAW9egQ&q=85&s=27e92127e1e2b5ef20635ab9859dc779" alt="Policy Diagram" width="1920" height="1076" data-path="images/light/development/policy_diagram.png" />
</Frame>

## Policy Structure

A policy is a **list of statements** that define access rules:

```json theme={null}
[
  {
    "resource": "<string>",
    "branch": "<string | null>",
    "actions": ["<string>"],
    "effect": "allow" | "deny",
    "extra_constraints": {
      "<string>": "<value>"
    }
  }
]
```

### Fields

| Field | Type | Description |
| - | - | - |
| `resource` | string | Resource pattern (supports wildcards and hierarchical patterns) |
| `branch` | string \| null | Optional branch name (defaults to `main`) |
| `actions` | array | List of actions in `<resource>:<action>` format |
| `effect` | enum | Either `"allow"` or `"deny"` |
| `extra_constraints` | object | Resource-specific constraints (optional) |

## Resource Patterns

Resources follow a hierarchical pattern that supports various levels of specificity:

### Flat Resources

| Pattern | Scope | Description |
| - | - | - |
| `*` | All | All resources in the organization |
| `dataset` | Type | Dataset type (for creation permission) |
| `dataset:*` | All instances | All dataset instances |
| `dataset:<id>` | Specific | A specific dataset by ID |

### Hierarchical Resources

Hierarchical patterns enable project-scoped permissions:

| Pattern | Scope | Description |
| - | - | - |
| `project:<id>:*` | All children | All entities within the project |
| `project:<id>:dataset:*` | Typed children | All datasets within the project |
| `project:<id>:dataset:<id>` | Specific child | Specific dataset within the project |

### Supported Resource Types

* `dataset` - Data tables in the lakehouse
* `project` - Project containers
* `view` - Virtual views over datasets
* `schedule` - Automated execution schedules
* `extract` - Data ingestion jobs
* `compute` - Compute resources
* `api_key` - API authentication keys
* `user` - User accounts
* `role` - User roles
* `notebook` - Interactive analysis notebooks
* `pipeline` - Data transformation pipelines
* `endpoint` - REST API endpoints
* `intelligent_app` - Dashboard applications
* `variable` - Environment variables
* `agent` - AI agents
* `action` - Executable actions
* `organisation` - Organisation-level administration
* `orion` - Orion logs
* `source` - Data source connections
* `notification` - Notification channels and settings
* `tag` - Resource tags
* `ruleset` - [Data Quality](/reference/development/data-quality) rulesets
* `rule_template` - [Data Quality](/reference/development/data-quality) Rule Library templates

## Actions

Actions follow the `<resource>:<action>` format and define what operations can be performed:

### Action Patterns

* `dataset:read` - Read access to datasets
* `dataset:write` - Modify datasets
* `dataset:delete` - Delete datasets
* `dataset:execute` - Execute operations on datasets
* `dataset:manage` - Full management access
* `dataset:create` - Create new datasets
* `dataset:*` - All dataset actions
* `*:read` - Read access to all resources
* `*:*` - All actions on all resources

### Common Actions

| Action | Description |
| - | - |
| `<resource>:read` | View the resource |
| `<resource>:write` | Modify the resource |
| `<resource>:delete` | Delete the resource |
| `<resource>:create` | Create new instances |
| `<resource>:execute` | Execute operations |
| `<resource>:manage` | Full control (includes all above) |
| `<resource>:*` | All actions for that resource |

### Exceptional Actions

Some resources support custom actions beyond the standard CRUD operations:

* `project:read_repository` - Read access to project code repository
* `project:write_repository` - Write access to project code repository (push commits, merge pull requests)
* `project:pr_create` - Permission to open a pull request targeting a branch
* `project:deploy` - Permission to deploy a project
* `endpoint:invoke` - Permission to call an API endpoint
* `agent:ask` - Permission to ask (query) an AI agent

## Manage Permissions and Settings Access

Some parts of the application — mainly the **Settings** area — are gated by the `manage` action rather than by `read`. A user who holds `<resource>:manage` sees that resource's menu in Settings and can view its entries.

`manage` grants **visibility only**. It does not imply creating, editing, or deleting — grant `<resource>:create`, `<resource>:write`, or `<resource>:delete` alongside it for those operations.

Previously these areas were visible only to users with `organisation:manage`. Now each resource can be delegated independently, so you can grant access to a single Settings menu without handing over organisation-wide administration.

### Resources that support `manage`

| Resource | Action | Grants access to |
| - | - | - |
| `organisation` | `organisation:manage` | Organisation-wide administration (users, roles, all Settings menus) |
| `orion` | `orion:manage` | Orion logs |
| `source` | `source:manage` | Source menu in Settings |
| `api_key` | `api_key:manage` | API Keys menu in Settings (keys are user-owned, so this also covers creating them) |
| `notification` | `notification:manage` | Notification settings and channels |
| `compute` | `compute:manage` | Compute resource configuration |
| `variable` | `variable:manage` | Variable management |
| `tag` | `tag:manage` | Tag management |

### Example: access to API keys and sources

This policy reveals the **API Keys** and **Source** menus in Settings without granting any other organisation administration:

```json theme={null}
[
  {
    "resource": "api_key",
    "actions": ["api_key:manage"],
    "effect": "allow"
  },
  {
    "resource": "source",
    "actions": ["source:manage"],
    "effect": "allow"
  }
]
```

The user can open both menus and see their contents. All other Settings menus stay hidden. Because API keys belong to the user who owns them, `api_key:manage` is enough to create and revoke their own keys. Sources are shared organisation resources, so this policy does **not** let them create or delete a source.

### Example: adding source create permission

To let the same role also create sources, add `source:create` on the resource type:

```json theme={null}
[
  {
    "resource": "api_key",
    "actions": ["api_key:manage"],
    "effect": "allow"
  },
  {
    "resource": "source",
    "actions": ["source:manage", "source:create"],
    "effect": "allow"
  }
]
```

Deleting or editing existing sources requires `source:delete` and `source:write` on the instances (for example `source:*`).

<Note>
  `organisation:manage` still implies access to every Settings menu. Use the per-resource `manage` actions when you want to delegate one area only.
</Note>

## Row-Level and Column-Level Security

Datazone supports fine-grained data access control through row-level and column-level restrictions using the `extra_constraints` field. This enables you to restrict what data users can see within a dataset or view, beyond just granting or denying access to the entire resource.

### Extra Constraints Structure

For datasets and views, you can specify columnar constraints:

```json theme={null}
{
  "resource": "dataset:<object_id>",
  "actions": ["dataset:read"],
  "effect": "allow",
  "extra_constraints": {
    "row_level_restrictions": ["<SQL condition>"],
    "column_level_restrictions": ["<column_name>"]
  }
}
```

### Fields

| Field | Type | Description |
| - | - | - |
| `row_level_restrictions` | array of strings | SQL WHERE conditions to filter rows - only matching rows are accessible (e.g., `["region = 'US'", "status = 'active'"]`) |
| `column_level_restrictions` | array of strings | Column names to allow - only these columns are accessible (e.g., `["id", "name", "email"]`) |

### Row-Level Restrictions

Row-level restrictions apply SQL conditions to filter which rows a user can access:

```json theme={null}
{
  "resource": "dataset:507f1f77bcf86cd799439011",
  "actions": ["dataset:read"],
  "effect": "allow",
  "extra_constraints": {
    "row_level_restrictions": ["country = 'USA'", "department = 'Sales'"]
  }
}
```

When a user queries this dataset, these conditions are automatically appended to the WHERE clause:

```sql theme={null}
SELECT * FROM dataset WHERE (country = 'USA') AND (department = 'Sales')
```

### Column-Level Restrictions

Column-level restrictions specify which columns users can access (allowlist):

```json theme={null}
{
  "resource": "view:507f1f77bcf86cd799439012",
  "actions": ["view:read"],
  "effect": "allow",
  "extra_constraints": {
    "column_level_restrictions": ["id", "name", "email", "department"]
  }
}
```

Only the specified columns will be accessible in query results. All other columns will be filtered out automatically.

### Combined Restrictions

You can use both row and column restrictions together:

```json theme={null}
{
  "resource": "dataset:507f1f77bcf86cd799439011",
  "actions": ["dataset:read"],
  "effect": "allow",
  "extra_constraints": {
    "row_level_restrictions": ["region = 'EMEA'"],
    "column_level_restrictions": ["id", "name", "region", "department"]
  }
}
```

<Warning>
  **Important Restrictions for Row/Column-Level Security:**

  When using `extra_constraints` with `row_level_restrictions` or `column_level_restrictions`:

  1. **Must target a specific resource**: Use `dataset:<object_id>` or `view:<object_id>`, not wildcards like `dataset:*`
  2. **Read-only actions**: Only `dataset:read` or `view:read` actions are allowed
  3. **Single action**: Statement must contain exactly one action
  4. **Single resource**: Statement must target exactly one dataset or view

  Invalid examples:

  * ❌ `"resource": "dataset:*"` (wildcard not allowed)
  * ❌ `"actions": ["dataset:read", "dataset:write"]` (multiple actions)
  * ❌ `"actions": ["dataset:*"]` (wildcard action not allowed)
  * ❌ `"actions": ["dataset:write"]` (write action not allowed)

  Valid example:

  * ✅ `"resource": "dataset:507f1f77bcf86cd799439011"` with `"actions": ["dataset:read"]`
</Warning>

## Policy Examples

### Read-Only Access

Grant read access to all resources:

```json theme={null}
[
  {
    "resource": "*",
    "actions": ["*:read"],
    "effect": "allow"
  }
]
```

### Dataset Admin

Full control over all datasets:

```json theme={null}
[
  {
    "resource": "dataset",
    "actions": ["dataset:create"],
    "effect": "allow"
  },
  {
    "resource": "dataset:*",
    "actions": ["dataset:*"],
    "effect": "allow"
  }
]
```

### Project Admin

Full control over a specific project and all its resources:

```json theme={null}
[
  {
    "resource": "project:66be5fc75158d037e9970c6d",
    "actions": ["project:*"],
    "effect": "allow"
  },
  {
    "resource": "project:66be5fc75158d037e9970c6d:*",
    "actions": ["*:*"],
    "effect": "allow"
  }
]
```

This allows the user to:

* Manage the project itself (`project:*`)
* Create and manage all child resources (datasets, notebooks, pipelines, etc.)

### Restricted Access with Deny

Allow read access to all datasets except one specific dataset:

```json theme={null}
[
  {
    "resource": "dataset:*",
    "actions": ["dataset:read"],
    "effect": "allow"
  },
  {
    "resource": "dataset:507f1f77bcf86cd799439011",
    "actions": ["dataset:read"],
    "effect": "deny"
  }
]
```

<Warning>
  Deny statements always override allow statements, regardless of order.
</Warning>

### Project-Scoped Dataset Access

Grant access to datasets within a specific project only:

```json theme={null}
[
  {
    "resource": "project:66be5fc75158d037e9970c6d:dataset:*",
    "actions": ["dataset:read", "dataset:write"],
    "effect": "allow"
  }
]
```

### Branch Protection

Repository permissions can be scoped to a branch with the `branch` field. Combined with the separation between `project:write_repository` (pushing commits and merging pull requests) and `project:pr_create` (opening a pull request), this lets you protect a branch such as `main` while keeping the rest of the project fully editable.

```json theme={null}
[
  {
    "effect": "allow",
    "actions": ["project:*"],
    "resource": "project:6a2ac2b4b45557181b0ecf04"
  },
  {
    "effect": "allow",
    "actions": ["*:*"],
    "resource": "project:6a2ac2b4b45557181b0ecf04:*"
  },
  {
    "effect": "deny",
    "actions": ["project:write_repository"],
    "resource": "project:6a2ac2b4b45557181b0ecf04",
    "branch": "main"
  }
]
```

How this evaluates:

| Operation | Result | Why |
| - | - | - |
| Push a commit to a feature branch | Allowed | The deny only applies to `main` |
| Push a commit directly to `main` | Denied | `project:write_repository` is denied on `main` |
| Create a branch from `main` | Allowed | Branch creation writes a new ref, not `main` itself |
| Open a pull request targeting `main` | Allowed | `project:pr_create` on `main` still comes from `project:*` |
| Merge a pull request into `main` | Denied | Merging requires `project:write_repository` on `main` |

The result is a familiar protected-branch workflow: contributors work on feature branches and open pull requests into `main`, but nobody with this policy can push or merge into `main` directly. Grant merge rights to a separate reviewer role that is not denied `project:write_repository` on `main`.

<Note>
  `project:pr_create` is checked against the **base** branch of the pull request — the branch being merged into. To block pull requests into `main` entirely, add `project:pr_create` to the deny statement's actions.
</Note>

### Data Analyst Role

Typical permissions for a data analyst:

```json theme={null}
[
  {
    "resource": "dataset:*",
    "actions": ["dataset:read"],
    "effect": "allow"
  },
  {
    "resource": "notebook",
    "actions": ["notebook:create"],
    "effect": "allow"
  },
  {
    "resource": "notebook:*",
    "actions": ["notebook:*"],
    "effect": "allow"
  },
  {
    "resource": "view:*",
    "actions": ["view:read"],
    "effect": "allow"
  }
]
```

## Built-in Policies

Datazone provides several built-in policies for common use cases:

### Admin Policy

Full access to all resources:

```json theme={null}
[
  {
    "resource": "*",
    "actions": ["*:*"],
    "effect": "allow"
  }
]
```

## Best Practices

### Policy Design

1. **Start restrictive**: Begin with minimal permissions and add as needed
2. **Use hierarchical patterns**: Organize permissions by project for better management
3. **Leverage deny sparingly**: Use deny for exceptions to broad allow rules
4. **Document policies**: Add clear descriptions to explain policy intent

### Role Assignment

1. **Bind to roles only**: Policies are assigned to roles, not individual users
2. **Create role hierarchies**: Use multiple roles for different permission levels (Viewer, Editor, Admin)
3. **Audit regularly**: Review policy assignments periodically

### Performance

1. **Cache aware**: Policies are cached; changes may take a few seconds to propagate
2. **Granular resources**: Use specific resource IDs when possible to reduce evaluation complexity
3. **Minimize deny statements**: They require checking all policies

### Security

1. **Principle of least privilege**: Grant only necessary permissions
2. **Explicit denies**: Use deny statements to override broad allows for sensitive resources
3. **Extra constraints**: Apply row-level and column-level security for sensitive data
4. **Path restrictions**: Use `path_prefix` constraints to sandbox project access

## Validation Rules

Policies are validated automatically to ensure correctness:

### Action Format

* Must follow `<resource>:<action>` pattern
* Both parts must be lowercase with underscores
* Wildcards allowed: `*:*`, `dataset:*`, `*:read`

**Valid:**

* `dataset:read`
* `project:*`
* `*:*`

**Invalid:**

* `dataset` (missing action)
* `Dataset:Read` (uppercase)
* `read` (missing resource)

### Resource Pattern

* Must be valid resource type or wildcard
* ObjectIds must be valid MongoDB ObjectIds
* Hierarchical patterns must follow `parent:<id>:child` format

**Valid:**

* `dataset:*`
* `project:507f1f77bcf86cd799439011`
* `project:507f1f77bcf86cd799439011:dataset:*`

**Invalid:**

* `dataset:invalid-id`
* `project::dataset:*`

### Action-Resource Matching

Actions must match the resource type they're applied to:

```json theme={null}
{
  "resource": "dataset:*",
  "actions": ["dataset:read"], // ✓ Valid
  "effect": "allow"
}
```

```json theme={null}
{
  "resource": "dataset:*",
  "actions": ["project:read"], // ✗ Invalid - mismatched types
  "effect": "allow"
}
```

Exception: Wildcard actions (`*:*`) can be used on any resource.

## Troubleshooting

### Permission Denied Errors

If you encounter permission denied errors:

1. **Check user roles**: Verify the user has the appropriate role assigned
2. **Review policy statements**: Ensure the policy includes the required action and resource
3. **Look for deny statements**: Check if an explicit deny is overriding an allow
4. **Verify resource IDs**: Ensure you're using the correct resource identifier
5. **Check cache**: Wait a few seconds for policy changes to propagate

### Hierarchical Permissions Not Working

If project-scoped permissions aren't working:

1. **Verify pattern format**: Use `project:<id>:*` not `project:*:<id>`
2. **Check parent context**: Ensure the resource creation includes project reference
3. **Review cache**: Hierarchical relationships are cached; wait 5 minutes or invalidate cache
4. **Validate ObjectIds**: All IDs must be valid MongoDB ObjectIds

### Performance Issues

If policy evaluation is slow:

1. **Reduce policy complexity**: Simplify nested hierarchies
2. **Use specific resources**: Prefer `dataset:<id>` over broad wildcards when possible
3. **Monitor cache health**: Ensure Redis is functioning properly
4. **Check database queries**: Hierarchical policies should use cache, not database

## Related Resources

<CardGroup cols={2}>
  <Card title="Roles" icon="users" href="/reference/development/role">
    Learn about role management and user assignment
  </Card>

  <Card title="Authentication" icon="lock" href="/reference/integration/authentication">
    Understand authentication and token management
  </Card>

  <Card title="API Keys" icon="key" href="/reference/development/api-key">
    Generate and manage API keys for programmatic access
  </Card>

  <Card title="Projects" icon="folder" href="/reference/development/project">
    Organize resources within projects
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.