Skip to content

Consent System

How consent-gated operations work — auto-request in gateway, pre-flight bundling, session scope, risk levels

When to use

agent calls a capability that touches @requires_consent functions (handled transparently by the gateway)

  • consent_request
  • consent_request_resolve
  • consent_grant
  • consent_revoke
  • consent_list

Directions

When you call wb_run on a consent-gated capability, the gateway handles consent transparently:

  1. Pre-flight check — if the capability declares consent_operations, the gateway checks all of them upfront. Missing grants are bundled into ONE notification sent to all surfaces.
  2. User responds — Always / Temporary / Once / Deny on any surface (Obsidian, Telegram, Dashboard).
  3. Grants written automatically — the gateway grants all operations and executes the callable. You get the result directly.
  4. Fallback for unannotated gates — if a ConsentRequired fires at runtime (capability didn't declare it), the gateway auto-requests and retries. Max 2 retries.

What agents see

  • Success: normal result, no consent artifacts in the response
  • Denied: {"status": "denied", "operation_id": "op_xxx"}
  • Timeout: {"status": "timeout", "operation_id": "op_xxx", "request_id": "req_xxx"} — the request stays pending. Once the user approves, retry with mcp__work-buddy__wb_retry(operation_id="op_xxx"). This replays the original call without re-sending parameters.

Starting a workflow grants blanket consent for all its steps. The blanket: - Is granted by the conductor via grant_workflow_consent(run_id) on workflow start - Is revoked when the workflow completes (3-hour default TTL) - Can be overridden per-step with requires_individual_consent: true in the workflow definition, which temporarily suspends the blanket and requires per-step consent - Agents don't need to manage this — the conductor handles it automatically

Rules

  • Do NOT manually call consent_request for wb_run operations — the gateway does it for you
  • Do NOT use consent_grant to self-grant — agents must NEVER bypass consent
  • Do NOT use AskUserQuestion for consent — the notification system reaches the user everywhere
  • All grants are session-scoped (stored in data/agents//consent.db, max 24h TTL)
  • Risk levels: low, moderate, high
  • Sidecar operations not routed through wb_run (e.g., agent_spawn consent)
  • Custom flows where you need non-standard choices or context
  • Direct Python function calls outside the gateway

Architecture (for developers)

  • Capability.consent_operations: list[str] declares which @requires_consent ops a capability may trigger
  • consent.py._CONSENT_REGISTRY maps operation IDs to metadata (reason, risk, default_ttl), populated at decoration time
  • gateway.py._auto_consent_request() creates bundled notifications, polls via SurfaceDispatcher, grants on approval
  • gateway.py._check_missing_consent() checks which operations lack grants before callable invocation
  • Pre-flight runs before the callable; fallback catches ConsentRequired at runtime with max 2 retries