Skip to main content

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.

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.

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, 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)

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

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

Permission grants can use name patterns to scope access to resources matching a pattern:
PatternMatches
${username}Resources named with the current user’s GitHub username
dev-*Resources with names starting with dev-
${username}/*Resources under the user’s namespace
Name patterns are useful for restricting agent permissions to a user’s own agents:
name: self-service-agents
permissions:
  - agent.create
  - agent.edit:${username}/*
  - agent.read:${username}/*
  - agent.delete:${username}/*
This grants the ability to create agents and manage only their own agents (agents under their username namespace).

Checking permissions

Use the CLI to check what permissions you (or another user) have:
# Check your own permissions
murmur check-permissions

# Check a specific permission
murmur check-permissions agent.create

# Check permissions for another user (requires admin access)
murmur check-permissions --user alice
The output lists all effective permissions after resolving roles, groups, bindings, and wildcards.

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.