Skip to main content

toolpolicy API

Table of Contents

Top

upsquad/toolpolicy/v1/toolpolicy.proto

CreateToolPolicyRequest

CreateToolPolicyRequest seeds a new policy. org_id / created_by are taken from scope.

FieldTypeLabelDescription
unit_idstringunit_id is the team scope; "" creates an org-wide policy (L4+ only).
server_idstringserver_id is the MCP server scope; "" = every server.
tool_namestringtool_name is the governed tool, or "*" for every tool.
policy_kindPolicyKindpolicy_kind selects the policy shape (required; UNSPECIFIED rejected).
cel_exprstringcel_expr is the portable CEL expression (required for argument_rule).
actionPolicyActionaction fires on match (required for argument_rule; ignored otherwise).
filter_specFilterSpecfilter_spec is the response-filter body (required for response_filter).
enabledboolenabled controls whether the policy is live on create (default true when unset is handled server-side — the field default false is overridden to true unless explicitly disabled via Update).
agent_idstringagent_id optionally narrows the policy to a single agent (ADR-0022 #1736); "" = team/org scope. When set it must name an agent in the caller's org (validated server-side) — it is an additional narrowing WITHIN the unit_id authority, not a replacement for it.

CreateToolPolicyResponse

CreateToolPolicyResponse echoes the persisted policy with id assigned.

FieldTypeLabelDescription
policyToolPolicypolicy is the stored row.

DeleteToolPolicyRequest

DeleteToolPolicyRequest soft-deletes an owned policy.

FieldTypeLabelDescription
idstringid targets the policy to delete.

DeleteToolPolicyResponse

DeleteToolPolicyResponse is empty on success.

FilterSpec

FilterSpec is the response_filter policy body (persisted as the mcp_tool_policies.filter_spec JSONB). Mirrors internal/guardrails/response.FilterSpec. All fields are optional; a zero spec is a no-op.

FieldTypeLabelDescription
detect_piibooldetect_pii redacts (or blocks) platform PII classes (email, SSN, phone …).
detect_secretsbooldetect_secrets redacts (or blocks) platform secret classes (API keys …).
regexesstringrepeatedregexes are caller-supplied patterns to redact/block; invalid patterns are rejected at write time.
blockboolblock, when true, causes ANY match to block the whole response rather than redact; when false, matches are replaced with placeholder.
max_bytesint32max_bytes caps the response size (0 disables the cap); applied last.
placeholderstringplaceholder overrides the default "[REDACTED]" replacement token.

ListToolPoliciesRequest

ListToolPoliciesRequest narrows the policy list. org_id is implicit (scope).

FieldTypeLabelDescription
unit_idstringunit_id is the caller's team org_unit whose home chain drives the inherited set; "" lists the org-wide rows only (no ancestors above the org).
server_idstringserver_id optionally narrows to one MCP server (plus any-server rows); "" returns policies for every server.
tool_namestringtool_name optionally narrows to one tool (plus '*' any-tool rows); "" returns policies for every tool.
agent_idstringagent_id optionally narrows to the guardrails that bind ONE agent (ADR-0022 #1736). When "" the list returns EVERY row in scope, INCLUDING every agent-scoped child row (each carrying its own agent_id) so the team/registry view can surface 'these agent overrides exist'. When set it mirrors the resolver's agent-scope read: the response is narrowed to the rows that would actually bind that agent — its own agent-scoped rows PLUS the team/org-wide (agent_id-less) rows that cascade down to it; OTHER agents' rows are excluded. It is an additional narrowing WITHIN the unit_id authority, not a replacement for it.

ListToolPoliciesResponse

ListToolPoliciesResponse is the resolved policy set (own + inherited).

FieldTypeLabelDescription
policiesToolPolicyrepeatedpolicies is the flat list; own rows come first, then inherited rows.

ToolPolicy

ToolPolicy is one mcp_tool_policies row in wire form, plus cascade provenance.

FieldTypeLabelDescription
idstringid is the policy UUID (server-assigned on create).
org_idstringorg_id is the owning tenant (echoed for the client; taken from scope on write, never trusted from the request body).
unit_idstringunit_id is the team org_unit scope; "" = org-wide.
server_idstringserver_id is the MCP server scope; "" = every server.
tool_namestringtool_name is the tool this policy governs, or "*" for every tool on the scoped server(s).
policy_kindPolicyKindpolicy_kind discriminates argument_rule vs response_filter.
cel_exprstringcel_expr is the portable CEL boolean expression (argument_rule only).
actionPolicyActionaction fires when an argument_rule matches (argument_rule only).
filter_specFilterSpecfilter_spec is the response-filter body (response_filter only).
enabledboolenabled gates whether the policy is live; disabled rows are still returned so the editor can toggle them.
inheritedboolinherited is true when this row is NOT owned by the caller's own team — it cascades down from an ancestor team or is org-wide. Inherited rows are READ-ONLY from a child team (the UI renders them locked).
inherited_from_unit_idstringinherited_from_unit_id names the ancestor org_unit this inherited row belongs to; "" when the inherited row is org-wide (unit_id IS NULL). Empty for rows the caller owns (inherited = false).
created_atgoogle.protobuf.Timestampcreated_at is the wall-clock insert time.
updated_atgoogle.protobuf.Timestampupdated_at is the wall-clock time of the last mutation.
agent_idstringagent_id is the optional agent scope (ADR-0022 #1736); "" = team/org scope. A non-empty agent_id narrows the policy to a single agent — an agent-scoped row outranks a team-scoped row, which outranks an org-wide row, WITHIN a severity; the deny floor is scope-independent so an agent-scoped escalate can never soften a team/org deny.

UpdateToolPolicyRequest

UpdateToolPolicyRequest replaces the editable fields of an owned policy. The key + policy_kind are immutable; only rows the caller owns may be updated.

FieldTypeLabelDescription
idstringid targets the policy to update.
cel_exprstringcel_expr is the new CEL expression (applied for argument_rule rows).
actionPolicyActionaction is the new match action (applied for argument_rule rows).
filter_specFilterSpecfilter_spec is the new response-filter body (applied for response_filter rows).
enabledboolenabled is the new enable bit.

UpdateToolPolicyResponse

UpdateToolPolicyResponse echoes the updated policy.

FieldTypeLabelDescription
policyToolPolicypolicy is the stored row after update.

PolicyAction

PolicyAction is the outcome when an argument_rule MATCHES. Mirrors mcp_tool_policies.action and internal/guardrails.Action. Unused (UNSPECIFIED) for response_filter rows.

NameNumberDescription
POLICY_ACTION_UNSPECIFIED0POLICY_ACTION_UNSPECIFIED is the proto3 zero value; the only valid value for a response_filter, rejected for an argument_rule.
POLICY_ACTION_DENY1POLICY_ACTION_DENY blocks the call with a structured refusal + audit row.
POLICY_ACTION_ESCALATE2POLICY_ACTION_ESCALATE routes the call to HITL approval.

PolicyKind

PolicyKind discriminates the two policy shapes. Mirrors mcp_tool_policies.policy_kind and internal/guardrails.PolicyKind.

NameNumberDescription
POLICY_KIND_UNSPECIFIED0POLICY_KIND_UNSPECIFIED is the proto3 zero value; rejected at the edge.
POLICY_KIND_ARGUMENT_RULE1POLICY_KIND_ARGUMENT_RULE carries a portable CEL boolean over the tool-call arguments, evaluated BEFORE the upstream call; on match action fires.
POLICY_KIND_RESPONSE_FILTER2POLICY_KIND_RESPONSE_FILTER carries a FilterSpec applied to the tool RESULT AFTER the call (PII / secret / regex redaction + size cap).

ToolPolicyService

ToolPolicyService is the management CRUD surface over mcp_tool_policies. It rides the gateway scope middleware's per-request transaction (app.org_id GUC bound for RLS) — the same isolation the T5 resolve path relies on.

Method NameRequest TypeResponse TypeDescription
ListToolPoliciesListToolPoliciesRequestListToolPoliciesResponseListToolPolicies returns the tool policies visible to the caller's team: its own editable rows PLUS the inherited (ancestor / org-wide) rows flagged read-only via ToolPolicy.inherited. Optionally narrowed to a server / tool.
CreateToolPolicyCreateToolPolicyRequestCreateToolPolicyResponseCreateToolPolicy persists a new policy under the caller's team. The CEL expression (argument_rule) is compiled server-side and rejected if it does not type-check to bool. A write that duplicates or is shadowed by an inherited parent DENY is rejected (parent deny wins).
UpdateToolPolicyUpdateToolPolicyRequestUpdateToolPolicyResponseUpdateToolPolicy mutates the editable fields (cel_expr / action / filter_spec / enabled) of a policy the caller OWNS. The key (unit_id / server_id / tool_name) and policy_kind are immutable. Inherited rows cannot be edited (they belong to an ancestor).
DeleteToolPolicyDeleteToolPolicyRequestDeleteToolPolicyResponseDeleteToolPolicy soft-deletes a policy the caller OWNS (sets deleted_at). Inherited rows cannot be deleted from a child team.

Scalar Value Types

.proto TypeNotesC++JavaPythonGoC#PHPRuby
doubledoubledoublefloatfloat64doublefloatFloat
floatfloatfloatfloatfloat32floatfloatFloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intintint32intintegerBignum or Fixnum (as required)
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/longint64longinteger/stringBignum
uint32Uses variable-length encoding.uint32intint/longuint32uintintegerBignum or Fixnum (as required)
uint64Uses variable-length encoding.uint64longint/longuint64ulonginteger/stringBignum or Fixnum (as required)
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intintint32intintegerBignum or Fixnum (as required)
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/longint64longinteger/stringBignum
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intintuint32uintintegerBignum or Fixnum (as required)
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/longuint64ulonginteger/stringBignum
sfixed32Always four bytes.int32intintint32intintegerBignum or Fixnum (as required)
sfixed64Always eight bytes.int64longint/longint64longinteger/stringBignum
boolboolbooleanbooleanboolboolbooleanTrueClass/FalseClass
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicodestringstringstringString (UTF-8)
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr[]byteByteStringstringString (ASCII-8BIT)