Skip to main content

Policies

Policy Controls Catalog

This page lists every policy control that the gateway runs, grouped by the phase in which it runs. Find the control for the result you need, then open its page for the settings and a test. A control runs only when it is in the applicable policies.chain.

New to policies? Start with the Policy Configuration Overview.

Select controls by outcome​

OutcomeStart withAdd when necessary
Block prompt attacksprompt-injectionembedding-detector for similarity signals
Remove personal identifierspii-detectorhipaa-phi-detector for more identifier patterns
Protect organization datadlp-filterdata-routing-policy to limit eligible providers
Control agent toolstool-validationtool-security, tool-budget, and agent-firewall
Control output quality or evidencequality-scorercitation-verifier and human-oversight
Change prompts or responsesrequest-rewriterresponse-rewriter for non-streaming output
Add compliance text controlsCompliance Policy ConfigurationOne compliance control at a time, after you read its limits
Record an audit markeraudit-loggerEvents and Trail for evidence, storage, and integrity

Controls with similar names do different work. For example, tool-budget compares the max_tokens value of the request with a tool limit and does not measure cost. audit-logger adds an allow-only marker and does not configure retention.

In the tables below, Families shows the request families that a control accepts:

  • All: Chat Completions, Completions, Responses, Messages, Embeddings, Audio, and Moderation
  • Text: Chat Completions, Completions, Responses, and Messages
  • Tools: Chat Completions, Responses, and Messages

At this time, the gateway evaluates the chain only on Chat Completions, Responses, and Messages requests. The embeddings, audio, moderation, and legacy completions routes do not run any control. See Runtime Request Families.

Input phase controls​

These controls examine the request before the gateway forwards it.

ControlWhat it doesFamilies
prompt-injectionDetects jailbreak and prompt-injection signalsText
pii-detectorRedacts or blocks personal identifiers in the request, and redacts them in the buffered responseAll
hipaa-phi-detectorAdds HIPAA-style PHI checks to the shared redaction pipelineText
dlp-filterApplies pattern-based data loss preventionAll
safety-filterBlocks or escalates configured dangerous termsText
rbacEnforces role, identity, and data-sensitivity access rulesAll
cjis-modeEnforces CJIS-style constraints on the authenticated identityAll
student-privacyDetects student-record markers and replaces student-ID phrasesText
case-privacyDetects built-in case-number patternsText
itar-ear-filterBlocks export-control reference termsText
entity-list-filterMatches denied or watch-listed entitiesText
dual-use-filterDetects dual-use and sensitive capability signalsText
data-routing-policyLimits the provider targets that can receive the requestAll
bot-detectorFlags matching fingerprints or near-identical prompts on one gatewayAll
language-validatorBlocks or warns when the request language is not allowedText
request-rewriterChanges selected request text fields before forwardingText
gdpr-complianceBlocks a request without the consent header when consent_required is setAll
audit-loggerAdds an allow-only audit marker to the decisionAll

Input and output phase controls​

These controls examine request fields or tool data. Some also check responses. A stage override does not add support for a response format that the control does not read.

ControlWhat it doesFamilies
agent-firewallAllows or denies tool use and enforces action and transaction limitsTools
embedding-detectorCompares text with references by word overlap or configured embeddingsAll
external-moderationSends content to a third-party moderation serviceText
content-extractorFetches content from URLs in request messages, within host and size limitsText
document-analyzerExamines documents in the request JSONText
code-sanitizerMatches message text against built-in and custom code-safety patternsText
tool-validationValidates declared tool names and schema syntax, but not generated argumentsTools
tool-securityBlocks unsafe tool definitions in the requestTools
tool-budgetBlocks a request when max_tokens is more than a tool limitTools

Output phase controls​

These controls examine the complete response. Send requests with stream: false.

ControlWhat it doesFamilies
quality-scorerScores output quality and blocks or replaces output below the thresholdText
human-oversightReturns an escalated result instead of the assistant contentText
flagged-reviewReviews each response with a model, or escalates it without oneText
citation-verifierChecks that the request context supports the citations in the outputText
mnpi-filterBlocks output that contains configured MNPI phrasesText
financial-complianceApplies finance-oriented output controlsText
healthcare-complianceEnforces medical blocked patterns and disclaimersText
legal-privilegeBlocks output that contains privilege markersText
upl-filterMatches legal-advice phrases and adds a disclaimer or blocks the responseText
bias-monitorEscalates when the HR bias score reaches the thresholdText
response-rewriterApplies deterministic text rules to the responseText

Reporting-only controls​

eu-ai-act exists for compliance reports only. Lint accepts it in policies.chain, but the gateway then blocks every request with reason code policy.reporting_only. Put its settings in policy.eu-ai-act and generate the report with POST /verdictan/compliance/report.

How the chain selects controls​

policies.chain decides which controls run. policy.<kind> only holds their settings. A settings block without a chain entry does nothing:

policies:
  chain:
    - prompt-injection
policy:
  prompt-injection: {}

A route chain, a when condition, or targeting can also include or remove a control for a request. The output phase controls ignore when, so use routes for them. See Conditional Chain Configuration.

When a control returns block or escalate, the rest of that phase does not run. Put audit-logger first if blocked requests must also have its marker.

