Session Overrides
Available on platform v7.1.0+. Requires an Evaluation or Enterprise license.
Session overrides give a user a governed, time-bounded, audit-logged way to unblock themselves from a policy deny. Instead of silently disabling the plugin or editing code out-of-band, the user creates a scoped override that flips the next decision from deny to allow for a short window.
Every override is recorded in the audit log with the user's justification, the policy it overrides, the tool it's scoped to (if any), and its expiry. The full lifecycle — override_created, override_used, override_expired, override_revoked — is reconstructable from audit search alone.
When to use them
- A policy deny is a false positive in a specific debugging context.
- A developer needs short-term access to unblock a legitimate workflow.
- An admin is investigating a policy's blast radius before broader tuning.
Overrides are not for structural policy changes. If a policy's rule should be softened permanently, edit the policy — don't pile overrides on top.
Rules (ADR-042)
| Rule | Value |
|---|---|
| Default TTL | 60 minutes |
| Hard cap | 24 hours |
| Minimum TTL | 1 minute |
| Critical-risk policies | Cannot be overridden. Server rejects with 403. |
allow_override=false on any policy | Cannot be overridden. Server rejects with 403. |
| Justification | Mandatory free-text field (1-500 chars) |
| TTL enforcement | Server-side — plugin may suggest shorter; platform clamps to the hard cap. |
The critical-risk invariant is enforced at the database level via a trigger, not by convention. If a policy writer sets risk_level=critical, the trigger forces allow_override=false regardless of what the policy document says.
Creating an override
curl -X POST https://your-platform/api/v1/overrides \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{
"policy_id": "pol-sqli-detector",
"policy_type": "static",
"override_reason": "Debugging prod incident INC-4521 — temporarily allowing test SQL",
"tool_signature": "Bash",
"ttl_seconds": 900
}'
Response:
{
"id": "ov-f3a81c...",
"policy_id": "pol-sqli-detector",
"policy_type": "static",
"expires_at": "2026-04-17T13:15:00Z",
"ttl_seconds": 900,
"requested_ttl": 900,
"clamped": false,
"created_at": "2026-04-17T13:00:00Z"
}
If the TTL was clamped:
{
"id": "ov-...",
"ttl_seconds": 86400,
"requested_ttl": 172800,
"clamped": true,
"clamped_reason": "exceeds_hard_cap"
}
SDK usage
The platform-level /api/v1/overrides endpoint (new in v7.1.0) is accessible
from the OpenClaw plugin v1.3.0+ TypeScript client. SDK wrappers for
Go, Python, TypeScript, and Java that specifically target this endpoint
are planned for a follow-up batch — the existing CreatePolicyOverride SDK
methods from v5.x call an older, static-policy-only path and do not carry
the same TTL-clamping / critical-risk enforcement semantics.
For SDK callers today, use the raw HTTP contract via your SDK's transport
layer, or call the endpoint directly with curl (shown above).
OpenClaw plugin client (v1.3.0+):
const ov = await client.createOverride({
policyId: "pol-sqli-detector",
policyType: "static",
overrideReason: "Debugging",
toolSignature: "Bash",
ttlSeconds: 900,
});
MCP tool surface
The full override lifecycle is also exposed as MCP tools by the agent's MCP server at /api/v1/mcp-server. Every plugin (OpenClaw, Claude Code, Cursor, Codex) points its MCP client at the same endpoint, so these tools are available wherever an agent runs — no per-plugin tool registration is required.
| MCP tool | HTTP endpoint | Arguments |
|---|---|---|
create_override | POST /api/v1/overrides | policy_id, policy_type, override_reason, optional tool_signature, ttl_seconds |
delete_override | DELETE /api/v1/overrides/{id} | override_id |
list_overrides | GET /api/v1/overrides | optional policy_id, include_revoked |
explain_decision | GET /api/v1/decisions/{id}/explain | decision_id |
Verify registration against a live stack:
curl -s -X POST https://your-platform/api/v1/mcp-server \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"1","method":"tools/list"}' \
| jq '.result.tools[] | .name'
All four tools require an authenticated user identity; the agent threads X-User-ID / X-User-Email through from the MCP session, so plugin configuration never needs to expose it.
Scoping
An override applies to a tuple of (policy_id, user, tenant, optional tool_signature).
- Tool-agnostic (
tool_signatureomitted) — applies to every matching tool call from this user. - Tool-scoped (
tool_signatureset) — applies only when that specific tool is invoked.
A tool-scoped override beats a tool-agnostic one when both exist for the same policy and user. Inside the same scope, first-match-wins by created_at DESC.
Revoking
curl -X DELETE https://your-platform/api/v1/overrides/{override_id} \
-u "$CLIENT_ID:$CLIENT_SECRET"
Revocation is immediate. The next policy evaluation after revoked_at does not consult the override.
Revocations are triggered by:
- The user who created it (
DELETE /api/v1/overrides/:id) - An org admin (same endpoint, different auth)
- A policy change — if
allow_overrideflips tofalse, all active overrides for that policy are revoked with reasonpolicy_changed.
Auditing
Four new audit event types:
| Event | Emitted when |
|---|---|
override_created | Override record successfully created |
override_used | Policy eval applied an active override to flip a deny |
override_expired | Background cleanup detected TTL expiry |
override_revoked | User or admin explicitly revoked |
Search for everything tied to one override:
curl -X POST https://your-platform/api/v1/audit/search \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{"override_id": "ov-f3a81c..."}'
Tier split
| Tier | What's available |
|---|---|
| Community | See override context in approval prompts + audit records. Cannot create overrides. |
| Evaluation | Create session-scoped overrides up to 60m default / 24h cap. |
| Enterprise | Above + org-wide override listings, admin revocation at scale, extended audit retention, cross-plugin override history. |
See also
- Explainability — get the full decision context that precedes an override decision.
- Audit Logging — find overrides in the audit trail.
- Human in the Loop — for decisions that need a second-person approval rather than a session bypass.
