Skip to main content
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 roleMurmur access
Org adminFull root access — all permissions on all resources
Org memberBasic 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

VerbDescription
readView a resource’s fields and metadata
listList resources of a kind
createCreate new resources
editModify existing resources
deleteDelete resources
assumeAct as a resource (e.g., assume an agent identity)
encryptEncrypt tenant secret material (distinct from read, so a tenant-wide read grant can’t also encrypt)
endorseAdd an advisory thumbs-up to a change-request (never authorizes a write)

Examples

PermissionGrants
agent.createSpawn new agents
agent.editModify agent state (kill, queue messages, update tasks)
agent.readView agent status and details
secret.readRead secret metadata (not values — values require secret.assume)
placement.editModify placement configurations
workspace.deleteDelete workspace resources
change-request.createPropose a change to a catalog resource behind the approval path
change-request.endorseAdd an advisory thumbs-up to an open change-request

Wildcards

Wildcards let you grant broad permissions concisely:
PatternMeaning
*All permissions on all kinds (root access)
agent.*All verbs on agents (read, list, create, edit, delete, assume)
*.readRead access on all kinds
*.listList 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:
# 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)

name: observer
permissions:
  - "*.read"
  - "*.list"
Grants read and list access on all resource kinds. Cannot spawn agents, modify resources, or access secret values.

Developer

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)

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:
# murmur set group backend-team
name: backend-team
source: static
members:
  - alice
  - bob
  - carol

Group sources

SourceDescription
staticMembers are explicitly listed in the group definition
github_adminAutomatically includes all GitHub org admins
all_tenant_membersAutomatically includes all org members
Dynamic sources (github_admin, all_tenant_members) automatically update as org membership changes — no manual member management required.
# 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:
# murmur set tenant-binding backend-developers
name: backend-developers
grant:
  role_ref: developer
  group_ref: backend-team

Binding a user directly

name: alice-admin
grant:
  role_ref: admin
  user_ref: alice

Binding a group

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.
# 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

VariableResolves 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

# 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.
# 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:
# 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.
TypePage
ReferencePermission reference — every permission, what it enables, and its default builtin grant
GuidePermissions guide
GuideService profiles
Referencerole
Referencegroup
Referencetenant-binding
Referencemurmur check-permissions
ConceptAuthentication
ConceptEncryption