Skip to content

Organization YAML

Models and MCP servers are managed as Git-reviewed YAML, not database CRUD. The global file lists organization files; each organization file declares security limits, providers, model deployments, virtual-model routes, MCP servers, and eligible tools. The catalog is organization-wide; Team allowance is managed separately in the Console; each key further narrows operation/resource policy.

Global file

version: 1
organizationConfigs:
  - organizations/acme.yaml

Paths resolve inside the global file's directory. Absolute paths and relative paths that escape that directory are rejected.

Complete organization example

version: 1
organization: acme

security:
  keys:
    defaultLifetimeDays: 30
    maxLifetimeDays: 90

telemetry:
  standardOtlp:
    enabled: true
    captureMode: full
    metadataRetentionDays: 30

providers:
  primary:
    type: openai-compatible
    profile: openai
    baseUrl: https://models.example.test/v1
    credential: env/ACME_OPENAI_API_KEY
    defaultHeaders:
      X-Tenant: acme
    healthCheck:
      path: /models
      authentication: bearer

models:
  - id: support-primary
    provider: primary
    providerModel: provider-model-name
    virtualModel: support
    priority: 1
    weight: 100
    timeouts:
      firstTokenMs: 30000
      idleMs: 15000
      totalMs: 300000
    fallbacks:
      - support-fallback
    inputCostPerMillion: 2.5
    outputCostPerMillion: 10
  - id: support-fallback
    provider: primary
    providerModel: provider-fallback-name
    virtualModel: support
    priority: 2
    weight: 100
    fallbacks: []
    inputCostPerMillion: 1
    outputCostPerMillion: 4

connectors:
  - id: crm
    name: CRM
    transport: streamable-http
    url: https://crm-mcp.example.test/mcp
    auth:
      type: bearer
      credential: env/ACME_CRM_MCP_TOKEN
    timeoutMs: 15000
    enabled: true
    tools:
      - name: lookup-customer
        classification: data
        schemaHash: sha256:1dc63095e8672403bbe40fa26719d175e695c0167f6daad6b9655f6506491f01
        autoExecute: true
        costPerCallMicros: 0
      - name: create-ticket
        classification: action
        schemaHash: sha256:7b1a4c0f2d9e8b6a5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b
        approval: required
        costPerCallMicros: 250
        rules:
          - id: ticket-title-length
            action: block
            applies: arguments
            argument: title
            match:
              maxLength: 200

rules:
  - id: secrets
    action: detect
    match:
      secrets: true

The organization value must match a bootstrapped tenant slug. Startup validates every organization mapping before reconciliation. New runtime evidence uses a normalized non-secret configuration hash; no saved revision or activation is created.

Key and concurrency limits

Field Default Contract
security.keys.defaultLifetimeDays null Positive integer or null. Applied when a key is issued without an explicit expiry; null issues non-expiring keys by default.
security.keys.maxLifetimeDays null Positive integer or null. When set, issuance rejects a longer or non-expiring key. defaultLifetimeDays cannot exceed it.

security is required and may be empty (security: {}); security.keys may be omitted entirely. The key policy is read from loaded configuration at issuance and rotation time. Changes require a coordinated gateway/Console restart and do not alter existing keys.

Concurrency and other product budgets are canonical control-plane policies, not principal-scoped YAML fields. Use Budgets for Organization, Team, exact member/service, key and customer caps. Stored spend amounts are integer USD micros here and in the management API; the Console enters and shows the same amounts in dollars. The retired security.maxConcurrentRequestsPerPrincipal field is rejected, so config:check and startup fail while it is present. Saving a budget takes effect on the next admission without YAML restart or resetting recorded usage.

Standard OTLP policy

telemetry.standardOtlp is strict organization configuration:

Field Default Contract
enabled false Boolean. When false, no new spans are stored for the Organization: external standard OTLP exports and managed-runtime telemetry are refused as permission denied, and the gateway records no request spans for its Requests. Effective capture is metadata. Requests, ledger Usage and audit are unchanged; see below the table.
captureMode full Exact full or metadata. Each invocation inherits its captured organization maximum; live Team/key/deployment restrictions may narrow it to metadata.
metadataRetentionDays 30 Integer from 1–90. It sets retention for request spans using the configuration captured at invocation ingress.

