Skip to main content

Declarative Config Reference

Use this page when you need to author, review, or validate policy-config.yaml and want a customer-facing explanation of what the declarative config supports.

Declarative resources own their runtime tags

When a configuration or gateway is managed declaratively, Keeptrusts treats the config document as the source of truth for resource metadata. In the console, you can edit tags live only for manually managed resources. Declaratively managed resources must take tag changes through the same draft/apply flow as the rest of the config change.

Use this rule of thumb:

  • manual resource → edit tags live
  • declarative resource → update the draft, review, then apply

Workflow map

Validating and starting the gateway

Lint the config

kt policy lint --file policy-config.yaml

Start the gateway with a policy config

export KEEPTRUSTS_API_TOKEN="kt_your_gateway_runtime_token"
export KEEPTRUSTS_OPENAI_API_KEY="sk-..."

kt gateway run \
--agent docs-reference \
--listen 127.0.0.1:41002 \
--policy-config policy-config.yaml \
--fail-mode block

For one-off experiments you can still pass --upstream flags on the CLI, but long-lived configs should keep provider targets in YAML so the same document works for local runs, connected gateways, and console-managed configuration workflows.

Verify the running config

curl http://127.0.0.1:41002/keeptrusts/config | jq .

What the config is for

The declarative config is the source-of-truth document for local gateway behavior. Customers use it to:

  • Define the policy chain.
  • Declare provider targets and provider data-handling metadata.
  • Declare agents for agent-scoped context fabric and MCP configuration.
  • Tune behavior for each policy kind.
  • Validate changes before starting the gateway.
  • Apply a known local config to a connected running gateway from Configurations and verify the running state in Gateways and representative request outcomes with kt events tail or GET /v1/events with required since. Use History only for captured session context when history capture is enabled.

Deep-dive index

This reference explains the top-level shape. Use the companion guides for the field-heavy sections:

Strict validation rules

Keeptrusts treats the config as a strict contract.

  • Unknown top-level keys are rejected.
  • Unknown policy kinds are rejected.
  • Unknown keys inside a supported policy block are rejected.
  • Validation happens after YAML is parsed into an object model.

In practice, this means you should not add ad hoc metadata to the file unless the schema explicitly supports it.

Supported document shapes

There are two supported shapes.

1. Config document

This is the normal production and template shape.

pack:
name: demo-pack
version: 1.0.0
enabled: true
description: Demo config

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

policy:
audit-logger: {}
pii-detector:
action: redact

Required top-level objects:

  • pack
  • policies

Common optional top-level sections:

  • policy
  • providers
  • agents

The schema also defines dedicated sections for routes, consumer groups, rate limits, network controls, runtime services, testing, callbacks, models, and tool servers. A review shape exists in schema material, but the current runtime loader ignores a top-level review: section. Use the linked deep-dive pages for field-heavy sections instead of adding ad hoc keys.

2. Single-policy document

This shape is only supported for four policy kinds:

  • prompt-injection
  • agent-firewall
  • citation-verifier
  • quality-scorer

Example:

policy:
name: prompt-injection
version: 1.0.0
enabled: true

detection:
embedding_threshold: 0.8

encoding:
decode_base64: true
normalize_unicode: true

boundaries:
enforce_delimiters: true

response:
action: block
message: "Request blocked: potential prompt injection detected"

Any single-policy document for other policy kinds is rejected.

Config document structure

pack

Required fields:

  • name: non-empty string.
  • version: SemVer string.
  • enabled: boolean.

Optional field:

  • description: string.

policies

Required field:

  • chain: non-empty array of supported policy kinds or conditional chain entries.

Execution rules:

  • Policies execute in chain order.
  • Conditional chain entries can attach when, stage, parallel, and targeting metadata to a policy kind.
  • If a policy kind is in chain and policy.<kind> is missing, the gateway's runtime defaults apply.
  • If policy.<kind> exists but the kind is not in chain, it validates but does not execute.

policy

This optional object holds the per-policy configuration blocks.

providers

This optional object defines multi-provider routing targets and related behavior.

