All field notes
ArchitectureField note 01

Why approval is a control-plane concern

A model asking itself for permission is not the same as an application-enforced decision boundary. Here is how to separate intent, authority, and execution.

01 / 05

Self-policing is not a security boundary

Agent systems are good at proposing work. They can choose tools, construct arguments, and explain why an action appears reasonable. None of those capabilities grant authority to spend money, publish data, change production, or contact a customer.

A prompt that says 'ask before deploying' is useful guidance, but guidance lives inside the same probabilistic system that selected the action. It can be omitted from context, weakened by later instructions, or bypassed by another execution path. A reliable checkpoint has to sit outside the model and before the side effect.

That makes approval a control-plane concern. The application owns the policy, records the request, identifies the decision maker, and decides whether execution may resume. The model contributes intent and context, but it never becomes the authority that validates its own request.

02 / 05

Separate intent, authorization, and execution

Production approval flows become easier to reason about when they are split into three explicit responsibilities. Each boundary should be observable and testable on its own.

This separation prevents a common failure mode: treating an approval response as a loose chat message. A durable decision should name the exact action it authorizes and be correlated to the workflow that will consume it. If the action changes materially, the old decision should not silently authorize the new one.

  • Intent: the agent describes the proposed action, its reason, and the minimum context a person needs to decide.
  • Authorization: the control plane creates an immutable approval request and accepts one terminal decision from an authorized recipient.
  • Execution: the worker validates that decision, checks that it still applies, and performs the side effect with its own idempotency protection.
03 / 05

Make the approval request a contract

An approval record should be useful to the human, the resuming workflow, and the audit trail. That means carrying a stable action name, a plain-language summary, an authorized recipient, an expiry, and a durable external identifier. Add only the non-sensitive context required to make the decision.

The request also needs lifecycle rules. Pending is not the same as approved. Expired is not rejected. Cancellation by the application is different from a decision by the recipient. Explicit states make retries and incident review far less ambiguous.

Example request
POST /v1/approvals
Authorization: Bearer appr_live_...
Idempotency-Key: deploy-prod-1042

{
  "action": "deploy_production",
  "summary": "Release version 4.2 to production",
  "recipient": "[email protected]",
  "external_id": "release-1042"
}
04 / 05

Design the unhappy paths first

The value of a control plane shows up when normal assumptions fail. A user can click twice. A webhook can arrive twice or out of order. A job can restart after the decision is recorded but before the side effect completes. An approval can expire while a worker is offline.

Build invariants for those cases instead of relying on timing. Only one terminal decision should win. Every event should have a stable identifier and a verifiable signature. The consumer should record processed event IDs and make the final action idempotent. Expired or cancelled requests must fail closed.

  • Never put a reusable API credential in a model prompt or a human decision link.
  • Never let a webhook body alone prove that a decision is authentic.
  • Never resume a consequential workflow without checking the approval ID, action, status, and correlation data.
  • Never assume a successful approval means the downstream side effect already happened.
05 / 05

A practical production checklist

Before placing a checkpoint in front of a real side effect, test the boundary as if every surrounding system were unreliable. Retry the create request. Race approve and reject. Replay a signed event. Restart the consumer between receipt and execution. Change the proposed action after approval and confirm that execution is refused.

A good approval layer does not make an agent less capable. It gives the system a clear place to transfer authority, preserve accountability, and resume safely. That is what allows teams to automate consequential work without pretending the model is also the policy engine.

Put the pattern to work

Build a checkpoint your application can trust.

Start with one approval request, then connect the signed outcome to your workflow.

Read the quick start Create a workspace