With enabled: false, Observe → Requests and Usage show the Organization's Requests and ledger facts as usual, but Observe → Traces has no spans for them. The gateway still returns each Request's traceparent and passes Trace context on to providers and tools, but exports no span. A gateway span of the Organization that reaches the span writer anyway, such as one exported before a restart turned the setting off, is dropped on its own; the other Organizations' spans in the same export are still stored. Evaluation that reads captured spans cannot run: readiness blocks tool validators and judges using tool_calls or evidence, a validator's tool call is refused as validator_capture_off before the tool is called, and LLM auto-evaluation judgments end evidence_uncaptured.

The observation schema is mission-control.metadata/v1 for metadata and mission-control.observation/v1 for full capture. Each invocation captures its base capture and retention settings before Trace binding and reads live Team/key/deployment restrictions during policy resolution. A restart loads changes for subsequent invocations, including continued Traces, without rewriting stored spans or extending their recorded retention. An authorized exact-scope Trace deletion remains a separate operation.

Changing a YAML value requires restarting gateway and Console; running processes keep their loaded files. No new API key is required. Start a new external process only when its OTLP endpoint/protocol changes.

captureMode: full enables bounded permitted text/JSON content for subsequent invocations. To narrow future invocations, restart with captureMode: metadata. Credentials, hidden reasoning, unrelated memory, files/attachments, and caller authority remain hard-excluded.

Example metadata restriction:

telemetry:
  standardOtlp:
    enabled: true
    captureMode: metadata
    metadataRetentionDays: 30

Providers and models

Provider IDs are the YAML mapping keys. type names the protocol family: openai-compatible, anthropic, aws-bedrock, azure-openai, or google-vertex. Existing OpenAI-compatible profiles below retain their behavior. Native families use the connection/authentication fields and operation profiles in Native providers, including separate AWS runtime/control/agent-runtime endpoints and independent Google ranking endpoint/location/timeout overrides.

Profile Use it for Defaults it changes Fields it accepts beyond the baseline Output-token field
generic Any OpenAI-compatible server the gateway does not know None: chat upstream, both client protocols, text only, streaming, structured output, function calls, usage reporting, abort-signal cancellation, retry-unsafe None max_tokens
openai api.openai.com Image input store: false max_completion_tokens
anthropic-compat api.anthropic.com through the OpenAI SDK compatibility layer Image input; structured output off metadata, store (both ignored by the vendor) max_tokens
deepseek api.deepseek.com Structured output off None max_tokens

The baseline every profile accepts is function tools, tool_choice, a JSON-schema response format where structured output is on, stream, the standard stream_options on the chat upstream, temperature, and the output-token limit. A request that sends a field the deployment's profile does not accept makes that deployment ineligible; when no deployment is eligible the call fails with capability_unavailable instead of being approximated. stream_options is the exception: a deployment whose upstream has no such field stays eligible, because the Responses upstream reports usage without being asked.

capabilities on a provider is an optional block of explicit overrides over the profile's defaults; only keys you write take effect. Each models item may carry the same block to override one deployment, which is how a single model opts into the Responses upstream:

models:
  - id: support-responses
    provider: openai
    providerModel: gpt-support-responses
    virtualModel: support
    priority: 1
    capabilities:
      upstreamProtocol: responses

Merge order is profile defaults, then the provider block, then the deployment block. The keys are upstreamProtocol, supportedCanonicalProtocols, inputModalities, streaming, structuredOutput, functionCalls, usageReporting, cancellation, retrySafety, and reasoningEfforts. A merged result may not claim what its profile cannot carry: structuredOutput: true on a profile that does not accept a JSON-schema response format, such as anthropic-compat or deepseek, is rejected when the configuration is applied, naming the deployment, the profile, and the field.

