toolpolicy API
Table of Contents
upsquad/toolpolicy/v1/toolpolicy.proto
CreateToolPolicyRequest
CreateToolPolicyRequest seeds a new policy. org_id / created_by are taken from scope.
| Field | Type | Label | Description |
|---|---|---|---|
| unit_id | string | unit_id is the team scope; "" creates an org-wide policy (L4+ only). | |
| server_id | string | server_id is the MCP server scope; "" = every server. | |
| tool_name | string | tool_name is the governed tool, or "*" for every tool. | |
| policy_kind | PolicyKind | policy_kind selects the policy shape (required; UNSPECIFIED rejected). | |
| cel_expr | string | cel_expr is the portable CEL expression (required for argument_rule). | |
| action | PolicyAction | action fires on match (required for argument_rule; ignored otherwise). | |
| filter_spec | FilterSpec | filter_spec is the response-filter body (required for response_filter). | |
| enabled | bool | enabled 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_id | string | agent_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.
| Field | Type | Label | Description |
|---|---|---|---|
| policy | ToolPolicy | policy is the stored row. |
DeleteToolPolicyRequest
DeleteToolPolicyRequest soft-deletes an owned policy.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id 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.
| Field | Type | Label | Description |
|---|---|---|---|
| detect_pii | bool | detect_pii redacts (or blocks) platform PII classes (email, SSN, phone …). | |
| detect_secrets | bool | detect_secrets redacts (or blocks) platform secret classes (API keys …). | |
| regexes | string | repeated | regexes are caller-supplied patterns to redact/block; invalid patterns are rejected at write time. |
| block | bool | block, when true, causes ANY match to block the whole response rather than redact; when false, matches are replaced with placeholder. | |
| max_bytes | int32 | max_bytes caps the response size (0 disables the cap); applied last. | |
| placeholder | string | placeholder overrides the default "[REDACTED]" replacement token. |
ListToolPoliciesRequest
ListToolPoliciesRequest narrows the policy list. org_id is implicit (scope).
| Field | Type | Label | Description |
|---|---|---|---|
| unit_id | string | unit_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_id | string | server_id optionally narrows to one MCP server (plus any-server rows); "" returns policies for every server. | |
| tool_name | string | tool_name optionally narrows to one tool (plus '*' any-tool rows); "" returns policies for every tool. | |
| agent_id | string | agent_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).
| Field | Type | Label | Description |
|---|---|---|---|
| policies | ToolPolicy | repeated | policies 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.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id is the policy UUID (server-assigned on create). | |
| org_id | string | org_id is the owning tenant (echoed for the client; taken from scope on write, never trusted from the request body). | |
| unit_id | string | unit_id is the team org_unit scope; "" = org-wide. | |
| server_id | string | server_id is the MCP server scope; "" = every server. | |
| tool_name | string | tool_name is the tool this policy governs, or "*" for every tool on the scoped server(s). | |
| policy_kind | PolicyKind | policy_kind discriminates argument_rule vs response_filter. | |
| cel_expr | string | cel_expr is the portable CEL boolean expression (argument_rule only). | |
| action | PolicyAction | action fires when an argument_rule matches (argument_rule only). | |
| filter_spec | FilterSpec | filter_spec is the response-filter body (response_filter only). | |
| enabled | bool | enabled gates whether the policy is live; disabled rows are still returned so the editor can toggle them. | |
| inherited | bool | inherited 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_id | string | inherited_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_at | google.protobuf.Timestamp | created_at is the wall-clock insert time. | |
| updated_at | google.protobuf.Timestamp | updated_at is the wall-clock time of the last mutation. | |
| agent_id | string | agent_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.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id targets the policy to update. | |
| cel_expr | string | cel_expr is the new CEL expression (applied for argument_rule rows). | |
| action | PolicyAction | action is the new match action (applied for argument_rule rows). | |
| filter_spec | FilterSpec | filter_spec is the new response-filter body (applied for response_filter rows). | |
| enabled | bool | enabled is the new enable bit. |
UpdateToolPolicyResponse
UpdateToolPolicyResponse echoes the updated policy.
| Field | Type | Label | Description |
|---|---|---|---|
| policy | ToolPolicy | policy 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.
| Name | Number | Description |
|---|---|---|
| POLICY_ACTION_UNSPECIFIED | 0 | POLICY_ACTION_UNSPECIFIED is the proto3 zero value; the only valid value for a response_filter, rejected for an argument_rule. |
| POLICY_ACTION_DENY | 1 | POLICY_ACTION_DENY blocks the call with a structured refusal + audit row. |
| POLICY_ACTION_ESCALATE | 2 | POLICY_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.
| Name | Number | Description |
|---|---|---|
| POLICY_KIND_UNSPECIFIED | 0 | POLICY_KIND_UNSPECIFIED is the proto3 zero value; rejected at the edge. |
| POLICY_KIND_ARGUMENT_RULE | 1 | POLICY_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_FILTER | 2 | POLICY_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 Name | Request Type | Response Type | Description |
|---|---|---|---|
| ListToolPolicies | ListToolPoliciesRequest | ListToolPoliciesResponse | ListToolPolicies 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. |
| CreateToolPolicy | CreateToolPolicyRequest | CreateToolPolicyResponse | CreateToolPolicy 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). |
| UpdateToolPolicy | UpdateToolPolicyRequest | UpdateToolPolicyResponse | UpdateToolPolicy 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). |
| DeleteToolPolicy | DeleteToolPolicyRequest | DeleteToolPolicyResponse | DeleteToolPolicy soft-deletes a policy the caller OWNS (sets deleted_at). Inherited rows cannot be deleted from a child team. |
Scalar Value Types
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
|---|---|---|---|---|---|---|---|---|
| double | double | double | float | float64 | double | float | Float | |
| float | float | float | float | float32 | float | float | Float | |
| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| bool | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | |
| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |