workload_identities row a CI
credential is, with kind = 'agent' — delegated a slice of a human’s own
authority, never a permission of its own. This page states exactly what is
enforced on that delegation (a rule a request cannot get past), what is
only observed (a fact surfaced for a person to review, that never refuses
anything), and what is not built.
Identity and credentials
An agent authenticates with atwa_ workload credential: a 12-character
prefix used to look the credential up, and a 52-character secret, hashed
before storage. Rotation mints a new secret for the same prefix — the
prefix is never secret and never rotates, so a caller that has cached it by
prefix keeps working through a rotation instead of failing until it is
updated out of band.
A credential has an outer lifetime of at most twelve hours. Within it, a
session bounds one run of work to a stated purpose, for at most four hours,
and never longer than the credential’s own remaining life.
Enforced: the tool allowlist
Registering an agent does not grant it anything. An agent declares a set of tools — at most 64 — and each tool names, at most, one permission it requires to be invoked. A tool is a narrowing, never a source of authority: declaring a tool that requires a permission the agent’s delegator does not currently hold is not an error, it is a tool that will be refused the moment it is invoked, on that specific call, with that refusal recorded. Every invocation goes through one gate, server-side, on every call:- Is the tool declared? An undeclared tool is refused and quarantines the agent — see below.
- Is the tool disabled? An operator can switch off a single tool without touching the rest of the agent’s inventory.
- Is the named session live — this agent’s own, not ended, not expired?
- Does the delegation, intersected with the delegator’s current role, actually hold what the tool requires? A demotion narrows this on the very next action; nothing is cached.
- Is the tool irreversible? If so, a human must have proven presence in
the last five minutes by spending a single-use approval token issued at
POST /agents/{id}/approvalsfor exactly this agent, tool and resource. The agent cannot claim a human is present itself — that field is set only by the server, only after consuming the token.
allow, step_up,
deny, quarantine or revoke — and every decision is written, permitted
or refused, to an append-only trail no application role may edit or delete.
“Was this permitted last March, and why” is answerable from that trail alone.
Enforced: blast-radius containment
Quarantine stops an agent’s entire credential, reversibly. It triggers automatically on:- an invocation naming an undeclared tool,
- an invocation naming a session that is not this agent’s own, or
- any decision the broker marks terminal with a halt obligation.
policies:manage-equivalent
permission workloads:manage), and it is never available to an agent against
itself or a peer. Only a human lifts it — there is no automatic expiry, on
the reasoning that a quarantine nobody looked at should never silently end.
Quarantine is distinct from revocation: revocation ends the credential
permanently (the kill switch, DELETE /api/v1/agents/{id}, which calls the
same workload revocation the job plane checks on every request), quarantine
suspends it while the credential survives.
Tenant and permission boundaries are structural, not merely tested as a
happy path: an agent’s authority is computed as delegation ∩ delegator's CURRENT role, is scoped to one organization by the same row-level security
every tenant table carries, and revocation is checked on the credential
itself — so a revoked agent is refused everywhere it authenticates,
including scheduled jobs on the job plane, not only interactive API calls.
Observed, not enforced: behavioural signals
GET /agents/{id}/signals reports facts computed over an agent’s own
recorded action history. Every action a signal fires on already passed
the enforcement above — a signal never refuses anything, and it is not a
second authorization path.
Three kinds are computed today:
volume_spike uses a fixed threshold, not a per-agent baseline — the
simplest rule that is still evidence rather than noise. It will produce a
false positive for an agent whose normal workload is genuinely this busy, and
a false negative for a slower one that never reaches the ceiling in a single
minute.
Limitations — stated, not implied
Two signals a mature design should eventually carry are not built:- Credential used from a new network source. An agent’s actions do not record a source address today, so there is nothing to compare “new” against.
- Action outside a declared schedule. A tool declares what it does; it does not declare when it is expected to run.
delegator_user_id, never null), and offboarding that human revokes every
workload they delegated, agents included — not merely removes them from a
listing.
