Each action in duct.config.ts declares what Duct may do on behalf of a user or agent. These four fields are enforced at invoke time — before your API is called. Set them from product risk, not from HTTP convenience.
Who this applies to
Human shell only
sideEffects and sensitivityLevel still matter (ConfirmCard, prompts). agentAccessible is ignored for in-app chat.
Your own Agent API
All four fields apply. Fail-closed: agents cannot call actions unless agentAccessible is true and consent rules pass.
Third-party agents
Same as Agent API, plus requiresAuth must match a token type partners can obtain (uct_ or your delegated JWT). See Agent Access.
Cross-shell (Duct network)
Target action must be agentAccessible. Shell-level registry_visibility and intershell_enabled must also be on. See Inter-Shell.
Guest sessions
Cannot invoke requiresAuth or sideEffects actions without a user token, even in the human shell.
Concepts
Think in three independent axes plus identity. They combine at runtime — changing one field can change enforcement without touching the others.
Exposure (agentAccessible)
Is this action on the menu for automated callers? false = human shell only (agents get 403).
Mutation (sideEffects)
Does the call change state or trigger irreversible work? true = confirmation on every invocation.
Data risk (sensitivityLevel)
How sensitive is data read or written? high/critical = extra consent for agents even on read-only GETs.
Identity (requiresAuth)
Does your API need a real user session? true = agents must pass user_consent_token; guests are blocked.
Manifest ≠ backend auth
Duct enforces the manifest before proxying. Your API must still authorize the request. A permissive manifest does not replace your middleware — a strict manifest can block calls your API would have accepted.
Field reference
agentAccessible
boolean · default false after duct init · Agents and cross-shell: denied when false. Human shell: not gated by this field.
sideEffects
boolean · POST/PUT/PATCH/DELETE forced true by CLI · Human shell: ConfirmCard. Agents: 202 confirmation_required per call even with consent token.
sensitivityLevel
none | low | medium | high | critical · default low (medium for unmatched writes) · high/critical: agents need user_consent_token.
requiresAuth
boolean · no platform default · Agents without user_consent_token: 403. Guests: blocked for true.
sensitivityLevel values
none
Public, anonymous-safe data. Rare for tenant-scoped products.
low
Operational reads scoped to the user (order lists, ticket counts).
medium
User-owned business records (orders, subscriptions, team settings). Default when unsure on writes.
The CLI applies deterministic rules you cannot override by accident: write methods always get sideEffects: true; read methods get false. Sensitivity is inferred from path/name keywords (payment, profile, admin, etc.). agentAccessible stays false until you or --yes mode enables safe GETs (low sensitivity, confidence ≥ 0.85).
Exception: if your API performs a mutation on GET (e.g. GET /api/send-receipt), set sideEffects: true manually — method alone is not enough.
Enforcement by caller
Same manifest, different callers. Use this table when debugging why a path works in chat but fails for an agent.
Human shell (signed in)
Read actions run when the router selects them. sideEffects → ConfirmCard. requiresAuth → onTokenRequest forwards duct_delegated. sensitivity high/critical may prompt.
Human shell (guest)
requiresAuth or sideEffects without token → denied at Duct layer.
Same agent rules on the target action, plus intershell_enabled, registry_visibility public, optional allowedCallers.
Choosing values
Start conservative. Open exposure only after consent and confirmation flows work end-to-end. Use the scenario column as a checklist — not a copy-paste block.
When integration fails, match the response to a manifest fix. Full Agent API flows (consent URLs, execution tokens) are in Agent Access.
403 · not agent-accessible
agentAccessible is false. Set true only if the action is safe for automated callers, or route through human shell.
403 · requires user_consent_token
requiresAuth true or sensitivity high/critical without token. Agent must obtain uct_ or your delegated JWT.
403 · side-effect without consent
sideEffects true and agent lacks user_consent_token. User must approve consent scope first.
202 · confirmation_required
Expected for sideEffects on agents. Not a misconfiguration — complete human approval, retry with execution_token.
409 · consent stale
You changed method, path, sideEffects, or sensitivityLevel after the user approved. Re-run consent flow.
409 · MANIFEST_STALE
Agent token from before push/rollback. Re-exchange at /v1/agent-access-token.
401 from your API (shell works, agent fails)
requiresAuth true but your middleware only accepts session cookies, not uct_/duct_delegated from agents.
Manifest changes
Every push updates the live contract immediately. Tightening sideEffects or sensitivityLevel invalidates existing consent tokens for that action. Loosening agentAccessible exposes new surface to agents on the next invoke — there is no grace period.