Common sub-objects:

  • targets: one or more provider targets.
  • fallback: provider fallback metadata. Lint and runtime use trigger_on; several other fields are parsed but not dispatched. See Multi-Provider Fallback before using it.
  • routing: ordered or latency-based selection strategy.
  • model_groups: virtual model aliases that map to ordered target lists.
  • pipelines: virtual model aliases that orchestrate multiple provider targets in sequence or fan_out mode.

Each target can also declare data_policy metadata for retention, training, and regulated-routing guarantees:

pack:
name: declarative-config-reference-providers-3
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-zdr
provider: openai
model: gpt-5.4-mini
base_url: https://api.openai.com
secret_key_ref:
env: KEEPTRUSTS_OPENAI_API_KEY
data_policy:
zero_data_retention: true
training_opt_out: true
retention_days: 0
policies:
chain:
- audit-logger
policy:
audit-logger: {}

This metadata is operator-declared and is used by data-routing-policy to allow or exclude targets before the fallback loop runs.

agents

This optional array declares agents for agent-scoped context fabric and MCP configuration. Each entry requires id and team; the only optional fields are context_fabric and mcp.

pack:
name: agent-declaration-example
version: 1.0.0
enabled: true
agents:
- id: support-agent
team: customer-success
policies:
chain:
- audit-logger
policy:
audit-logger: {}

Do not add usage_constraints to this array: it is not part of GatewayAgentDeclaration, and kt policy lint rejects it. Agent usage constraints are API-owned persisted controls, not declarative gateway-config fields. Manage them through the selected agent's Agent Usage Constraints flow in the Console, or use the control-plane API:

  • list or create: GET or POST /v1/agents/{id}/usage-constraints
  • update or delete: PUT or DELETE /v1/agents/{id}/usage-constraints/{constraint_id}

Supported declarative policy kinds

The schema accepts these policy kinds in policies.chain and policy.<kind> blocks:

  • agent-firewall
  • audit-logger
  • bias-monitor
  • bot-detector
  • case-privacy
  • citation-verifier
  • cjis-mode
  • code-sanitizer
  • content-extractor
  • data-routing-policy
  • dlp-filter
  • document-analyzer
  • dual-use-filter
  • embedding-detector
  • entity-list-filter
  • eu-ai-act
  • external-moderation
  • financial-compliance
  • flagged-review
  • gdpr-compliance
  • healthcare-compliance
  • hipaa-phi-detector
  • human-oversight
  • itar-ear-filter
  • language-validator
  • legal-privilege
  • mnpi-filter
  • pii-detector
  • prompt-injection
  • quality-scorer
  • rbac
  • request-rewriter
  • response-rewriter
  • safety-filter
  • student-privacy
  • tool-budget
  • tool-security
  • tool-validation
  • upl-filter

Policy field reference

Access, tool, and runtime governance

agent-firewall

Supported shapes:

  • Simple form with allowed_tools, blocked_tools, and max_actions_per_session.
  • Expanded form with role-based tool rules, rate limits, transaction limits, and the supported kill-switch checks.

Supported fields:

  • allowed_tools: string array.
  • blocked_tools: string array.
  • max_actions_per_session: integer.
  • tools.roles.<role>.allowed: non-empty string array.
  • tools.roles.<role>.denied: string array.
  • rate_limits.<tool_or_default>: integer.
  • transaction_limits.max_single_transaction: number.
  • transaction_limits.max_daily_total: number.
  • transaction_limits.require_approval_above: number.
  • kill_switches.halt_on_pii_in_action: boolean.
  • kill_switches.halt_on_suspicious_pattern: boolean.

Notes:

  • kill_switches.max_errors_before_halt is not enforced by this policy.
  • monitoring.* settings are not enforced by this policy.

rbac

Supported fields:

  • deny_if_missing: string array.
  • require_auth: boolean.
  • roles.<role>.allowed_tools: string array.
  • roles.<role>.denied_tools: string array.
  • data_access.<scope>.max_sensitivity: public | internal | confidential | restricted.
  • minimum_necessary.enabled: boolean.
  • minimum_necessary.allowed_phi_roles: string array.

cjis-mode

Supported fields:

  • require_auth: boolean.
  • access_logging: boolean.
  • encryption_at_rest: boolean.
  • session_timeout_minutes: integer from 1 through 1440.

Runtime note: require_auth controls the verdict and access_logging controls the structured access-log marker. encryption_at_rest and session_timeout_minutes are validated declarations but do not currently change this policy's verdict.