reasoningEfforts is an optional array containing distinct low, medium, or high values (maximum three). Absent means no declared support; [] explicitly disables inherited support. It is accepted only for the openai profile with chat_completions upstream, whose wire is reasoning_effort. Configurations claiming it on Responses or another profile are refused; the stateless Responses subset does not replay opaque reasoning continuation items. An administrator must verify the actual providerModel supports the declared values. Managed case settings require every configured route of the virtual model to support the requested effort, so they cannot choose a different model implicitly.

models:
  - id: support-reasoning
    provider: openai
    providerModel: supported-provider-model
    virtualModel: support
    priority: 1
    capabilities:
      upstreamProtocol: chat_completions
      reasoningEfforts: [low, medium, high]

Activate configuration and restart gateway/Console processes after changing capabilities. No new virtual key or user session is required. A request asking for an undeclared effort receives capability_unavailable; evaluation readiness reports case_reasoning_effort_unsupported.

For OpenAI-compatible connections, baseUrl must be an absolute URL and trailing slashes are normalized. credential is an env/NAME reference. defaultHeaders is optional and defaults to an empty mapping.

Secret references are resolved only in declared credential fields: OpenAI-compatible/Anthropic credential, Azure API-key authentication.credential, modelGuardrails.classifier.credential, and Connector authentication secrets (including credential-valued headers, OAuth client secrets and discovery credentials). Ordinary header and text values such as x-note: env/ORDINARY_TEXT remain literals and do not cause a lookup or receive credential redaction metadata. Cloud secret-reference schemes are not supported; native cloud SDK credential chains are configured separately in the gateway environment.

A reference must name a variable the Organization owns. The platform's own names are reserved: every documented platform setting, the native providers' cloud SDK identity variables, PostgreSQL client and proxy variables, and platform namespaces such as MISSION_CONTROL_, MCP_CREDENTIAL_, CLICKHOUSE_ and AWS_; see Names Organization YAML cannot reference for the complete list. Gateway startup, Console startup and config:check refuse a file with a reserved reference, for example credential: env/DATABASE_URL, with Secret reference names a reserved platform environment variable (acme.yaml: providers.primary.credential). Keep each credential in an Organization-owned variable such as env/ACME_OPENAI_API_KEY, then restart the gateway and Console.

For OpenAI-compatible connections, healthCheck is optional. It configures the non-inference request made by Test connection:

Field Default Contract
healthCheck.path /models Absolute provider-relative path without a query or fragment. Mission Control performs GET <baseUrl><path>.
healthCheck.authentication bearer bearer sends the resolved credential as Authorization: Bearer …; x-api-key sends it as x-api-key. Authentication values supplied in defaultHeaders are discarded so a configuration cannot override the resolved credential.

The request also includes safe defaultHeaders and the correlation ID. Redirects are not followed, so a 3xx response cannot forward a credential to another origin and is recorded as provider_status_<status>. A 2xx response is healthy only when its OpenAI-compatible data array, within a 1 MiB response limit, contains the deployment's exact providerModel. A missing, oversized, malformed, or mismatched model list records provider_model_unavailable. The check never calls a completion endpoint, generates output tokens, or incurs inference-token charges.

For an Anthropic identity-linked API key, keep normal OpenAI-compatible invocation on Bearer authentication while configuring the native model-list check explicitly:

providers:
  anthropic:
    type: openai-compatible
    baseUrl: https://api.anthropic.com/v1
    credential: env/ANTHROPIC_API_KEY
    defaultHeaders:
      anthropic-version: "2023-06-01"
      anthropic-workspace-id: wrkspc_example000000000000000
    healthCheck:
      path: /models
      authentication: x-api-key

Adding or rotating a provider environment credential or changing YAML healthCheck/defaultHeaders requires preflight and a coordinated gateway/Console restart, with no new API key or caller session.

Each models item is a provider deployment. operation is generation (default), embedding, or rerank; optional deployment profile selects a same-family operation dialect. Fallbacks stay within the same virtual model and operation. Bedrock Titan embeddings and AWS/Google reranking require explicit profiles; see Native providers.

