Skip to main content
Browse docs
By Audience
Getting Started
Configuration
Use Cases
IDE Integration
Third-Party Integrations
Engineering Cache
Console
API Reference
Gateway
Workflow Guides
Templates
Providers and SDKs
Industry Guides
Advanced Guides
Browse by Role
Deployment Guides
In-Depth Guides
Tutorials
FAQ

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.yaml for multi-environment deployment (staging, production, regulated).
  • You need patterns for keeping secrets out of YAML, using secret_key_ref and 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.
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:

WorkflowBest forStart with
Local authoring + CLI validationFast iteration on a developer machineQuickstart
Saved versions in the consoleTeams that want review, version history, and controlled rolloutConfigurations
Versioned configuration rolloutTeams treating config as code in a shared repoConfigurations

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:

NeedRecommended surface
Bootstrap a new configkt init
Validate or test a configkt policy lint and kt policy test
Manage config variableskt config-var or the console
Save versions and roll them outConfigurations
Roll out a saved config versionConfigurations

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.yaml per environment under configs/<env>/; shared tests/ directory per env.
  • Secret management: use block-form secret_key_ref objects for both local and hosted gateways, for example env: VAR locally or store: VAR with config-variable resolution.
  • Validation loop: kt policy lint --file policy-config.yaml && kt policy test --json before 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 runtime knobs are configuration-owned

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