Overrides API
Endpoints for managing session-scoped policy overrides. Implements ADR-042.
Available on platform v7.1.0+. Requires an Evaluation or Enterprise license for create/revoke operations. Community tier gets read-only visibility via audit search.
POST /api/v1/overrides
Create a session-scoped override.
Request body
{
"policy_id": "pol-sqli-detector",
"policy_type": "static",
"override_reason": "Debugging prod incident INC-4521",
"tool_signature": "Bash",
"ttl_seconds": 900,
"action_override": "require_approval"
}
| Field | Type | Required | Notes |
|---|---|---|---|
policy_id | string | yes | Policy to override. System policies use the canonical sys_* ID or the legacy snake-case name (tenant_isolation, sensitive_data_control); tenant policies use the UUID. |
policy_type | string | yes | static or dynamic. |
override_reason | string | yes | 1-500 chars. Free text. Mandatory per ADR-042. |
tool_signature | string | no | Scope override to a specific tool name. Omit for tool-agnostic scope. |
ttl_seconds | int | no | Requested TTL. Clamped server-side. Default 3600 (60m), hard cap 86400 (24h), min 60 (1m). |
action_override | string | no | Replace the policy's terminal action for the duration of the override. Must be one of block, require_approval, redact, warn, log. require_approval accepted starting platform v7.2.0; earlier platforms silently dropped it. Authoring-only actions (alert, route, modify_risk) are rejected with ErrInvalidOverrideAction. |
enabled_override | bool | no | Flip a policy to disabled for the duration of the override instead of changing its action. Mutually exclusive with action_override in practice. |
Valid override actions
The canonical terminal-action list is the same whether you are setting action_override through this endpoint, through the Customer Portal's Policies → Overrides tab, or via the agent's override repository. The source of truth is platform.shared.policy.ValidOverrideActions:
| Action | Meaning when used as an override |
|---|---|
block | Deny the request (matches the policy's default). Most restrictive. |
require_approval | Route the request to the HITL approval queue. Queue operator controls (auto-approve delays, SLA escalation) are tier-gated; see HITL Approval Gates for the tier matrix. |
redact | Strip matched content from the request or response and proceed. |
warn | Allow the request and emit a warning log. |
log | Allow the request and record an audit entry. Least restrictive. |
Authoring-only actions (alert, route, modify_risk) are valid for defining a policy via POST /api/v1/policies but are rejected here. See HITL Approval Gates for the require_approval queue semantics.
Response (201)
{
"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"
}
When TTL is clamped:
{
"id": "ov-...",
"ttl_seconds": 86400,
"requested_ttl": 172800,
"clamped": true,
"clamped_reason": "exceeds_hard_cap"
}
Error responses
| Status | Meaning |
|---|---|
| 400 | Missing policy_id, policy_type, or override_reason. Reason exceeds 500 chars. |
| 401 | Auth failure |
| 403 | Policy is critical-risk (not overridable). Or policy has allow_override=false. Or tier doesn't permit override creation. |
| 404 | Policy not found |
Critical-risk rejection is enforced at the database level via trigger. allow_override=true on a critical-risk policy is coerced to false at insert time, so the server will always return 403 regardless of any race.
GET /api/v1/overrides
List active overrides scoped to the caller's tenant.
Query parameters
| Name | Type | Description |
|---|---|---|
policy_id | string | Filter to overrides for a specific policy. |
include_revoked | bool | Include revoked overrides in results. Default false. |
Response (200)
{
"overrides": [
{
"id": "ov-...",
"policy_id": "pol-sqli-detector",
"policy_type": "static",
"tenant_id": "tenant-x",
"override_reason": "Debugging",
"expires_at": "2026-04-17T13:15:00Z",
"revoked_at": null,
"created_at": "2026-04-17T13:00:00Z"
}
],
"count": 1
}
Requires X-Tenant-ID header (set automatically by the agent).
GET /api/v1/overrides/{id}
Fetch a single override by ID.
Response (200)
{
"id": "ov-...",
"policy_id": "pol-sqli-detector",
"policy_type": "static",
"tenant_id": "tenant-x",
"organization_id": "org-y",
"tool_signature": "Bash",
"override_reason": "Debugging",
"expires_at": "2026-04-17T13:15:00Z",
"created_by": "[email protected]",
"created_at": "2026-04-17T13:00:00Z",
"revoked_at": null,
"revoked_by": null
}
Error responses
| Status | Meaning |
|---|---|
| 404 | Override not found |
DELETE /api/v1/overrides/{id}
Revoke an override. Next policy evaluation after the revocation does not consult it.
Response (200)
{
"id": "ov-...",
"revoked_at": "2026-04-17T13:10:00Z"
}
Error responses
| Status | Meaning |
|---|---|
| 404 | Override not found or already revoked |
Emits an override_revoked audit event.
Audit events
Every override lifecycle event writes an entry to the audit log with its own request_type:
| Event | When |
|---|---|
override_created | Successful POST /api/v1/overrides |
override_used | Policy evaluation consumed an active override to flip a deny |
override_expired | Background cleanup detected TTL expiry |
override_revoked | Successful DELETE (user, admin, or policy-change-triggered) |
Audit record policy_details includes: override_id, policy_ids, reason, ttl_seconds, requested_ttl, clamped, and for override_used: decision_id. Search for all events tied to one override:
curl -X POST /api/v1/audit/search \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d '{"override_id": "ov-f3a81c-..."}'
Listing overrides through the canonical alias
Starting on platform v7.2.0, the agent exposes a canonical /api/v1/policy-overrides GET alias for the tenant override list. It matches the existing policy-categories / static-policies / dynamic-policies naming pattern and returns the same payload as the ADR-042 /api/v1/overrides endpoint above.
curl http://localhost:8080/api/v1/policy-overrides \
-H "Authorization: Basic $(echo -n 'client-id:client-secret' | base64)"
Response shape is identical to GET /api/v1/overrides. The alias exists because the Customer Portal's overrides handler proxies to the canonical path; callers using the canonical path against a pre-v7.2.0 agent get 404 page not found. Pre-v7.2.0 deployments can use /api/v1/static-policies/overrides for the same list.
See also
- Session Overrides concept
- Audit API with filters
decision_id,policy_name,override_id - Explainability to figure out whether an override is available before creating one
- HITL Approval Gates for the
require_approvalqueue semantics when using that action as an override
Operational Readiness Checklist
Before relying on this page in a production rollout, pair it with the core operations docs:
- Deployment Mode Matrix for self-hosted, Evaluation, Enterprise, SaaS, and In-VPC fit
- Failure Modes And Recovery for degraded-provider, connector, approval, and runtime behavior
- Capacity Planning for sizing and growth signals
- Community vs Evaluation vs Enterprise for limits, support surfaces, and upgrade triggers