The following fields remain common to deployments:

Field Meaning
id Stable deployment ID; unique within the organization.
provider Existing provider mapping key.
providerModel Model string sent to the upstream provider.
virtualModel Stable name requested by clients, such as support. Its resource ID for Team allowance and key policy is model:support.
priority Positive integer; lower values route first.
weight Optional positive weight within the same priority; defaults to 1.
fallbacks Optional deployment IDs for the same virtual model. Unknown IDs, duplicates, cross-model references, and cycles are rejected.
inputCostPerMillion Optional non-negative USD estimate per million input tokens used for metadata attribution and recorded estimated spend.
outputCostPerMillion Optional non-negative USD estimate per million output tokens used for metadata attribution and recorded estimated spend.
capabilities Optional explicit capability overrides for this deployment only.
timeouts Optional firstTokenMs, idleMs and totalMs, positive integers in milliseconds; defaults 60000, 30000 and 600000. firstTokenMs bounds the wait for the response headers or the first stream event, idleMs the silence between stream events, totalMs the whole call. See Model gateway.

Multiple deployments with the same virtualModel compile into one route table. Changing a route changes the startup-loaded configuration hash after restart; clients continue to request the virtual name. If two teams need different providers behind "the same" model, declare two virtual models; there are no per-team route overrides.

For a finalized model call, Mission Control calculates recorded estimated spend from the resolved deployment:

input tokens / 1,000,000 * inputCostPerMillion
+ output tokens / 1,000,000 * outputCostPerMillion

Each physical provider attempt records integer USD micros from priced usage, with explicit known/estimated/unknown state. Governing Organization/Team/owner/key/customer meters may reflect the same fact without multiplying billed usage. Historical facts are not repriced by changing YAML. Finite spend admission needs a priced, finite output bound before provider I/O; unknown or unbounded liability fails closed. Unknown termination retains its bounded debit until confirmation/recovery, rather than becoming free usage. Model token usage is separate from business tool cost.

Model guardrail policies

Organization-owned guardrailPolicies define reusable rule bundles. modelGuardrails.policies assigns the mandatory baseline; modelGuardrails.virtualModels adds policies to exact declared virtual-model names. See Create and assign reusable policies for a copyable example and activation procedure.

Field Contract
guardrailPolicies.<id> Map entry with optional description, input, output; at least one rule. Policy IDs are lowercase letter/digit/hyphen slugs, start with a letter/digit, and are at most 100 characters. Maximum 100 definitions.
description Optional text, at most 1,000 characters; does not instruct a detector.
Policy input / output Existing model rule syntax, maximum 100 per array; omitted arrays are empty.
modelGuardrails.policies Ordered policy IDs for all models in this Organization, maximum 100, with no duplicate references.
modelGuardrails.virtualModels Exact virtual-model names to ordered policy-ID arrays, maximum 100 per array. Names must exist in models[].virtualModel; provider/deployment IDs and wildcard matching are not accepted.
Inline modelGuardrails.input / output Existing mandatory Organization rules; named policies add to them.
modelGuardrails.classifier Shared url, credential: env/NAME, and timeoutMs connection for all classifier rules. Required even for an unassigned definition containing a classifier check.
modelGuardrails.maxBufferedOutputBytes Shared output-buffer bound: default 1048576, maximum 8388608; policies cannot override it.

Order is inline Organization rules, named baseline policies, then named model policies. A policy assigned at both scopes executes once. Rule IDs are unique across all definitions and inline/MCP rules in the file. Each effective model stage has at most 100 rules after deduplication. Saved policy evidence is bounded to 64 KiB. Unknown references, empty definitions, unsupported fields and invalid regex fail preflight/startup; inactive definitions are validated but do not run. Assignment maps use exact own entries, including names that resemble object properties. The reserved map key __proto__ is rejected before parsing so an intended assignment or definition cannot silently disappear; use another virtual-model name for such an assignment.

