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

# Authorization

> Role-based access control in Murmur — how roles, groups, and tenant-bindings combine to decide who can do what within your tenant.

Murmur uses a catalog-based authorization model. Org admins get full access by default. For finer control, define roles, create groups, and bind them to users. This page explains the permission system end to end.

## Default access

Out of the box, Murmur provides two levels of default access based on GitHub org membership:

| GitHub role    | Murmur access                                                   |
| -------------- | --------------------------------------------------------------- |
| **Org admin**  | Full root access — all permissions on all resources             |
| **Org member** | Basic access — can spawn agents, view status, manage own agents |

These defaults work for most teams. The authorization system described below lets you customize access when you need finer control.

### Built-in grants

A few capabilities come from built-in platform bindings rather than your own configuration:

* **Change-request proposals.** Every org member and every service profile can propose, discover, and endorse change-requests (`change-request.create`, `change-request.list`, `change-request.read`, `change-request.endorse`). Endorsing is an advisory thumbs-up only — it never approves a change, and approving still requires permission to write the target resource directly.
* **Agent persona reads.** Agent runtime VMs can read and list their tenant's agent-persona catalog (`agent-persona.read`, `agent-persona.list`) so a running agent can resolve the persona it operates under. They cannot create, edit, or delete personas.

## Permission model

Permissions are expressed as `{kind}.{verb}` strings. A permission grants the ability to perform a specific verb on a specific resource kind.

### Kinds

Kinds correspond to catalog resource types and platform operations:

`agent`, `secret`, `user-secret`, `placement`, `environment`, `workspace`, `pool-config`, `machine-type`, `image`, `recipe`, `repo-config`, `agent-persona`, `flight`, `change-request`, `user`, `role`, `group`, `tenant-binding`, `alias`, `service-profile`

### Verbs

