Terraform provider
Manage KavachOS agents, permissions, API keys, and organizations as Terraform resources.
Why IaC for auth
Auth config drifts in ways application code doesn't. An agent spun up by hand in a dashboard has no peer review, no version history, and no automated rollback. When the production incident happens and you need to know why an agent had write access to the deploy tool, "someone added it last Tuesday" is not an audit trail.
Treating agents and permissions as Terraform resources fixes this. Every grant goes through a pull request. Every change is versioned in git. Destroying a staging environment tears down the access alongside the infrastructure — no orphaned tokens floating around.
Installation
The provider requires Go 1.21 to build.
Clone the repository and build the binary:
git clone https://github.com/kavachos/terraform-provider-kavachos
cd terraform-provider-kavachos/sdks/terraform
go build -o terraform-provider-kavachos .Install into the local plugin cache:
OS=$(go env GOOS)
ARCH=$(go env GOARCH)
PLUGIN_DIR=~/.terraform.d/plugins/registry.terraform.io/kavachos/kavachos/0.1.0/${OS}_${ARCH}
mkdir -p "$PLUGIN_DIR"
mv terraform-provider-kavachos "$PLUGIN_DIR/"Declare the provider in your Terraform configuration:
terraform {
required_version = ">= 1.5"
required_providers {
kavachos = {
source = "kavachos/kavachos"
version = "~> 0.1"
}
}
}Provider setup
provider "kavachos" {
base_url = "https://your-app.com/api/kavach"
token = var.kavachos_token
}Both arguments can be set via environment variables, which is preferred in CI:
export KAVACHOS_BASE_URL=https://your-app.com/api/kavach
export KAVACHOS_TOKEN=kv_live_...Prop
Type
Resources
kavachos_agent
Manages an agent identity — the primary entity in KavachOS.
resource "kavachos_agent" "github_reader" {
owner_id = "user-123"
name = "github-reader"
type = "autonomous"
permission {
resource = "mcp:github:*"
actions = ["read"]
}
permission {
resource = "mcp:deploy:production"
actions = ["execute"]
constraints {
require_approval = true
max_calls_per_hour = 10
ip_allowlist = ["10.0.0.0/8"]
}
}
expires_at = "2026-12-31T23:59:59Z"
}The token attribute is computed on creation and marked sensitive. Read it with:
terraform output -raw github_reader_tokenThe raw token is only returned once, at creation time. KavachOS does not store it in recoverable form. If you lose it, rotate the agent's token via the API or dashboard.
Prop
Type
Permission block arguments
Prop
Type
Constraints block arguments
Prop
Type
kavachos_permission
Grants a single permission to an existing agent from a separate module. If you control both the agent and all its permissions in one place, use inline permission blocks on kavachos_agent instead.
resource "kavachos_permission" "staging_deploy" {
agent_id = kavachos_agent.deploy_bot.id
resource = "mcp:deploy:staging"
actions = ["execute"]
max_calls_per_hour = 20
}Prop
Type
kavachos_api_key
Manages an API key for server-to-server requests.
resource "kavachos_api_key" "ci_pipeline" {
name = "ci-pipeline"
scopes = ["agents:read", "agents:write"]
}
output "ci_key" {
value = kavachos_api_key.ci_pipeline.key
sensitive = true
}Valid scopes: agents:read, agents:write, audit:read, delegation:read, delegation:write, organizations:read, organizations:write, admin.
The key attribute is only populated immediately after creation. Read it with terraform output -raw ci_key and store it in your secret manager before the session ends.
kavachos_organization
Manages an organization for multi-tenant isolation.
resource "kavachos_organization" "engineering" {
name = "Engineering"
slug = "engineering"
plan = "pro"
}slug is immutable after creation. Change it by deleting and recreating the organization.
Data sources
kavachos_agent
Reads an agent that was not created by this Terraform configuration.
data "kavachos_agent" "legacy" {
id = "agent-id-from-dashboard"
}
output "status" {
value = data.kavachos_agent.legacy.status
}kavachos_agents
Lists agents, optionally filtered.
data "kavachos_agents" "active_bots" {
owner_id = "user-123"
status = "active"
type = "autonomous"
}
output "bot_count" {
value = length(data.kavachos_agents.active_bots.agents)
}Filter arguments: owner_id, status (active | revoked | expired), type (autonomous | delegated | service).
Import existing state
Resources provisioned outside Terraform can be brought under management:
# Import an agent
terraform import kavachos_agent.my_bot agent-abc123
# Import an API key
terraform import kavachos_api_key.ci kv_key_abc123
# Import an organization
terraform import kavachos_organization.eng org-xyz789After importing, run terraform plan. Terraform will show a diff for any attributes that differ from your configuration. Update the HCL to match, or let Terraform converge.
Importing an API key restores the ID and metadata but not the raw key value — that was only available at creation time.
GitOps workflow
Manage KavachOS configuration alongside your application infrastructure:
infra/
├── main.tf # Provider and state backend
├── organizations.tf # kavachos_organization resources
├── agents.tf # Agent definitions
├── api_keys.tf # API keys for CI and services
└── variables.tfA minimal GitHub Actions workflow:
name: Terraform
on:
push:
branches: [main]
paths: ['infra/**']
pull_request:
paths: ['infra/**']
jobs:
terraform:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.8"
- run: terraform -chdir=infra init
- name: Plan
id: plan
env:
KAVACHOS_BASE_URL: ${{ secrets.KAVACHOS_BASE_URL }}
KAVACHOS_TOKEN: ${{ secrets.KAVACHOS_TOKEN }}
run: terraform -chdir=infra plan -out=tfplan -no-color
- name: Apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
env:
KAVACHOS_BASE_URL: ${{ secrets.KAVACHOS_BASE_URL }}
KAVACHOS_TOKEN: ${{ secrets.KAVACHOS_TOKEN }}
run: terraform -chdir=infra apply tfplanEvery permission change ships as a pull request diff. The plan output shows exactly what will change before it's applied. The apply only runs on merge to main.
This means the same controls you use for code changes — required reviewers, branch protection, signed commits — apply to auth config changes too.