Embeddings and reranking inspect inputs only. Their output policy entries are inapplicable, and an output-only named assignment produces guardrail_policy_no_applicable_rules. Adding a virtual model policy grants no access and cannot remove baseline checks. There are no Team/key assignments, caller overrides or inheritance/remove operations. Definitions, references and policy settings require preflight and coordinated gateway/Console restart. Existing inline files need no migration. See classifier semantics and errors.

MCP servers

Connector server IDs use lowercase letters, digits, and hyphens. The only current transport is streamable-http, pinned to MCP revision 2026-07-28; a server that offers only an initialize-based revision is unavailable and is not retried through fallback. Supported authentication shapes are:

auth:
  type: none
auth:
  type: bearer
  credential: env/ACME_CRM_MCP_TOKEN
auth:
  type: header
  headerName: X-API-Key
  credential: env/ACME_CRM_MCP_KEY
auth:
  type: headers
  headers:
    Authorization:
      credential: env/CRM_AUTHORIZATION
    X-Tenant-ID:
      value: example-team

For headers, each entry has exactly one credential or value. A credential reference resolves only from env/NAME; CRM_AUTHORIZATION supplies the complete header value, including a scheme when the upstream requires one. Literal values have no interpolation: value: env/ORDINARY_TEXT sends those exact characters and remains visible to administrators in redacted configuration. Authorization is allowed only with credential.

Header names are normalized to lowercase and must be unique ignoring case. Configure 1–32 entries; names are 1–128 ASCII letters, digits, or hyphens, each resolved or literal value is at most 8192 UTF-8 bytes, and the encoded set is at most 32 KiB. Transport-safe values may contain horizontal tab, printable ASCII, and U+0080–U+00FF. NUL, other control characters, DEL, CR/LF, and characters above U+00FF fail validation for both value and resolved credential fields. Reserved names are Host, Content-Length, Transfer-Encoding, Connection, Upgrade, Trailer, TE, Expect, Accept, Content-Type, Origin, traceparent, tracestate, and baggage, plus all Proxy-*, Sec-*, MCP-*, X-MC-*, and X-Mission-Control-* names. The same reserved-name validation applies to singular header; existing configurations using one of those names must move to an upstream-supported ordinary name before startup.

timeoutMs is a positive integer. A disabled server remains visible to admins but its tools are not eligible for clients.

MCP OAuth configuration

auth.type: oauth selects one shared upstream identity. grant is required and is exactly authorization_code or client_credentials; errors never change the grant. registration is preregistered (default) or dynamic.

