Declarative Configuration with kt control
Keeptrusts has two different declarative surfaces, and mixing them up creates unnecessary confusion. policy-config.yaml defines runtime AI behavior. control-manifest.yaml defines the control-plane resources around that runtime. kt control is the command group that reconciles the second category so teams can manage surrounding inventory as code instead of through manual drift-prone changes.
Use this page when
- You need infrastructure-as-code for org-level resources such as teams, users, agents, budgets, and secrets.
- You want a dry-run and apply workflow for control-plane state that complements runtime policy config.
- You need to explain where
kt controlfits without confusing it withkt gateway runorpolicy-config.yaml.
Primary audience
- Primary: Platform engineers and technical operators
- Secondary: Technical Leaders, security teams, AI operations teams
The problem
As soon as an AI platform moves beyond a single developer setup, runtime policy is only half the story. Teams also need a reliable way to manage surrounding control-plane state: which teams exist, which users belong to them, which agents are defined, what budgets apply, how secrets are declared, and which organizational defaults should be present.
If that surrounding state is managed manually, drift appears quickly. A staging environment accumulates slightly different teams. An agent gets created in one environment and forgotten in another. Budgets are updated in the console but not mirrored into code review. The platform still works, but the operational model becomes harder to audit and harder to reproduce.
This is exactly the gap kt control closes. It is not a replacement for runtime config. It is the declarative layer for everything around the runtime that still needs to be versioned, reviewed, and reconciled.
The solution
kt control provides three real subcommands for that workflow:
kt control exportto scaffold current remote state into a manifestkt control planto compute a dry-run diffkt control applyto reconcile remote state to the manifest
That is the familiar infrastructure-as-code loop. Export or author the desired state, inspect the planned changes, then apply intentionally.
The supported resource set is broad enough to matter in day-to-day operations. The CLI supports declarative resources including secrets, IAM policies and roles, teams, users, agents, billing budgets, knowledge assets, regulated execution profiles, approval policies, memory policies, prompt evaluation suites, collaboration defaults, hosted gateway settings, and auth org policy.
Implementation
At the manifest level, the core shape is simple:
version: "1"
resources:
teams:
- name: finance
description: Finance operations
users:
- email: alice@example.com
teams: [finance]
agents:
- name: finance-bot
gateways: [gw-finance]
learning:
enabled: true
strategy: extract
source_policy: allowed_only
schedule: on_session_close
budgets:
- name: org-monthly-cap
amount: "1000.00"
period_type: monthly
billing_categories: [gateway_llm, data_transfer]
Once the manifest exists, the operating loop is equally simple:
kt control export --file control-manifest.yaml
kt control plan --file control-manifest.yaml --json
kt control apply --file control-manifest.yaml --yes
This is where the separation from runtime config matters. The gateway does not need to know how teams or budgets were declared. It only needs the runtime config and the resolved surrounding state. kt control is what keeps that surrounding state converged.
There are two habits worth adopting immediately.
First, always run plan before apply. The command exists for a reason. A dry-run diff is the cheapest way to catch unintended mutations before they hit shared environments.
Second, use --prune deliberately rather than casually. Pruning includes delete operations for remote resources absent from the manifest. That is powerful, but it should be treated as an intentional cleanup step, not a default reflex.
The export command is also more useful than it looks. Teams often assume declarative tooling only helps greenfield environments. In practice, kt control export is what makes brownfield adoption sane. It lets you capture existing remote state into a manifest, review it, and then start managing it declaratively from there.
One final point is easy to miss: kt control complements the config-first workflow, it does not replace it. Runtime policy behavior still belongs in policy-config.yaml. The control manifest is for org-level state around the runtime. When teams keep that boundary clean, both surfaces stay easier to reason about.
Results and impact
The obvious benefit is drift reduction. Shared resources become reviewable and reproducible instead of living only in a mutable control plane.
The broader benefit is change clarity. Engineers can look at a manifest diff and understand whether a rollout changes users, agents, budgets, or secrets separately from whether it changes runtime policy behavior. That reduces the blast radius of each change and makes approval easier.
It also creates a better path for scale. Multi-team environments do not stay manageable through memory and screenshots. They stay manageable when the surrounding control-plane inventory is versioned and reconciled with the same discipline teams already apply to application infrastructure.
Key takeaways
kt controlis the declarative interface for control-plane state, not runtime policy behavior.export,plan, andapplyform the core operating loop.control-manifest.yamlshould live beside runtime config, but it should not absorb runtime policy definitions.planbeforeapplyis the safety habit that keeps the workflow predictable.- Declarative control state becomes more valuable as environments and teams multiply.