Guide

Map every tool to an authorization check against the real user (or service account), not against whatever id the model invented. Prompts are steerable. Authorization checks are not.

Concept

Before you start: IAM decides what an identity may do. An agent is a new client type in that model. The model may propose refund(order, 40). The executor decides whether that user may refund $40 on that order today.

The big idea

Policy lives in code next to the executor, not only in the system prompt.

  • Capability tokens per session: can_refund, can_read_pii, can_exec_sandbox
  • Dual control for high risk: model proposes → policy engine → human approve → execute
  • Impersonation forbidden: a support agent acts as the user only through scoped APIs
  • Full audit log: actor, tool, args hash, result status, policy decision, correlation id

A useful split: the model writes the proposal; the executor enforces the rule.

A refund tool in the source required ctx.user.role in {"support_lead", "admin"} and amount_usd <= 50 without approval. Above $50, the executor returned needs_approval and a Temporal signal waited. Audit showed who approved. Chargebacks from double refunds dropped after adding idempotency keys tied to tool_use_id.

Walking through a disputed refund

A customer says "it deleted the wrong thing" or "it refunded twice." You need the audit row: actor, tool, hashed args, policy decision, who approved, run_id. Not a guess from Slack. Join user feedback back to that run_id for LLMOps.

Trajectory observability beyond app metrics:

  • Spans per model call and per tool, with parent run_id
  • Prompt and tool schema versions as attributes
  • Token and cost counters as metrics, not only logs

Common mistakes

  • Authorization only in the system prompt. A prompt injection walks around it.
  • Acting as the user with an admin token. Scope the API to that user and that resource.
  • No idempotency key on writes. Retries double-refund.

Check yourself

  1. The model proposes refund(order, 80). Who decides? The executor, using the real user's role and a threshold. Above $50 this waits for approval.
  2. Why hash tool args in the audit log? You can prove what was requested without storing raw PII in the log.

Key takeaways

  • Authorize tools against real identity. Treat agents as a new client type.
  • Keep policy in code. Prompts are not an access-control plane.
  • Audit every side effect with actor, tool, decision and correlation id.
  • Idempotency keys on writes stop retry doubles.

Further learning

The rest of the runtime — budgets, progress UX, kill switches — sits on agent infrastructure.