auth:
  type: oauth
  grant: client_credentials
  registration: preregistered
  issuer: https://identity.example.test
  clientId: mission-control-crm
  clientSecret: env/CRM_OAUTH_CLIENT_SECRET
  scopes: [crm.read]
  allowedAuthOrigins: [https://identity.example.test]
Field Supported behavior
issuer Exact HTTPS issuer without userinfo, query or fragment; issuer identity is not silently normalized.
registration preregistered (default) or dynamic. Dynamic registration obtains the client from the issuer's registration_endpoint during the first Connect, requires authorization_code, and forbids clientId and clientSecret.
clientId Literal registered client ID, 1–512 characters; required for preregistered, forbidden for dynamic.
clientSecret Optional env/NAME for authorization-code public clients; required for client credentials.
scopes Required array of 1–64 explicit OAuth scope tokens; duplicates are removed and order canonicalized.
allowedAuthOrigins 1–16 exact HTTPS origins including the issuer origin. Discovery cannot add origins. The MCP resource origin is also permitted for metadata discovery.
headers Optional supplemental static headers using the literal/reference contract above. OAuth owns Authorization.
tokenTtlSeconds Optional integer 1–300 used only when a provider omits expires_in; choose it from the provider contract. Invalid/nonpositive expiry rejects regardless.

Empty scopes arrays fail startup preparation; discovery never supplies implicit scopes. OAuth resource URLs must use HTTPS without credentials or fragments. Gateway encryption settings are required at startup preparation even for client credentials, because its client-auth binding is encrypted. Client/header references resolve at startup; access/refresh tokens are runtime state outside YAML. OAuth timeoutMs covers credential waiting plus MCP work. See Shared MCP OAuth. Per-user modes are described below; delegated token exchange is not an accepted configuration mode.

Per-user connector configuration

auth.type: per_user_oauth and auth.type: per_user_headers make the Connector act as the calling person. Both require discoveryAuth, a static shape (none, bearer, header, or headers) used only by Refresh connection; tool calls never use it.

auth:
  type: per_user_oauth
  registration: preregistered
  issuer: https://identity.example.test
  clientId: mission-control-records
  clientSecret: env/RECORDS_OAUTH_CLIENT_SECRET
  scopes: [records.read]
  allowedAuthOrigins: [https://identity.example.test]
  discoveryAuth:
    type: bearer
    credential: env/RECORDS_DISCOVERY_TOKEN
auth:
  type: per_user_headers
  headerNames: [x-personal-token]
  discoveryAuth:
    type: none
Field Supported behavior
registration, issuer, clientId, clientSecret, scopes, allowedAuthOrigins, headers, tokenTtlSeconds As for shared OAuth above. The grant is always authorization_code, completed by each person in their own browser; grant is not a field of this mode.
headerNames 1–8 header names, compared without case and stored in lowercase, unique, and subject to the reserved-name rules above. Each person supplies a value for every name under My connections.
discoveryAuth Required. One of the static shapes above with its own credential references, resolved at startup preparation. Changing it never touches anyone's personal grant or values.

A change to the OAuth client, issuer, scopes, or origins starts a new credential generation, which disconnects every person's grant; a change to headerNames hides stored values that no longer match the declared names until people save them again. Personal grants and values are runtime state outside YAML and never appear in redacted configuration. Delegated token exchange is not an accepted configuration mode.

Discover and declare tools

Register a new server with tools: [], restart with the catalog, then use Refresh connection on the server page. Discovery records server metadata and canonical input-schema hashes; it enables nothing in any team.

For each tool approved for use:

  1. Copy the discovered tool name and SHA-256 schema hash.
  2. Classify it as exactly one of data, decision, or action.
  3. Add it to tools in YAML.
  4. Review and commit the change.
  5. Run preflight and restart with the new configuration.
  6. Refresh the connection again and confirm Matched.
  7. Enable the tool in each team that should be able to use it.

The public tool name is <server-id>__<tool-name>, for example crm__lookup-customer. Its resource ID for Team allowance and key policy is tool:<server-id>/<tool-name>.

Each tools entry has these fields:

Field Default Meaning
name required The discovered tool name, unique within the server.
classification required Exactly one of data, decision, or action.
schemaHash required The sha256: digest of the canonical input schema from the latest successful discovery.
autoExecute false Boolean. When true, the gateway may run this tool inside a model call without returning it to the caller, but only when the request also names it (or asks for every automatic tool) and the caller may see it; see Governed tools on a model call. Validation warns when an action tool is marked and needs no approval. It does not affect /mcp calls or Chat approvals.
approval required for action, none otherwise required or none. Whether a call on /mcp or inside a model loop pauses as a durable approval that a separate person decides in the Console; managed deployments use separate durable conversation consent. See Approvals.
rules [] Up to 100 rules evaluated for this tool after the organization's and the server's.

A discovered but undeclared tool, a missing declared tool, or a different schema hash is not eligible for listing or invocation. Review the change and restart with an updated declared hash; do not weaken the comparison to bypass drift. The Console's Declare panel renders this block from the latest discovery; see Declare discovered tools.

Tool sets

toolSets is an optional top-level list of named bundles of declared tools:

toolSets:
  - id: support
    name: Support tools
    tools:
      - crm/lookup-customer
      - crm/create-ticket
  - id: reporting
    tools: []
Field Default Meaning
id required Lowercase letters, digits and hyphens, unique among sets. The catalog resource id is toolset:<id>.
name the id Display name, 1–200 characters.
tools [] Up to 200 members as <server-id>/<tool-name>; each must be a tool declared under connectors, or validation fails with Tool set <id> references an undeclared tool <member>. Duplicates collapse.

Team allowance and selected key/deployment policy may explicitly follow a tool set. At authorization the current loaded members expand only inside the catalog/Team/key intersection. An empty set, and a toolset: id the catalog no longer contains, grant nothing; Preflight warns about an empty set. See Tool sets.

Tool pricing

An optional costPerCallMicros on each tool declares an integer USD-micro charge per physical business call, from 0 through the maximum safe integer. 0 is an explicit known-zero charge; omission is unknown, not free. Negative/fractional/string/null values fail configuration validation. Use actual contract prices: the example's 250 is a fictional quarter of a mill (0.00025 USD).

Finite spending caps require this bounded liability before tool dispatch. A completed call settles its configured per-call charge; uncertain dispatch retains the bounded estimate until confirmation/recovery. Tool calls charge zero model tokens; a subsequent model round is separately metered. Changing the price requires reviewed YAML and gateway/Console restart and changes future calls only. Direct MCP and managed/gateway-loop business calls use the same price/ledger boundary.

Rules

rules is an optional list (at most 100 entries each) at the top level of the file, under a Connector, and under a declared tool. Every rule has:

Field Default Meaning
id required Lowercase letters, digits and hyphens, at most 100 characters, unique across the whole file. Recorded on decisions and used in redaction markers.
action required block refuses the call or withholds the result; redact replaces the matched content; detect records the rule only.
applies both arguments, results or both.
argument every string The one top-level argument the rule inspects, as text (a non-string value is compared as its JSON). Not allowed with applies: results; with both, the result side inspects every text item.
match required Exactly one of the matchers below.
Matcher Value Matches when
regex an RE2 expression, at most 500 characters; see Regular expressions the pattern matches; redact replaces every match with [redacted:<id>].
maxLength a positive integer the text is longer; redact cuts it to the limit and appends …[truncated:<id>].
allow 1–200 strings the text is not one of them; redact replaces the whole value with [redacted:<id>]. Not allowed with applies: results.
secrets true a built-in secret shape appears: AWS access keys (AKIA…), GitHub tokens (ghp_… and its siblings), Slack tokens (xox…), Google API keys (AIza…), Stripe live keys (sk_live_…), PEM private keys, Bearer … tokens, and api_key, secret, token or password assignments; redact replaces each.

Rules are evaluated per tool in declaration order: the organization's, then the Connector's, then the tool's. Argument rules run after schema validation and before any credential is prepared; result rules run on the text items of the MCP result after dispatch and before the caller, the model or the capture sees them. A block on arguments rejects the decision with error_code: rule_blocked and dispatches nothing; a block on results fails the decision with the same code after the call ran. The decision records one rule: the first blocking, else the first redacting, else the first detecting. Validation fails with Duplicate rule id: <id>, Rule <id> names an argument but applies to results, Rule <id> allow-lists values but applies to results, or Rule <id> has an invalid regex (also for JavaScript-only syntax such as look-around or backreferences). See Rules on arguments and results and Gateway errors.

Regular expressions

Tool-rule regex matchers, secrets: true and the regex, secrets and pii matchers of model guardrails run in RE2, never in JavaScript's backtracking engine, so a search takes time linear in the text it reads. Tool-rule patterns use RE2 syntax:

  • Look-around ((?=…), (?!…), (?<=…), (?<!…)) and backreferences (\1, \k<name>) are not supported. config:check and startup fail with Rule <id> has an invalid regex (model guardrails: Model guardrail <id> has an invalid RE2 expression).
  • A pattern too large for RE2's fixed memory fails config:check and startup with the same invalid regex error. For example, \p{L}{100} repeats a class of thousands of letters a hundred times; narrow the class, as in [A-Za-z]{100}, or shorten the repetition.
  • Matching is Unicode-aware, as with JavaScript's u flag. \d, \w, \s and \b cover ASCII characters only, and . matches any character except a newline. Inline flags such as (?i) are accepted.

Rewrite an unsupported pattern so that it matches the text it needs:

  • secret(?=-) becomes secret-: the delimiter is part of the match and is redacted too.
  • (?<=id=)[0-9]+ becomes id=[0-9]+: the prefix is part of the match.
  • key(?!s) becomes key(?:[^s]|$): the following character, if any, is part of the match.
  • <(b)>[^<]*</\1> becomes <b>[^<]*</b>: the repeated text is written out.

Evaluation is bounded. The limits are fixed; they are not configuration settings:

Limit Value
Text one search reads (a window) 1,310,720 bytes of UTF-8: 1,310,720 characters of ASCII text, at least 436,905 characters of any text.
Overlap between consecutive windows Half a window, at least 218,452 characters.
Characters that must follow a custom match to redact it 4,096 inside its window, unless the window reaches the end of the text.
Searches per decision 100,000
Characters read per decision 8,388,608, plus 4 for every character of text an expression inspects. A built-in secret expression that also watches for long private keys or assignments counts the text once more for each.

Characters are UTF-16 code units. The window size keeps each search well inside the fixed memory of an RE2 instance. Tool rules, model guardrails and the built-in shapes run in one instance; evaluation assertion patterns, which Team members write, run in a separate one. If a search still runs its instance out of memory, the rule counts as matching for that call only (block blocks, redact replaces the text from where the search stopped, detect records), and the instance is replaced before the next search. A default 1 MiB guardrail output buffer, and any text of up to 1.25 MiB of ASCII such as a request-sized argument, is searched in one window. A decision is one evaluation of a call's argument rules, of its result rules, or of one model guardrail stage (input or output).

Text longer than one window is searched window by window. A match that no single window holds is handled as follows:

  • A custom regex whose match can be longer than the overlap, meaning any *, + or {n,} outside a character class or escape, or counted repetitions that add up to more than 218,452 characters, counts as matching the whole text unless a window finds a match: block blocks and detect records even when no window matched, and redact replaces everything from the first text it could not finish to the end. A custom regex bounded below the overlap is exact across windows.
  • Among the built-in secret shapes, only a -----BEGIN … PRIVATE KEY----- block with an -----END marker somewhere after it, and a secret, token, password or api_key assignment still running at a window's end, can outgrow the overlap. The search restarts at such an opening and fails closed only if a whole window from it cannot finish the match, so a key or assignment padded beyond a window counts as a secret. Every other shape can end within 40 characters of its start, so the overlap always holds it.
  • The email and phone pii shapes trust the overlap, so a match longer than 218,452 characters that crosses a window boundary may be missed.

A match that cannot be decided within one window is treated as running to the end of the text. A custom regex, or the email or phone pii shape, whose match depends on text more than 4,096 characters beyond it, such as a greedy .* followed by a delimiter that recurs much later, can choose a shorter match than a JavaScript engine would. Built-in secret shapes and the IP address and card number pii shapes are decided by the characters right after a match and are not affected.

When a decision reaches the search or character limit, the rule being evaluated and every later regex, secrets or pii rule in that decision count as matching: block blocks, redact replaces the rest of the text it has not searched (the whole text when it has not started) with one [redacted:<id>] marker, and detect records the rule. Ordinary traffic stays far below these limits. A decision reaches them only with more than about a thousand matches of one expression in the same text (tens of thousands for built-in secret shapes), or with more than 100,000 searches, for example 100,000 argument strings checked by one rule.

Startup validation

Startup and optional config:check parse both YAML levels, resolve every organization scope, compile models and Connectors, and resolve all designated nonempty environment credentials. Strict invalid configuration stops before serving. Preparation performs no upstream checks; all organizations must prepare before persistent reconciliation begins. Loaded configuration stays fixed until restart.

Secret values never appear in redacted configuration or evidence hashes. Nested credential entries expose safe reference metadata; literal value entries remain visible. Removed catalog resources are unavailable regardless of persisted Team/key selection. Re-adding cannot exceed current Team allowance and key policy. No new configuration revision or activation row is written. See File configuration and startup.