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
- Python
- Node.js
curl http://127.0.0.1:41002/keeptrusts/config | jq .
import httpx
config = httpx.get("http://localhost:41002/keeptrusts/config").json()
print(config["pack"]["name"], config["pack"]["version"])
print("Policy chain:", config["policies"]["chain"])
const config = await fetch("http://localhost:41002/keeptrusts/config").then(r => r.json());
console.log(config.pack.name, config.pack.version);
console.log("Policy chain:", config.policies.chain);
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 tailorGET /v1/eventswith requiredsince. 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:
- Providers Configuration
- Data Policies and Data Routing
- Rate Limits Configuration
- Routes and Consumer Groups
- Conditional Chains Configuration
- Security and Network Configuration
- Runtime Configuration
- Environment Variable Patterns
- Quality Assertions Configuration
- Config Testing
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:
packpolicies
Common optional top-level sections:
policyprovidersagents
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-injectionagent-firewallcitation-verifierquality-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
chainorder. - Conditional chain entries can attach
when,stage,parallel, andtargetingmetadata to a policy kind. - If a policy kind is in
chainandpolicy.<kind>is missing, the gateway's runtime defaults apply. - If
policy.<kind>exists but the kind is not inchain, 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 usetrigger_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 insequenceorfan_outmode.
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:
GETorPOST /v1/agents/{id}/usage-constraints - update or delete:
PUTorDELETE /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-firewallaudit-loggerbias-monitorbot-detectorcase-privacycitation-verifiercjis-modecode-sanitizercontent-extractordata-routing-policydlp-filterdocument-analyzerdual-use-filterembedding-detectorentity-list-filtereu-ai-actexternal-moderationfinancial-complianceflagged-reviewgdpr-compliancehealthcare-compliancehipaa-phi-detectorhuman-oversightitar-ear-filterlanguage-validatorlegal-privilegemnpi-filterpii-detectorprompt-injectionquality-scorerrbacrequest-rewriterresponse-rewritersafety-filterstudent-privacytool-budgettool-securitytool-validationupl-filter
Policy field reference
Access, tool, and runtime governance
agent-firewall
Supported shapes:
- Simple form with
allowed_tools,blocked_tools, andmax_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_haltis 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-loggeras an allow-only marker in the chain. - The schema accepts
immutable,retention_days,hipaa_audit_controls, andlog_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_providerisblock. - Continues with the full target list when no providers remain and
on_no_compliant_provideriswarn.
Validation and linting also catch common mistakes, including:
data-routing-policywithoutproviders.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 ofcase_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_resolverandoutput_action.hallucination_actionare validated but are not called by the current gateway evaluator.blockis the only unverified action that changes the verdict.flagandredactboth keep the verdict asallowand surface verification details;redactdoes not currently rewrite the response.
quality-scorer
Core tuning fields:
industry: string. Accepted metadata; runtime profile selection comes fromrequest.keeptrusts.industryinstead.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 ofproviders.- Each entry may be a string shorthand or an object with at least one of
provider,target,model, orid. - Provider objects may also include
label,base_url,secret_key_ref,headers, andconfig.
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, andconfig.
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_aggregatethresholds.min_faithfulnessthresholds.min_relevancythresholds.min_bleuthresholds.min_coherencethresholds.min_completenessthresholds.min_accuracyweights.faithfulnessweights.relevancyweights.bleuweights.coherenceweights.completenessweights.accuracy
Industry profile and failure behavior fields:
industry_profiles.<profile>.min_aggregateindustry_profiles.<profile>.min_accuracyindustry_profiles.<profile>.min_faithfulnessindustry_profiles.<profile>.min_relevancyindustry_profiles.<profile>.min_coherenceindustry_profiles.<profile>.min_completenessfailure_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.
legal-privilege
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, optionalmax_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
packorpoliciesin 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.
Recommended authoring workflow
- Start from a template or a known-good
policy-config.yaml. - Keep the
policies.chainexplicit and in the intended execution order. - Add only the policy blocks you need to override from defaults.
- Validate before runtime with
kt policy lint --file policy-config.yaml. - Run the gateway with the same file.
- Send representative traffic, preserve its request IDs, and verify the
running state in Gateways and the resulting Events with
kt events tailor 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
- Policy Controls Catalog — Browse all available policies
- Config Providers — Provider targets and routing
- Config Testing — Inline test suites
- Config-First Workflow — Operating model for policy rollout