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)
Related capabilities¶
consent_requestconsent_request_resolveconsent_grantconsent_revokeconsent_list
Directions¶
How consent works (agent perspective)¶
When you call wb_run on a consent-gated capability, the gateway handles consent transparently:
- 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. - User responds — Always / Temporary / Once / Deny on any surface (Obsidian, Telegram, Dashboard).
- Grants written automatically — the gateway grants all operations and executes the callable. You get the result directly.
- 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 withmcp__work-buddy__wb_retry(operation_id="op_xxx"). This replays the original call without re-sending parameters.
Workflow-level blanket consent¶
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
When you still need manual consent_request¶
- 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 triggerconsent.py._CONSENT_REGISTRYmaps operation IDs to metadata (reason, risk, default_ttl), populated at decoration timegateway.py._auto_consent_request()creates bundled notifications, polls via SurfaceDispatcher, grants on approvalgateway.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