GitOps for AI Policy Management
GitOps applies the principle that Git is the single source of truth for your desired system state. For AI governance, this means policy configurations live in Git, changes go through pull requests, and the platform automatically syncs the running state to match the repository. This guide covers setting up git-linked repos, automating sync, managing changes through PRs, and rolling back with git revert.
Use this page when
- You are setting up git-linked repos for automatic policy sync to running gateways
- You want PR-based policy change workflows with branch protection and CI validation
- You need to implement rollback via
git revertor emergency API override
Primary audience
- Primary: Technical Engineers
- Secondary: AI Agents, Technical Leaders
How Git Sync Works
The Keeptrusts API polls linked Git repositories on a configurable interval. When it detects a change to the tracked config file, it:
- Pulls the latest commit from the tracked branch
- Diffs the config against the stored configuration version
- Creates a new configuration version if changes are detected
- Signals connected gateways to reload their policy chain
Git Repository (main branch)
│
├─ commit: "Update PII patterns"
│
▼
Keeptrusts API (poll interval: 60s)
│
├─ Detect diff → Create new config version
│
▼
Gateway fleet (reload signal)
│
└─ Hot-reload policy chain (zero downtime)
Setting Up Git-Linked Repos
Via the API
curl -X POST https://keeptrusts-api.internal:8080/v1/git-repos \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"repo_url": "https://github.com/org/ai-policies.git",
"branch": "main",
"path": "teams/payments/prod/policy-config.yaml",
"poll_interval_seconds": 60,
"auto_create_configuration": true,
"access_token": "ghp_..."
}'
The access_token is encrypted at rest with AES-GCM-SIV. The API never exposes it in subsequent GET responses.
Via the Console
Navigate to Configurations in the management console:
- Click Link Repository
- Enter the repository URL, branch, and file path
- Provide an access token (PAT or deploy key)
- Set the poll interval (minimum 30 seconds)
- Enable Auto-create configuration for first-time sync
- Save — the API begins polling immediately
The console displays sync status, last sync timestamp, and the current configuration version for each linked repo.
Via Terraform
resource "keeptrusts_git_linked_repo" "payments_policy" {
repo_url = "https://github.com/org/ai-policies.git"
branch = "main"
path = "teams/payments/prod/policy-config.yaml"
poll_interval_seconds = 60
auto_create_configuration = true
access_token = var.github_pat
}
PR-Based Policy Changes
The PR Workflow
All policy changes follow the standard pull request flow:
# 1. Create a feature branch
git checkout -b policy/increase-payments-spend-limit
# 2. Edit the policy config
vi teams/payments/prod/policy-config.yaml
# Change max_daily_usd from 250 to 500
# 3. Validate locally
kt policy lint --file teams/payments/prod/policy-config.yaml
# 4. Commit and push
git add teams/payments/prod/policy-config.yaml
git commit -m "Increase payments team daily spend limit to $500"
git push origin policy/increase-payments-spend-limit
# 5. Open PR → reviewers approve → merge to main
# 6. Keeptrusts API detects the change → syncs → gateways reload
Branch Protection Rules
Configure branch protection to enforce governance:
# Repository settings (GitHub)
branches:
main:
protection:
required_reviews: 2
required_status_checks:
- "Validate AI Policies"
- "Policy Review Checks"
restrict_dismissals: true
require_code_owner_reviews: true
CI Validation on PRs
# .github/workflows/policy-pr.yml
name: Policy PR Validation
on:
pull_request:
paths:
- 'teams/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install kt CLI
run: |
curl -fsSL https://get.keeptrusts.dev/cli | sh
echo "$HOME/.keeptrusts/bin" >> $GITHUB_PATH
- name: Validate changed configs
run: |
changed=$(git diff --name-only origin/main -- 'teams/**/policy-config.yaml')
for config in ${changed}; do
echo "Validating ${config}..."
kt policy lint --file "${config}"
done
- name: Diff annotation
run: |
echo "### Policy Diff" >> $GITHUB_STEP_SUMMARY
echo '```diff' >> $GITHUB_STEP_SUMMARY
git diff origin/main -- 'teams/**/policy-config.yaml' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
Multi-Environment Sync
Environment-Per-Branch Strategy
Map branches to environments:
| Branch | Environment | Sync Target |
|---|---|---|
main | Production | Prod gateways |
staging | Staging | Staging gateways |
develop | Development | Dev gateways |
Link each environment to a different branch:
# Production sync — tracks main
curl -X POST "${API_URL}/v1/git-repos" \
-H "Authorization: Bearer ${API_TOKEN}" \
-d '{
"repo_url": "https://github.com/org/ai-policies.git",
"branch": "main",
"path": "teams/payments/policy-config.yaml",
"auto_create_configuration": true
}'
# Staging sync — tracks staging
curl -X POST "${API_URL}/v1/git-repos" \
-H "Authorization: Bearer ${API_TOKEN}" \
-d '{
"repo_url": "https://github.com/org/ai-policies.git",
"branch": "staging",
"path": "teams/payments/policy-config.yaml",
"auto_create_configuration": true
}'
Environment-Per-Directory Strategy
A single branch with directory-based environment separation (covered in the config-as-code guide):
teams/payments/dev/policy-config.yaml → linked to dev gateway
teams/payments/staging/policy-config.yaml → linked to staging gateway
teams/payments/prod/policy-config.yaml → linked to prod gateway
Rollback via Git Revert
Instant Rollback
If a policy change causes issues, revert the commit:
# Find the problematic commit
git log --oneline teams/payments/prod/policy-config.yaml
# Revert it
git revert abc1234 --no-edit
git push origin main
The API detects the revert commit, creates a new configuration version matching the previous state, and signals gateways to reload. Rollback is as fast as your poll interval.
Emergency Rollback via API
If Git is unavailable, override the configuration directly through the API:
# List configuration versions
curl -s "${API_URL}/v1/configurations/${CONFIG_ID}/versions" \
-H "Authorization: Bearer ${API_TOKEN}" | jq '.[0:5]'
# Revert to a previous version
curl -X POST "${API_URL}/v1/configurations/${CONFIG_ID}/versions/${PREV_VERSION_ID}/activate" \
-H "Authorization: Bearer ${API_TOKEN}"
This is an escape hatch. The Git repo will override the manual change on the next sync cycle, so also revert in Git to make the rollback permanent.
Monitoring Sync Status
API Status Endpoint
# Check sync status for all linked repos
curl -s "${API_URL}/v1/git-repos" \
-H "Authorization: Bearer ${API_TOKEN}" | \
jq '.[] | {repo_url, branch, last_sync, status, current_version}'
Console Sync Dashboard
The configuration workbench shows:
- Sync status:
synced,pending,error - Last sync: Timestamp of the last successful sync
- Current version: The active configuration version hash
- Error details: Git clone failures, parse errors, validation failures
Alerting on Sync Failures
Monitor the sync status endpoint and alert on errors:
# prometheus-rules.yaml
groups:
- name: keeptrusts-git-sync
rules:
- alert: GitSyncFailed
expr: keeptrusts_git_sync_status{status="error"} > 0
for: 5m
labels:
severity: warning
annotations:
summary: "Git sync failed for {{ $labels.repo_url }}"
description: "Keeptrusts git-linked repo sync has been failing for 5+ minutes"
GitOps for AI policy management gives you auditability (every change is a commit), reversibility (every rollback is a revert), and collaboration (every change is a PR). The platform does the rest.
For AI systems
- Canonical terms: git-linked repos, auto-sync, poll interval,
auto_create_configuration, configuration version, hot-reload,git revert, emergency rollback - API endpoints:
POST /v1/git-repos,GET /v1/git-repos,POST /v1/configurations/{id}/versions/{version_id}/activate - Console path: Configurations
- CLI commands:
kt policy lint --file <path> - Related pages: Config-as-Code, Secret Management, Multi-Tenant Gateway
For engineers
- Link a repo with
POST /v1/git-reposprovidingrepo_url,branch,path, andaccess_token(encrypted at rest via AES-GCM-SIV) - The API polls on
poll_interval_seconds(minimum 30s), diffs the file, creates a new config version on change, and signals gateways to reload - Map branches to environments (main → prod, staging → staging, develop → dev) or use directory-per-environment with a single branch
- Instant rollback:
git revert <commit>— the API detects the revert, creates a new version matching the previous state - Emergency override:
POST /v1/configurations/{id}/versions/{version_id}/activate— Git will re-override on next sync, so also revert in Git - Validate: confirm the approved YAML was imported, saved as a version, and deployed through Configurations; then verify the active version on the target gateways
For leaders
- GitOps provides auditability (every change is a Git commit), reversibility (every rollback is a revert), and collaboration (every change is a PR)
- Branch protection rules enforce governance team approval for production policy changes
- Sync failures are surfaced in the console and alertable via Prometheus metrics
- Rollback time equals your poll interval — typically 30–60 seconds from
git revertto gateway reload - Emergency override capability exists as an escape hatch when Git is unavailable
Next steps
- Structure your repo with Config-as-Code repository layout and CI validation
- Secure Git access tokens with Secret Management
- Propagate configs to fleet with Multi-Tenant Gateway hosted gateway mode