audit-logger

Public-safe shape:

  • audit-logger: {}

Current behavior:

  • The policy treats audit-logger as an allow-only marker in the chain.
  • The schema accepts immutable, retention_days, hipaa_audit_controls, and log_all_access, but the current gateway evaluator does not enforce them. Configure retention, immutability, and storage controls in their owning platform layers.

data-routing-policy

Use this control when you need to restrict which upstream providers may receive traffic based on their declared data-handling properties.

Supported fields:

  • require_zero_data_retention: boolean.
  • require_no_training: boolean.
  • max_retention_days: integer.
  • on_no_compliant_provider: block | warn.
  • log_provider_selection: boolean.
  • require_in_memory_only: boolean.
  • sanitize_before_provider: boolean.
  • tokenize_sensitive_fields: boolean.
  • allow_internet_egress: boolean.
  • local_only_processing: boolean.

Operational behavior:

  • Runs before provider fallback selection.
  • Excludes targets that do not satisfy the declared requirements.
  • Returns HTTP 403 when no providers remain and on_no_compliant_provider is block.
  • Continues with the full target list when no providers remain and on_no_compliant_provider is warn.

Validation and linting also catch common mistakes, including:

  • data-routing-policy without providers.targets
  • contradictory target metadata when zero_data_retention: true
  • configurations where every provider would be excluded at runtime

Privacy, safety, and content filters

prompt-injection

Supported fields:

  • embedding_threshold: number.
  • backend: local | external.
  • endpoint: non-empty string.
  • model: non-empty string.
  • api_key: non-empty string.
  • timeout_ms: integer from 1 through 60000.
  • attack_patterns: string array.
  • encoding.decode_base64: boolean.
  • encoding.normalize_unicode: boolean.
  • encoding.detect_homoglyphs: boolean.
  • boundaries.enforce_delimiters: boolean.
  • boundaries.reject_fake_boundaries: boolean.
  • response.action: block.
  • response.message: string.
  • response.log_level: trace | debug | info | warn | error.
  • data_poisoning.enabled: boolean.
  • data_poisoning.backdoor_trigger_patterns: string array.
  • data_poisoning.perplexity_threshold: non-negative number.
  • data_poisoning.anomaly_action: block | warn | audit.

Runtime note: the detector uses the encoding, boundary, attack-pattern, embedding, and data-poisoning fields. For data poisoning, only anomaly_action: block changes the verdict; warn and audit leave the request allowed and expose the signal in policy details. The response section is validated but does not currently alter the gateway verdict, returned message, or log level.

pii-detector

Supported fields:

  • action: redact | block.
  • healthcare_mode: boolean.
  • pci_mode: boolean.
  • detect_patterns: string array.
  • redaction.marker_format: label | asterisk | partial.
  • redaction.include_metadata: boolean.
  • redaction.preserve_length: boolean.
  • redaction.custom_markers.<entity>: string map.

hipaa-phi-detector

Supported fields:

  • mode: hipaa_18.
  • action: redact | block.
  • safe_harbor_method: boolean.

dlp-filter

Supported fields:

  • detect_patterns: string array.
  • blocked_terms: string array.
  • action: redact | block.
  • fuzzy_matching: boolean.
  • max_distance: integer.
  • sensitivity_level: standard | high | restricted.

document-analyzer

Supported fields:

  • enabled: boolean.
  • sanitize_code: boolean.
  • max_document_bytes: integer.
  • allowed_mime_types: string array.

dual-use-filter

Supported fields:

  • blocked_terms: string array.
  • action: block | redact.
  • fuzzy_matching: boolean.
  • max_distance: integer.

embedding-detector

Supported fields:

  • backend: local | external.
  • endpoint: string.
  • model: string.
  • api_key: string.
  • similarity_threshold: number.
  • timeout_ms: integer.
  • action: redact | block.
  • categories[].label: string.
  • categories[].reference_text: string.

entity-list-filter

Supported fields:

  • blocked_entities: string array.
  • fuzzy_matching: boolean.
  • max_distance: integer.

The policy always blocks on a match. There is no configurable action variant.

external-moderation