Lint checks structure. It does not prove that a control runs for live traffic. The active chain, route, conditions, and gateway version decide that.

Starter configurations​

Save one of these as policy-config.yaml in a new test directory. Each passes verdictan policy lint. Add your provider settings before you send live requests.

PII redaction with audit logging​

policy-config.yaml
pack:
  name: pii-redaction
  version: "1.0.0"
  enabled: true

policies:
  chain:
    - audit-logger
    - pii-detector

policy:
  pii-detector:
    action: redact
    redaction:
      marker_format: label
      include_metadata: true
  audit-logger: {}
Prompt-injection protection
policy-config.yaml
pack:
  name: prompt-injection-protection
  version: "1.0.0"
  enabled: true

policies:
  chain:
    - audit-logger
    - prompt-injection

policy:
  prompt-injection:
    attack_patterns:
      - "ignore.*previous.*instructions"
      - "forget.*system.*prompt"
    encoding:
      decode_base64: true
      normalize_unicode: true
      detect_homoglyphs: true
    boundaries:
      enforce_delimiters: true
      reject_fake_boundaries: true
  audit-logger: {}
Agent firewall with role-based tool access
policy-config.yaml
pack:
  name: agent-tool-access
  version: "1.0.0"
  enabled: true

policies:
  chain:
    - audit-logger
    - agent-firewall
    - rbac

policy:
  agent-firewall:
    tools:
      roles:
        analyst:
          allowed:
            - search
            - summarize
          denied:
            - execute_code
            - shell_command

  rbac:
    require_auth: true
    roles:
      analyst:
        allowed_tools:
          - search
          - summarize
        denied_tools:
          - execute_code
          - shell_command

  audit-logger: {}

Both controls read the role from the authenticated policy identity. They do not trust a role header that the caller sends.

Healthcare redaction stack
policy-config.yaml
pack:
  name: healthcare-redaction
  version: "1.0.0"
  enabled: true

providers:
  targets:
    - id: healthcare-provider
      provider: openai
      model: <model>
      secret_key_ref:
        env: VERDICTAN_OPENAI_API_KEY
      data_policy:
        zero_data_retention: true
        training_opt_out: true

policies:
  chain:
    - audit-logger
    - data-routing-policy
    - pii-detector
    - hipaa-phi-detector
    - healthcare-compliance

policy:
  data-routing-policy:
    require_zero_data_retention: true
    on_no_compliant_provider: block

  pii-detector:
    action: redact
    healthcare_mode: true
    pci_mode: false
    redaction:
      marker_format: label
      include_metadata: true

  hipaa-phi-detector:
    action: redact

  healthcare-compliance: {}

  audit-logger: {}

Replace <model> with a model ID from GET /v1/models on the gateway. A target with zero_data_retention: true must also set training_opt_out: true, or lint reports a contradiction.

Finance output controls
policy-config.yaml
pack:
  name: finance-output-controls
  version: "1.0.0"
  enabled: true

policies:
  chain:
    - audit-logger
    - mnpi-filter
    - financial-compliance
    - quality-scorer

policy:
  mnpi-filter:
    detect_patterns:
      - "earnings before announcement"
      - "merger not public"

  financial-compliance: {}

  quality-scorer:
    min_output_chars: 100
    min_sentences: 2

  audit-logger: {}

Send requests through this stack with stream: false.

Validate a chain​

  1. Lint the file. A valid file exits with code 0:

    verdictan policy lint --file policy-config.yaml
  2. Add the offline test cases from the page of each control, and run verdictan policy test --json.

  3. Apply the file to a test agent with the config-first workflow.

  4. Send a usual request and a request that matches the control. Examine the nested policy results with verdictan events tail --since 5m --json.

For redaction, check the forwarded or returned text. A redact verdict without replacement targets does not prove that sensitive content was removed.

Limits and failure behavior​

  • The gateway does not load a config with an unknown control in policies.chain or policy. verdictan policy lint reports unknown policy kind first.
  • human-oversight supports only action: escalate. The gateway rejects removed fields such as require_human_for and timeout_seconds.
  • language-validator checks input text only. apply_to: output does not add output enforcement.
  • Output controls read the buffered response. A streaming request through flagged-review fails with streaming.policy_cannot_enforce.
  • gdpr-compliance and eu-ai-act have no control page of their own. Compliance Policy Configuration describes them.
  • These controls do not make you compliant on their own. You still own legal review, operating processes, and provider governance.

Troubleshooting​

ProblemLikely causeWhat to examine
The file lints but the control does not runThe chain does not include it, or a route, when, or targeting removes itThe applied global or route chain and the request context
A valid field has no effectThe schema accepts more fields than the runtime enforcesThe supported fields on the page of the control
An output control works only for some clientsThe response structure or the streaming mode is differentThe request family, the stream value, and the supported response paths
A later result is missingAn earlier control stopped the phaseThe chain order and the block or escalation reason code
Pack tests pass but live requests failThe test runner does not simulate every gateway handler and transportThe same request through a test gateway and provider
The decision reason code is ok after an allowA nested allow reason does not replace the envelope reasonThe policy_results array and the decision envelope

Next steps​