Agents
An agent is an AI actor hired onto one app group’s roster. Each agent carries its own machine
ConnectedId (Type=AI) — permissions attach to that badge, not to a borrowed key, so an
agent shows up in the same access review as the person who created it. Agents take no seat,
never appear in member lists or SCIM /Users, and are born with a TTL: creation without an
expiry is rejected, and an expired agent is automatically suspended.
Base path: /api/org/{slug}/app-groups/{groupId}/agents (authenticated). Mutations are
hard-gated by the org.agent.* scopes.
| Method · Route | Purpose | Required scope |
|---|---|---|
GET / | List the roster (joined with badge status) | membership |
GET /templates | Kind template catalog (preset scopes per kind) | membership |
POST / | Hire an agent (kind, displayName, expiresAt, scopes[]?, description?, systemPrompt?, model?) | org.agent.hire |
PUT /{agentId} | Update name / description / system prompt / model / TTL | org.agent.update |
POST /{agentId}/suspend · /{agentId}/activate | Suspend or reactivate | org.agent.suspend |
DELETE /{agentId} | Revoke — roster row retired, badge deactivated | org.agent.revoke |
What POST / (hire) does
Section titled “What POST / (hire) does”- Issues a machine badge —
ConnectedIdwithType=AI,UserId=null,MembershipType=None. - Finds or creates the role for that kind —
AGENT_{KIND}, e.g.AGENT_DESIGN. ⚠️ This role is shared by every agent of that kind in the organization. Widening it widens all of them at once. Hire a different kind when you want a different authority. - Brings the role’s templates up to the kind template — on every hire, not only the first.
Scopes the catalog has gained since the role was created are added (never removed: a scope a
person deliberately took off the role stays off), and every badge already holding the role is
re-snapshotted. The same sync runs at boot, so the roles screen and the badge never disagree
about what an agent may do.
org.agent.hireis always refused — agents do not hire agents.customhas an empty template, so acustomagent starts with no scopes at all until someone adds permissions toAGENT_CUSTOMthrough the normal roles screen. - Assigns the role to the badge (snapshotting permissions — the snapshot is the agent’s toolset).
- Gives the agent a manager — a
reportingedge from the badge to the person who hired it. This is what lets an agent file an approval: the approval line walks the requester’s reporting tree, and an agent with no one above it could never be routed. Move it under someone else on the org chart if the hirer is not the right approver. - Writes the roster row, recording
expiresAt(TTL, required, must be in the future) and the ConnectedId of the person who hired it.
The first hire of each kind in an organization takes a little longer than the rest — that is when the role, its permissions and the reporting line are created. The dashboard says so on the hire dialog.
Kind templates
Section titled “Kind templates”GET /templates returns the preset catalog. Every preset scope is a real entry in the derived
permission catalog — nothing invented:
| Kind | What it does | Writes? | Opens pull requests? |
|---|---|---|---|
design | Screens and branding (HTML/CSS) | screens | yes |
db | Table schemas and queries; reads the data | schemas, queries | yes — migrations |
api | Key issuance and webhook wiring | keys, webhooks | yes |
test | Scenario verification | nothing — read/list only | no, by design |
infra | App settings and client registration | app config | yes |
custom | Pick scopes yourself | starts with zero | only if you grant it |
A kind is a permission bundle, not an expertise
Section titled “A kind is a permission bundle, not an expertise”This is the part people most often read backwards. A design agent is not better at design than a
db agent — they are the same model. Axowl does not run the model (see
Where an agent runs); your runtime does. What a kind changes is what the
badge may touch, and that difference is real: a test agent cannot write anything, and that is
enforced on the server against its badge, not requested in a prompt. You can say “this agent cannot
change our data” and mean it literally.
So pick a kind by blast radius, not by job title. If you want an agent that reads your database
and proposes migrations, db is the bundle for that — not because it knows SQL better, but because
that is the set of doors its badge opens.
Every kind except custom also carries the employee scopes — org.work_item.list/read and
org.reporting_instance.create/read/list. They let an agent see the organization’s approval
forms, submit a document and follow its stamps. They are deliberately on test too: submitting
a request is asking, not writing. No kind carries org.reporting_instance.approval_step.* — an
agent never stamps.
harnessReady: false means the Axowl console cannot drive that kind for you yet — it does not
mean the agent is unusable. Every kind is hireable today, and its badge, scopes, TTL, gate and audit
trail work the same either way.
Who operates an agent
Section titled “Who operates an agent”Every agent is assigned to a person — its operator. The operator is who the agent borrows authority from: the gate is the intersection of what the badge holds and what that person holds, so an agent can never do more than its operator can.
The person who hires an agent becomes its first operator. PUT /{agentId}/operator hands it to
someone else — this is how an admin creates an agent and gives it to the engineer who will actually
run it.
Assigning is a transfer of authority, not a label. Two things happen at once:
- The gate re-clamps to the new operator. If they hold less, the agent can do less, immediately.
- Existing credentials for that agent are revoked. Whoever held them can no longer drive it. The new operator issues a fresh one. Without this, the previous holder could keep working under the new operator’s authority — the delegation rule inverted.
The transfer is sealed (agent.operator_assigned), so “under whose authority did this machine act”
has an answer for every point in time.
Two limits worth knowing:
- Only a person can be an operator. Machines do not delegate to machines.
- If the operator’s badge is suspended or deleted, the agent has no delegating user and every gated tool refuses. It does not quietly fall back to whoever issued the key.
An operator can issue their own agent’s credential (POST /{agentId}/credential) without holding
organization-wide key permissions — they can create one for the agent assigned to them, and nothing
else.
Where an agent runs
Section titled “Where an agent runs”Axowl issues and enforces the authority; it does not require you to run the model here.
- Your runtime (any kind). The agent’s badge is a machine
ConnectedId, so it can obtain an M2M token and call the public API directly. Scope enforcement, denial events and the TTL apply exactly as they do in the console — the gate lives on the server, not in the harness. - The Axowl console (kinds with
harnessReady: true). For teams with no agent runtime of their own, the console runs the model for you and applies the result through the same gate. Token usage is metered per badge; agents never consume a seat.
Enforcement and audit
Section titled “Enforcement and audit”- Tool gate. Every write an agent produces is checked against its badge’s permission snapshot
before being applied — the check is server-side, so it holds whether the agent runs in the Axowl
console or in your own runtime. A denial is not silent: it is recorded in the reply
(“denied — agent lacks
org.record_schema.update”) and sealed as anagent.action_deniedaudit event. - An agent can ask, but never approve. Through MCP (
axowl_request_permission,axowl_approval_submit) an agent files an approval under its own badge, exactly as a member would from the dashboard; when the last person stamps it, the form’s scopes land on the badge. Two rules are enforced where the approval line is derived, so they hold for any client: a machine requester never self-approves (a form whose risk level would auto-approve for a person is raised so that at least one human in the agent’s reporting line must stamp — if nobody there is capable, the document stayssubmitted), and stamping itself is a passkey act that only a person can perform. See MCP server. - Suspension cuts credentials. Suspending or revoking an agent flips its badge status, which immediately blocks M2M token issuance and console execution.
- Lifecycle is sealed.
agent.hired,agent.suspended(manual orexpiredvia the TTL worker) andagent.revokedare all sealed audit events — a revocation is an append-only fact, not a row someone can quietly delete. - Billing. Each console reply row carries the agent’s badge id alongside its token usage, so per-agent cost is a single aggregation over existing metering — agents are billed by usage, never by seats.
See also Service accounts (machine badges for external systems) and Roles & permissions.