Supported fields:

  • provider: provider enum.
  • secret_key_ref.env: string.
  • endpoint: string.
  • categories: string array.
  • threshold: number.
  • timeout_ms: integer.
  • fail_closed: boolean.
  • webhook_headers: string map.
  • aws_region: string.
  • aws_access_key_env: string.
  • aws_secret_key_env: string.
  • aws_session_token_env: string.
  • guardrail_id: string.
  • guardrail_version: string.
  • embedding_model: string.
  • reference_texts: string array.
  • presidio_language: string.
  • presidio_entities: string array.
  • guard_name: string.
  • policy_id: string.
  • lakera_categories: string array.

itar-ear-filter

Supported fields:

  • blocked_terms: string array.
  • action: block.
  • fuzzy_matching: boolean.
  • max_distance: integer from 0 through 8.

safety-filter

Supported fields:

  • mode: critical_infrastructure | automotive | education | law_enforcement | government | military | hr | justice | healthcare | finance | legal | defense.
  • block_if: string array.
  • action: block | escalate.
  • fuzzy_matching: boolean.
  • max_distance: integer from 0 through 8.
  • max_age: non-negative integer.

The gateway has distinct built-in term sets for critical_infrastructure, automotive, education, and law_enforcement. The other accepted modes use the generic critical-term set unless block_if adds domain terms.

student-privacy

Supported fields:

  • action: redact | block.
  • age_gate: boolean.

case-privacy

Supported fields:

  • detect_patterns: string array.
  • action: redact.

Domain-specific output and compliance controls

citation-verifier

Supported fields:

  • require_sources: boolean.
  • require_source_match: boolean.
  • min_confidence: number.
  • min_groundedness: number.
  • extract_patterns: array of case_law | academic | url | quote | statistic.
  • rag_context.verify_against_context: boolean.
  • rag_context.min_context_overlap: number.
  • output_action.unverified_action: flag | redact | block.
  • response.include_verification_report: boolean.
  • external_resolver.endpoint: non-empty string.
  • external_resolver.api_key: non-empty string.
  • external_resolver.timeout_ms: integer from 1 through 60000.

Notes:

  • external_resolver and output_action.hallucination_action are validated but are not called by the current gateway evaluator.
  • block is the only unverified action that changes the verdict. flag and redact both keep the verdict as allow and surface verification details; redact does not currently rewrite the response.

quality-scorer

Core tuning fields:

  • industry: string. Accepted metadata; runtime profile selection comes from request.keeptrusts.industry instead.
  • min_output_chars: integer.
  • min_sentences: integer.
  • mock_scoring: boolean. Accepted but not used by the current gateway scorer.

Provider targeting fields:

  • providers: array of provider interface entries.
  • targets: alias of providers.
  • Each entry may be a string shorthand or an object with at least one of provider, target, model, or id.
  • Provider objects may also include label, base_url, secret_key_ref, headers, and config.

The providers and targets blocks validate, but the current gateway scorer does not use them to select assertion providers; provider-backed assertion and judge configuration is read from the applicable assertion or judge block.

Benchmark fields:

  • benchmarks.ragas_faithfulness: boolean.
  • benchmarks.ragas_relevancy: boolean.
  • benchmarks.bleu_score: boolean.
  • benchmarks.nli_entailment: boolean.
  • benchmarks.coherence: boolean.
  • benchmarks.completeness: boolean.

Assertion support:

  • assertions[] supports output, context, conversational, and trajectory-based assertion types.
  • Every assertion requires type.
  • Assertions may also include name, enabled, threshold, weight, and config.

Supported assertion categories:

  • Output-based: assert-set, search-rubric, model-graded-closedqa, model-graded-fact, factuality, g-eval, llm-rubric, answer-relevance, contains, contains-all, contains-any, contains-json, contains-html, contains-sql, contains-xml, cost, equals, f-score, finish-reason, icontains, icontains-all, icontains-any, is-html, is-json, is-refusal, is-sql, is-valid-function-call, is-valid-openai-function-call, is-valid-openai-tools-call, is-xml, javascript, latency, levenshtein, perplexity-score, perplexity, pi, python, regex, rouge-n, similar, classifier, moderation, select-best, starts-with, tool-call-f1, trace-span-count, trace-span-duration, trace-error-spans, word-count, max-score.

