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 |
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 |
Roles
Roles are catalog resources of kindrole. A role defines a named set of permissions:
Example roles
Observer (read-only)
Developer
Admin (full access)
Groups
Groups organize users for bulk role assignment. Groups are catalog resources of kindgroup:
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 |
github_admin, all_tenant_members) automatically update as org membership changes — no manual member management required.
Tenant bindings
Tenant bindings connect users or groups to roles. They are catalog resources of kindtenant-binding:
Binding a user directly
Binding a group
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.platform-admins can modify the production-placement resource, even if other users have general placement.edit permission.
Name patterns
Grants can include aname_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
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.
alice can access github_oauth/alice and nothing else.
Checking permissions
Use the CLI to check what permissions you have:Authorization flow
When an API request arrives, the authorization system evaluates permissions in this order:- Identify the caller — extract identity from the token (user, agent, or service).
- Resolve memberships — determine which groups the caller belongs to.
- Collect grants — gather all role bindings (tenant-wide + per-resource) that apply to the caller.
- Flatten permissions — expand wildcards and merge all permission sets.
- Check — verify that the required
{kind}.{verb}permission exists in the flattened set. - Allow or deny — if the permission is present, allow; otherwise, deny with a descriptive error.
| Type | Page |
|---|---|
| Reference | Permission reference — every permission, what it enables, and its default builtin grant |
| Guide | Permissions guide |
| Guide | Service profiles |
| Reference | role |
| Reference | group |
| Reference | tenant-binding |
| Reference | murmur check-permissions |
| Concept | Authentication |
| Concept | Encryption |