Agent permissions
What an agent may do, who decides it, and what the person who runs it contributes.
An agent acts on your project through the CLI, the API, git, connectors, and Apps. This page explains how Beeuni decides what an agent may do.
An agent acts as itself, not as the person who started it. Its authority is its Beeuni permissions ∩ its ceiling role. Permissions alone decide, the same way they do for a person. Nobody lends an agent their own role, so the agent does the same thing whoever runs it.
The agent is the acting principal
Every agent session has two identities:
| Identity | What it decides |
|---|---|
| Acting principal — the agent | Everything on shared resources: project permissions, shared connector accounts, project secrets, Apps, git. |
| On behalf of — the person | Only that person’s own resources, and only in that person’s own private session. |
Each agent has one identity per project: a service account that Beeuni creates for it. You never hold a credential for it.
Beeuni permissions — the manifest decides
Each agent declares its Beeuni permissions in beeuni.yaml, under
agents.<name>.beeuni_permissions. The manifest on the default branch is the
source of truth.
agents:
report-writer:
beeuni_permissions: [project.file.read, project.connector.read, project.app.read]
connectors: [reports-dashboard-api]
secrets: [REPORTS_API_KEY]
apps: [reports-dashboard]
- The list is deny-by-default. An agent without
beeuni_permissionsgets none. allgrants every project permission, still capped by the ceiling.beeuni_cliis the deprecated spelling. It still validates, with a warning. Both keys with different values on one agent is a validation error.
Edit the list in Customize → Agents → the agent → Beeuni permissions. A
save commits beeuni.yaml. See the manifest reference.
The ceiling — an admin decides
The ceiling is a project role that an admin binds to the agent’s service account. The agent’s Beeuni permissions never exceed it.
- No role bound: the default agent ceiling applies. It is every project
permission except
project.credentials.issue. - A role bound: built-in
memberormanager, or a custom role. The agent keeps only the Beeuni permissions that the role also grants. - A ceiling never adds a permission. A
managerceiling does not give an agent a permission its manifest does not list.
Set the ceiling in the Access hub → Projects → the project → Add. Pick the agent under Agents and choose a role. Only admins who manage roles see agents in the picker. The project’s access list shows each agent ceiling with an Agent badge.
all means every permission
beeuni_permissions: all, "*", and any list that contains "*" mean the
same thing: every project permission. That includes project.members.manage
(add, change, or remove project members and grants) and project.delete.
One permission stays with people: project.credentials.issue (mint a project
token or a project-scoped PAT). A token an agent minted would carry no agent
permissions, so it would act outside them. The refusal answers 403 with
code: "agent_human_only_action".
An entry that is not a grantable permission is ignored at runtime and the rest
of the list still applies. beeuni validate and a change request merge report
it as an error.
project.read is the reverse: an agent always holds it inside its own project.
Running an agent lends its authority
The person who runs an agent does not cap it. So the right to run an agent is the delegation. Beeuni checks “may this person run this agent” at every entry point:
| Entry point | Required |
|---|---|
| Create, start, or prompt a session; switch its agent | The person may run the agent |
| Fire a trigger by hand | The person who fires it may run the trigger’s agent |
| Start a child session from an agent session | The person behind the parent may run the child’s agent. With no person behind it, only the same agent. |
Grant “may run” on the agent’s People tab, or in the Access hub. Agents are closed by default: a member runs an agent only when an assignment names them or one of their groups.
Personal resources stay personal
An agent session reaches a resource that one person owns only when both are true:
- The session runs on behalf of that person.
- The session is private.
Personal resources are member-owned connector connections, personal project secrets, personal provider keys, and the person’s own computer. A shared session, a trigger or channel session, and an unattended run reach none of them.
When another person prompts a private session — for example an account admin who can open members’ private sessions — the session stops acting on behalf of its creator, for good. The agent keeps its own permissions. The person who prompts never acts through someone else’s accounts.
Apps
An agent opens a restricted or private App only
when its apps: grant names the App’s slug, or is all, and its effective
permissions include project.app.read.
| App access mode | The agent is admitted when |
|---|---|
| Public | Always |
| Project | project.app.read is effective |
| Restricted or private | The slug is in apps: and project.app.read is effective |
| Password | Never |
The App’s Access dialog lists the agents with access, read from
agents.<name>.apps. Change the list on the agent’s Apps page
(Customize → Agents → the agent → Apps), with
beeuni agents scope <agent> --apps <slug,slug>, or with a change request to
beeuni.yaml. The Apps page appears only when the project has the
Apps feature flag on.
Backends
A project can own Managed project backends. Two permissions govern them.
They follow the Apps permissions: a role that holds project.app.read or
project.app.write holds the matching Backend permission.
| Permission | Allows |
|---|---|
project.backend.read |
List and inspect the project’s Backends: name, status, and URL |
project.backend.write |
Create and delete Backends, and read a Backend’s admin credentials. Implies project.backend.read |
The admin key gives full control of a Backend’s data and code, so reading it
needs project.backend.write. The built-in Manager role holds both
permissions. The built-in Member role holds project.backend.read.
Changing agents and triggers
beeuni.yaml shapes what agents may do, so whoever lands a change on the
default branch shapes agents. The same permissions decide for an agent and for
a person:
- Merging a change request needs
project.gitops.merge. - A merge that changes
beeuni.yamlalso needs the permission the direct route for that change needs:agents.*→project.agent.write;triggers→project.trigger.create,.update, or.delete;default_agent→project.agent.write. The Manager role holds these, and the role editor adds them to any role that getsproject.gitops.merge. An agent’sbeeuni_permissionsmust list them, or beall. So an agent that may only merge cannot widen itself. - An agent grants only what it holds. When an agent writes any agent’s grant
(the agent editor, the scope and secret-grant routes, or a change request
it merges), every permission, connector, secret and App the write adds must
be in the writing agent’s own effective grant. Granting
allneeds every one of them. Narrowing or removing a grant is always allowed. A refusal answers403withcode: "agent_grant_escalation". - A push straight to the default branch skips the change request. An agent
session needs
project.gitops.ref.anyand every permission in item 2. The pushed manifest cannot be checked before it lands, so the agent must also hold every grant (allpermissions, connectors, secrets and Apps). Otherwise it opens a change request. - A refusal answers
403withcode: "agent_scope_insufficient"(agent) or"project_role_insufficient"(person) and the missingaction. When the manifest cannot be read, the merge answers503withcode: "CR_GOVERNANCE_UNVERIFIED"andRetry-After. Retry it. - The ceiling is admin-only IAM state. The manifest never exceeds it.
Read a denial
Every 403 from an authorization check carries code and action:
code |
Meaning | Fix |
|---|---|---|
agent_scope_insufficient |
action is not in the agent’s Beeuni permissions |
Add it to agents.<name>.beeuni_permissions |
agent_ceiling_insufficient |
action is outside the agent’s ceiling role |
An admin raises the ceiling |
agent_not_accessible |
The person may not run this agent | Grant them the agent |
agent_grant_escalation |
The write gives an agent something the writing agent does not hold | Grant only what the writer holds, or have a person make the change |
project_role_insufficient |
The person’s own role denies action |
Change their project role |
Audit
Every agent action records three fields: actor is the agent,
on_behalf_of is the person or null, and initiator is human,
trigger, or channel. A trigger run records no person.
See it in the dashboard
Open Customize → Agents → the agent → Beeuni permissions. The What this agent can do panel shows:
- the Beeuni permissions declared in
beeuni.yaml, - the ceiling role, or Default agent ceiling,
- the one human-only permission,
project.credentials.issue, - the effective permissions: “People who may run this agent act with these permissions.”
Scope
This page applies to every agent a project declares under agents: in
beeuni.yaml. A project with no agents: map declares no governed agent, so
there is nothing to switch on. There is no switch back to the old
launcher-role model.