Guards
Guards are optional fields on a policy rule that add an extra enforcement layer on top of the rule’s primary action. They run at request time — before the request is forwarded to the upstream server.
Two kinds of guards are available:
| Guard | Field | Applies to |
|---|
| Token guard | tokenGuard | LLM rules (llm_model, llm_endpoint targets) |
| Content guard | contentGuard | LLM rules only (llm_model, llm_endpoint targets) |
Guards are evaluated after target matching and condition checking. If a token guard fires, the request is denied regardless of the rule’s action. Content guards are evaluated for LLM requests only; see the interaction table below for how they interact with redact rule actions.
Token Guards
Token guards let you cap the size of LLM requests before they reach the upstream provider. They apply to rules whose target.kind is llm_model or llm_endpoint.
Source: packages/proxy/src/policy-engine.ts — checkTokenGuard, apps/api/src/lib/schemas/policies.ts.
Fields
tokenGuard?: {
maxInputTokens?: number; // deny if estimated input tokens exceed this value
maxRequestMaxTokens?: number; // deny if the request's max_tokens field exceeds this value
}
| Field | Description |
|---|
maxInputTokens | Deny if the estimated prompt token count (chars ÷ 4 heuristic) exceeds this value |
maxRequestMaxTokens | Deny if the request’s max_tokens parameter exceeds this value |
When a token guard fires, the request is denied before it reaches the upstream provider with a structured error explaining which limit was exceeded.
Example
{
"target": { "kind": "llm_model", "model": "gpt-4o" },
"action": "allow",
"tokenGuard": {
"maxInputTokens": 8000,
"maxRequestMaxTokens": 2048
}
}
This rule allows GPT-4o calls but blocks any request whose estimated input exceeds 8 000 tokens, or whose max_tokens exceeds 2 048.
maxInputTokens uses a character-count heuristic (chars / 4) at request time. It is not an exact token count. Use it to catch runaway prompts, not for precise billing.
Content Guards
Content guards run Igris detectors on request content (and optionally on the upstream response) before forwarding. They can block or redact matched content.
Source: packages/proxy/src/policy-engine.ts — checkContentGuard / redactRequestBody / inspectResponseContent, apps/api/src/lib/schemas/policies.ts.
Fields
contentGuard?: {
detectors: string[]; // detector IDs, pack names, or "custom:<slug>"
action: "deny" | "redact" | "alert";
inspectResponse?: boolean; // also scan the upstream response content
}
| Field | Description |
|---|
detectors | List of detector IDs (e.g. "us-ssn"), pack names (e.g. "pack:pii-default"), or custom detector slugs ("custom:internal-id") |
action | "deny" blocks the request when a detector matches; "redact" masks matched content and forwards; "alert" logs a match but does not block |
inspectResponse | When true, also run detectors on the upstream response content. Non-streaming responses only. |
Example: Redact PII before forwarding
{
"target": { "kind": "llm_endpoint", "endpoint": "chat.completions" },
"action": "redact",
"contentGuard": {
"detectors": ["pack:pii-default", "pack:secrets-default"],
"action": "redact",
"inspectResponse": false
}
}
Matched text is replaced with [REDACTED:<detector-id>] in-place. The upstream call still proceeds with the redacted content. Note: when the rule action is redact, the content-guard deny-check is skipped by the evaluator — redaction is applied directly to the request body before forwarding.
Example: Deny if secrets detected in LLM prompt
{
"target": { "kind": "llm_endpoint", "endpoint": "chat.completions" },
"action": "allow",
"contentGuard": {
"detectors": ["pack:secrets-default", "custom:internal-id"],
"action": "deny",
"inspectResponse": true
}
}
Built-in packs
| Pack | Detector members |
|---|
pack:pii-default | us-ssn, credit-card, email, us-phone, ipv4, iban, uk-nin |
pack:secrets-default | aws-access-key, aws-secret-key, gcp-service-account, private-key-pem, slack-token, github-token, jwt |
Custom detectors
Manage custom detectors via the API at https://api.igrisecurity.com/api/v1/detectors/custom. Three kinds are supported: regex, keywords, and luhn. Reference a saved custom detector in any detectors array using the custom:<slug> prefix.
Combining Guards with Actions
Guards and actions interact as follows:
| Rule action | Token guard fires | Content guard fires |
|---|
allow | Request denied | Denied or redacted depending on contentGuard.action |
deny | Request denied (guard fires first) | Request denied |
alert | Request denied | Denied or redacted depending on contentGuard.action |
redact | Request denied | Content-guard deny-check is skipped; redaction is applied separately to the request body before forwarding |
For maximum protection, pair a deny rule action with a contentGuard.action of "deny". The content guard provides a second enforcement layer if the primary rule action is changed.
- Policies — how rules are structured, evaluated, and rate-limited
- Tool Calls — how MCP tool calls flow through the proxy
- Identity & Metadata — how user and metadata context reach the policy engine