Declarative Config Patterns for Enterprise AI
Keeptrusts is designed to be operated through declarative config. For most teams, policy-config.yaml is the product surface: it defines what the gateway should enforce, where traffic can go, which limits apply, and how reviews or audits are recorded.
Use this page when
- You are structuring
policy-config.yamlfor multi-environment deployment (staging, production, regulated). - You need patterns for keeping secrets out of YAML, using
secret_key_refand config variables. - You want a repeatable rollout path from local validation to console-managed gateways.
Use the CLI, console, and optional API to validate, distribute, and observe that same document. Do not treat the API as the primary authoring surface unless you have a clear automation requirement that the CLI or console cannot cover.
Primary audience
- Primary: Technical Engineers designing config-as-code governance workflows
- Secondary: Platform Architects, AI Agents authoring configs programmatically
Use this guide when
- You want one source of truth for AI governance.
- You need separate configs for staging, production, or regulated workloads.
- You want to keep provider credentials out of YAML.
- You want a repeatable rollout path from local testing to shared gateways.
Recommended repository layout
ai-governance/
├── policy-config.yaml
├── tests/
│ ├── allows_normal_request.yaml
│ ├── blocks_prompt_injection.yaml
│ └── redacts_pii.yaml
└── README.md
For multiple environments, keep one full config per environment instead of relying on undocumented inheritance:
configs/
├── staging/policy-config.yaml
├── production/policy-config.yaml
└── regulated/policy-config.yaml
tests/
├── staging/
├── production/
└── regulated/
This keeps every deployed environment explicit, reviewable, and easy to lint in CI.
Pattern 1: Keep one full config document per environment
Start from the current supported shape:
pack:
name: customer-support
version: 0.1.0
enabled: true
description: Support assistant with redaction, routing, and audit logging
providers:
targets:
- id: openai-primary
provider: openai
model: gpt-4o
base_url: https://api.openai.com
secret_key_ref:
env: OPENAI_API_KEY
policies:
chain:
- prompt-injection
- pii-detector
- audit-logger
policy:
pii-detector:
action: redact
audit-logger:
retention_days: 365
When you need environment-specific differences, copy the full config and change only the fields that are intentionally different, such as provider targets, data-policy metadata, rate limits, or audit retention.
Pattern 2: Keep secrets out of YAML
For local and self-hosted gateways, prefer secret_key_ref:
pack:
name: declarative-config-providers-2
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-primary
provider: openai
model: gpt-4o
secret_key_ref:
env: OPENAI_API_KEY
policies:
chain:
- audit-logger
policy:
audit-logger:
immutable: true
retention_days: 365
log_all_access: true
export OPENAI_API_KEY="sk-..."
For hosted gateways, prefer secret_key_ref.store so the control plane resolves the credential at runtime:
pack:
name: declarative-config-providers-3
version: 1.0.0
enabled: true
providers:
targets:
- id: openai-primary
provider: openai
model: gpt-4o
secret_key_ref:
store: OPENAI_API_KEY
policies:
chain:
- audit-logger
policy:
audit-logger:
immutable: true
retention_days: 365
log_all_access: true
Create and manage that value with the CLI or console instead of hardcoding secrets:
kt config-var create --name OPENAI_API_KEY --value "sk-..."
kt config-var resolve --name OPENAI_API_KEY
See Environment Variable Patterns and kt config-var for the full resolution model.
Pattern 3: Treat validation as part of authoring
Every config change should go through the same loop:
kt policy lint --file policy-config.yaml
kt policy test --json
Use kt init to generate starter tests, then expand tests/ with representative real-world cases:
tests/
├── allows_normal_request.yaml
├── blocks_injection.yaml
├── escalates_sensitive_output.yaml
└── routes_zdr_requests_only.yaml
This keeps policy behavior reviewable before traffic ever hits production.
Pattern 4: Declare routing and constraints in config, not in app code
Put provider selection, fallback, and data-handling requirements in policy-config.yaml:
providers:
targets:
- id: openai-zdr
provider: openai
model: gpt-4o
secret_key_ref:
env: OPENAI_API_KEY
- id: anthropic-standard
provider: anthropic
model: claude-sonnet-4-20250514
secret_key_ref:
env: ANTHROPIC_API_KEY
routing:
strategy: ordered
fallback:
triggers:
- rate_limit
- server_error
- timeout
max_fallback_attempts: 2
policies:
chain:
- data-routing-policy
- prompt-injection
- audit-logger
policy:
data-routing-policy:
require:
zero_data_retention: true
on_no_compliant_provider: block
That keeps your application integration simple: point the app at the gateway and let config decide how requests are governed.
Pattern 5: Roll out versions, not one-off edits
Use one of these rollout paths:
| Workflow | Best for | Start with |
|---|---|---|
| Local authoring + CLI validation | Fast iteration on a developer machine | Quickstart |
| Saved versions in the console | Teams that want review, version history, and controlled rollout | Configurations |
| Versioned configuration rollout | Teams treating config as code in a shared repo | Configurations |
After rollout, verify the live result from the runtime surfaces:
Pattern 6: Prefer purpose-built docs over raw API calls
Most config workflows already have a better interface than the raw API:
| Need | Recommended surface |
|---|---|
| Bootstrap a new config | kt init |
| Validate or test a config | kt policy lint and kt policy test |
| Manage config variables | kt config-var or the console |
| Save versions and roll them out | Configurations |
| Roll out a saved config version | Configurations |
Use the API reference only when you are building custom automation around these workflows.
Anti-patterns to avoid
- Hardcoding provider API keys or secrets in YAML
- Treating a single successful request as sufficient validation
- Editing shared environments without versioning or change notes
- Relying on undocumented inheritance or overlay behavior instead of explicit per-environment config files
- Designing your application around direct provider routing when the gateway config should own that decision
For AI systems
- Canonical terms:
policy-config.yaml,pack,providers.targets,secret_key_ref,policies.chain,policy.*, config variables,kt config-var,kt init,kt policy lint,kt policy test. - Supported rollout paths: local CLI validation and console saved versions.
- Provider routing:
routing.strategy,fallback.triggers,data_policy.zero_data_retention. - Anti-patterns to avoid: hardcoded secrets, undocumented inheritance, editing shared configs without versioning.
- Best next pages: Declarative Config Reference, Providers Configuration, Config Validation.
For engineers
- Repository layout: one full
policy-config.yamlper environment underconfigs/<env>/; sharedtests/directory per env. - Secret management: use block-form
secret_key_refobjects for both local and hosted gateways, for exampleenv: VARlocally orstore: VARwith config-variable resolution. - Validation loop:
kt policy lint --file policy-config.yaml && kt policy test --jsonbefore every deploy. - Verify live: check Gateways and Actions and Events after rollout.
For leaders
- Declarative config makes AI governance auditable: every policy is explicit YAML, versioned, and reviewable in pull requests.
- Separate per-environment configs eliminate risk of staging rules leaking into production.
- Config-as-code enables the same change-management process (PR review, CI validation, approval) used for application code.
- Reduces vendor lock-in: policies are portable YAML, not opaque platform settings.
Agent history, learning, memory, and review behavior is declared in the history, learning, memory, and review sections of the configuration YAML. The CLI control manifest no longer supports resources.agents[].learning or resources.agents[].review fields — those knobs are owned by the configuration version referenced in resources.agents[].deployment.configuration_version_id.
Next steps
- Declarative Config Reference — complete schema and validation rules
- Providers Configuration — provider targets, fallback, routing, and data policies
- Environment Variable Patterns —
_envandsecret_key_refguidance - Testing Configuration — inline and external test patterns
- End-to-End Configuration Scenarios — full working examples