Agent door
Write approvals
Every agent write is held for a human by default. Nothing an agent submits changes a record until a workspace admin approves it — unless the workspace has explicitly, and provably, opted a grant out.
The agent door is human-above-the-loop for writes. When an agent calls a write tool, the door validates the request and then parks it for approval rather than applying it. The target record is byte-unchanged; a workspace admin decides whether it lands.
The default hold
A write tool call returns a pending result, not a mutation:
{
"status": "pending_approval",
"approval_id": "…",
"message": "The write was validated and is held for human approval.
Nothing has been changed yet; poll get_approval_status."
} The validated write is stored in an approval queue with a snapshot of the target as it was at request time. An admin reviews it in the dashboard and either approves or denies it.
Polling with get_approval_status
The agent polls get_approval_status with the approval_id to follow
the decision. An agent sees only its own grant's approvals. The status is one of:
| Status | Meaning |
|---|---|
pending_approval | Waiting for a human decision. |
applying | Approved; the write is being applied. |
applied | The write landed. |
denied | An admin declined it. Terminal. |
expired | The target changed, or the grant/issuer went away, before it could apply. Terminal. |
failed | An unexpected error while applying. Terminal. |
What the apply step re-checks
Approval is not a blind replay. When an admin approves a held write, the door re-verifies,
at apply time, that the grant, its trusted issuer, and the exact write capability are all
still live, and re-fetches the live target bound to the approval's own organization. If the
target changed since it was parked, or any authority behind it was revoked, the write
resolves to expired rather than applying stale intent.
Auto-approve requires a proven key binding
A workspace can opt a grant into direct apply (skip the hold), but this is deliberately hard to reach:
-
The grant must carry the
auto_approve_writesopt-in, set by a workspace admin. - and the calling session must be sender-constrained — bound to a client-held key, issuer-confirmed, with a fresh DPoP proof on the request that carries the write (see Authentication).
If the opt-in is set but the session cannot prove the key binding, the write is
held anyway — the response marks it
auto_approve_unavailable: "sender_constrained_auth_required". A bearer token
alone, a stolen assertion, or a grant flag by itself can never produce an un-held write.
Today's write surface
One write tool ships today: update_action_item, which requests a change to an
action item's lifecycle fields (status, assignee, due date, resolution notes) under the same
transition rules the dashboard enforces. See the
Tools reference.