Skip to content

Replace the tenant's policy document

PUT
/v1/policy
curl --request PUT \
--url https://example.com/v1/policy \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "default": "allow", "on_error": "allow", "rules": [ { "action": "allow", "match": { "agents": [ "example" ], "tools": [ "example" ], "max_body_bytes": 1, "rate_per_min": 1 } } ] }'

A wholesale replace, not a partial patch: every call sets default, on_error, and rules to exactly what is given, including replacing rules with an empty list. The document is validated before it replaces the stored policy; a malformed document is rejected with 400 and never reaches the store (spec 0009).

Media typeapplication/json

The PUT /v1/policy request body: a wholesale replacement of the tenant’s policy (spec 0009). default and on_error are both required on every call — there is no partial-patch “leave unchanged” state.

object
default
required

Applied when no rule matches. Operator-set, not hardcoded fail-closed.

string
Allowed values: allow warn deny
on_error
required

Applied when the evaluation engine or store errors.

string
Allowed values: allow warn deny
rules
required
Array<object>

One ordered entry in a policy document’s rule list, evaluated in order (spec 0009).

object
action
required
string
Allowed values: allow warn deny
match
required

Conditions a rule matches an in-flight call against (spec 0009). Every populated field must match for the rule to apply; an absent/empty field is not a match condition (matches any value). tools is meaningless for protocol=http agents (route-level only).

object
agents

Matches the calling agent’s ID. Absent/empty matches any agent.

Array<string>
tools

Matches the parsed MCP tool name, supporting a single trailing * wildcard (e.g. read_*). Absent/empty matches any tool.

Array<string>
max_body_bytes

Matches when the request body size is at least this many bytes.

integer
rate_per_min

Matches when the caller’s observed rate exceeds this many requests per minute.

integer

The replaced document’s new version and timestamp.

Media typeapplication/json

The PUT /v1/policy response — version and timestamp only, not the full document just written.

object
version
required
integer
updated_at
required
string format: date-time
Examplegenerated
{
"version": 1,
"updated_at": "2026-04-15T12:00:00Z"
}

Malformed request body — unknown action, ill-formed match condition, or missing default/on_error.

Media typeapplication/json

The uniform error body for all 4xx responses that carry one.

object
error
required

A coarse, caller-safe message. Never contains internal state (invariant

string
Examplegenerated
{
"error": "example"
}

Missing or invalid bearer token, or the token’s tenant/user claims are absent. No body.

An unexpected server-side error. No body (internal detail is never returned to callers, invariant