webhook is not a supported assertion type in the current quality evaluator or lint assertion registry.

  • Context-based: context-recall, context-relevance, context-faithfulness.
  • Conversational: conversation-relevance.
  • Trajectory-based: trajectory:goal-success, trajectory:tool-used, trajectory:tool-sequence, trajectory:step-count.

Threshold and weighting fields:

  • thresholds.min_aggregate
  • thresholds.min_faithfulness
  • thresholds.min_relevancy
  • thresholds.min_bleu
  • thresholds.min_coherence
  • thresholds.min_completeness
  • thresholds.min_accuracy
  • weights.faithfulness
  • weights.relevancy
  • weights.bleu
  • weights.coherence
  • weights.completeness
  • weights.accuracy

Industry profile and failure behavior fields:

  • industry_profiles.<profile>.min_aggregate
  • industry_profiles.<profile>.min_accuracy
  • industry_profiles.<profile>.min_faithfulness
  • industry_profiles.<profile>.min_relevancy
  • industry_profiles.<profile>.min_coherence
  • industry_profiles.<profile>.min_completeness
  • failure_action.action: block | fallback | retry.
  • failure_action.fallback_message: string.
  • failure_action.max_retries: integer.
  • pass_policy: assertion aggregation object.
  • judge: optional secondary judge configuration.
  • regression_monitoring: accepted monitoring metadata; not used by the current gateway scorer.

Only failure_action.action: fallback has distinct runtime handling today: it substitutes fallback_message and allows the replacement response. retry and max_retries are accepted configuration but do not run a retry loop; a failed quality result configured as retry currently ends with a blocked verdict.

human-oversight

Supported fields:

  • require_human_for: string array.
  • action: escalate | block.
  • confidence_threshold: number from 0 through 1.
  • default_assignee: non-empty string.
  • timeout_seconds: integer from 1 through 604800.

Runtime note: only action: escalate is effective, and it escalates every response reaching this policy. block and the targeting, assignment, confidence, and timeout fields are accepted but do not currently affect execution.

bias-monitor

Supported fields:

  • protected_characteristics: string array.
  • threshold: number.
  • action: block | escalate.

Runtime note: the evaluator uses threshold with its built-in HR/protected-characteristic heuristic and always emits escalate on a hit. protected_characteristics and action are accepted but do not currently change the detector or verdict.

mnpi-filter

Supported fields:

  • detect_patterns: string array.
  • action: block.

financial-compliance

Supported fields:

  • blocked_patterns: string array.
  • required_disclaimers: string array.

healthcare-compliance

Supported fields:

  • blocked_patterns: string array.
  • required_disclaimers: string array.
  • fda_class: I | II | III.

Supported fields:

  • privilege_markers: string array.
  • action: block.

upl-filter

Supported fields:

  • blocked_patterns: string array.
  • require_disclaimer: boolean.
  • rewrite_to_educational: boolean.

Single-policy top-level sections

If you intentionally use the single-policy shape, the allowed top-level sections depend on the policy kind.

  • prompt-injection: detection, encoding, boundaries, response.
  • agent-firewall: use either the simple fields (allowed_tools, blocked_tools, optional max_actions_per_session) or the expanded sections (tools, rate_limits, transaction_limits, kill_switches).
  • citation-verifier: verification, rag_context, output_action, response.
  • quality-scorer: providers, targets, benchmarks, assertions, thresholds, weights, industry_profiles, failure_action.

Any other top-level section is rejected.

Common validation failures

  • Missing pack or policies in a config document.
  • Empty policies.chain.
  • Unsupported policy kind in chain.
  • Using single-policy structure for a policy kind that only supports the config document shape.
  • Copying extra metadata into the config that the schema does not recognize.
  1. Start from a template or a known-good policy-config.yaml.
  2. Keep the policies.chain explicit and in the intended execution order.
  3. Add only the policy blocks you need to override from defaults.
  4. Validate before runtime with kt policy lint --file policy-config.yaml.
  5. Run the gateway with the same file.
  6. Send representative traffic, preserve its request IDs, and verify the running state in Gateways and the resulting Events with kt events tail or the Events API. Check Inbox for resulting human-review work. Use History only when capture is enabled and the investigation needs retained session context.

Next steps