| Verb      | Description                                                                                           |
| --------- | ----------------------------------------------------------------------------------------------------- |
| `read`    | View a resource's fields and metadata                                                                 |
| `list`    | List resources of a kind                                                                              |
| `create`  | Create new resources                                                                                  |
| `edit`    | Modify existing resources                                                                             |
| `delete`  | Delete resources                                                                                      |
| `assume`  | Act as a resource (e.g., assume an agent identity)                                                    |
| `encrypt` | Encrypt tenant secret material (distinct from `read`, so a tenant-wide read grant can't also encrypt) |
| `endorse` | Add an advisory thumbs-up to a change-request (never authorizes a write)                              |

### Examples

| Permission               | Grants                                                             |
| ------------------------ | ------------------------------------------------------------------ |
| `agent.create`           | Spawn new agents                                                   |
| `agent.edit`             | Modify agent state (kill, queue messages, update tasks)            |
| `agent.read`             | View agent status and details                                      |
| `secret.read`            | Read secret metadata (not values — values require `secret.assume`) |
| `placement.edit`         | Modify placement configurations                                    |
| `workspace.delete`       | Delete workspace resources                                         |
| `change-request.create`  | Propose a change to a catalog resource behind the approval path    |
| `change-request.endorse` | Add an advisory thumbs-up to an open change-request                |

## Wildcards

Wildcards let you grant broad permissions concisely:

| Pattern    | Meaning                                                        |
| ---------- | -------------------------------------------------------------- |
| `*`        | All permissions on all kinds (root access)                     |
| `agent.*`  | All verbs on agents (read, list, create, edit, delete, assume) |
| `*.read`   | Read access on all kinds                                       |
| `*.list`   | List access on all kinds                                       |
| `secret.*` | Full access to secrets                                         |

Wildcard permissions are resolved at authorization time. If a new kind or verb is added, existing wildcards automatically cover it.

## Roles

Roles are catalog resources of kind `role`. A role defines a named set of permissions:

```yaml theme={null}
# murmur set role developer
name: developer
permissions:
  - agent.create
  - agent.edit
  - agent.read
  - agent.list
  - agent.delete
  - secret.read
  - secret.list
  - workspace.read
  - workspace.list
```

### Example roles

#### Observer (read-only)

```yaml theme={null}
name: observer
permissions:
  - "*.read"
  - "*.list"
```

Grants read and list access on all resource kinds. Cannot spawn agents, modify resources, or access secret values.

#### Developer

```yaml theme={null}
name: developer
permissions:
  - agent.create
  - agent.edit
  - agent.read
  - agent.list
  - agent.delete
  - secret.read
  - secret.list
  - user-secret.create
  - user-secret.edit
  - user-secret.read
  - user-secret.delete
  - workspace.read
  - workspace.list
  - flight.read
  - flight.list
```

Grants the ability to spawn and manage agents, read secrets, and manage personal user-secrets. Cannot modify infrastructure resources or authorization configuration.

#### Admin (full access)

```yaml theme={null}
name: admin
permissions:
  - "*"
```

Grants all permissions. Equivalent to org admin default access.

## Groups

Groups organize users for bulk role assignment. Groups are catalog resources of kind `group`:

```yaml theme={null}
# murmur set group backend-team
name: backend-team
source: static
members:
  - alice
  - bob
  - carol
```

### Group sources

| Source               | Description                                           |
| -------------------- | ----------------------------------------------------- |
| `static`             | Members are explicitly listed in the group definition |
| `github_admin`       | Automatically includes all GitHub org admins          |
| `all_tenant_members` | Automatically includes all org members                |

Dynamic sources (`github_admin`, `all_tenant_members`) automatically update as org membership changes — no manual member management required.

```yaml theme={null}
# All org members get this group's bindings
name: all-developers
source: all_tenant_members

# Only org admins get this group's bindings
name: platform-admins
source: github_admin
```

## Tenant bindings

Tenant bindings connect users or groups to roles. They are catalog resources of kind `tenant-binding`:

```yaml theme={null}
# murmur set tenant-binding backend-developers
name: backend-developers
grant:
  role_ref: developer
  group_ref: backend-team
```

### Binding a user directly

```yaml theme={null}
name: alice-admin
grant:
  role_ref: admin
  user_ref: alice
```

### Binding a group

```yaml theme={null}
name: observers-binding
grant:
  role_ref: observer
  group_ref: all_tenant_members
```

This gives every org member the `observer` role's permissions in addition to their default access.

## Per-resource grants

For fine-grained control, you can attach permissions directly to individual catalog resources. Per-resource grants restrict who can modify specific resources without affecting access to other resources of the same kind.

```yaml theme={null}
# On a specific placement resource
name: production-placement
grants:
  - role_ref: admin
    group_ref: platform-admins
```

This means only members of `platform-admins` can modify the `production-placement` resource, even if other users have general `placement.edit` permission.

## Name patterns

Grants can include a `name_pattern` that restricts the grant to resources whose name matches the pattern. This is how Murmur implements self-scoped access — a developer can manage their own secrets without accessing anyone else's.

### Variables

| Variable      | Resolves to                                      |
| ------------- | ------------------------------------------------ |
| `${provider}` | The caller's auth provider (e.g. `github_oauth`) |
| `${username}` | The caller's username (e.g. `alice`)             |

### Matching

* **Exact match** — the resolved pattern must equal the resource name
* **Prefix match** — a trailing `*` matches any resource name starting with the prefix

### Examples

```yaml theme={null}
# Developer can only manage their own user-secrets
name: user-secrets-self
grant:
  groups: ["all-developers"]
  inline:
    - user-secret.read
    - user-secret.create
    - user-secret.edit
    - user-secret.delete
  name_pattern: "${provider}/${username}/*"
```

When `alice` (authenticated via `github_oauth`) calls the API, the pattern resolves to `github_oauth/alice/*` — she can access `github_oauth/alice/GH_TOKEN` but not `github_oauth/bob/GH_TOKEN`.

```yaml theme={null}
# Developer can only read/edit their own user record
name: user-self
grant:
  groups: ["all-developers"]
  inline:
    - user.read
    - user.create
    - user.edit
  name_pattern: "${provider}/${username}"
```

This resolves to an exact match — `alice` can access `github_oauth/alice` and nothing else.

## Checking permissions

Use the CLI to check what permissions you have:

```bash theme={null}
# Check a specific permission
murmur check-permissions agent.create
```

## Authorization flow

When an API request arrives, the authorization system evaluates permissions in this order:

1. **Identify the caller** — extract identity from the token (user, agent, or service).
2. **Resolve memberships** — determine which groups the caller belongs to.
3. **Collect grants** — gather all role bindings (tenant-wide + per-resource) that apply to the caller.
4. **Flatten permissions** — expand wildcards and merge all permission sets.
5. **Check** — verify that the required `{kind}.{verb}` permission exists in the flattened set.
6. **Allow or deny** — if the permission is present, allow; otherwise, deny with a descriptive error.

Default org admin and org member access is applied before custom roles. Custom roles add to (not replace) the defaults.

***

| Type      | Page                                                                                                                      |
| --------- | ------------------------------------------------------------------------------------------------------------------------- |
| Reference | [Permission reference](/security/permission-reference) — every permission, what it enables, and its default builtin grant |
| Guide     | [Permissions guide](/security/permissions)                                                                                |
| Guide     | [Service profiles](/security/service-profile)                                                                             |
| Reference | [role](/catalog/role)                                                                                                     |
| Reference | [group](/catalog/group)                                                                                                   |
| Reference | [tenant-binding](/catalog/tenant-binding)                                                                                 |
| Reference | [`murmur check-permissions`](/cli/check-permissions)                                                                      |
| Concept   | [Authentication](/security/authentication)                                                                                |
| Concept   | [Encryption](/security/encryption)                                                                                        |
