Policy as code is the practice of defining AI safety policies in machine-readable files (YAML) that are stored in version control, reviewed through pull requests, tested in CI, and deployed through automation. It brings software engineering practices to governance.
Traditional governance relies on documents: PDFs, Word files, wiki pages. These documents describe what should happen but do not enforce it. There is a gap between the written policy and the running system.
Policy as code closes that gap. The YAML file that describes the policy is the same file that the policy engine evaluates. There is no translation step, no interpretation, no drift between documentation and enforcement.
1. Engineer writes policy.yaml
2. Opens pull request
3. CI runs policy linter (syntax, conflicts, unreachable rules)
4. CI runs policy tests (known inputs → expected decisions)
5. Security team reviews and approves
6. Merge to main → deploys to shadow mode
7. Shadow mode comparison for 48 hours
8. Promote to active if results are acceptable
Store policies in git:
policies/
production.yaml
staging.yaml
development.yaml
overrides/
team-finance.yaml
team-engineering.yaml
Every change is tracked. You can see who changed what, when, and why. You can revert to any previous version instantly.
Policy changes go through pull requests:
PR #42: Tighten email sending rules
- Changed email.send from 'allow' to 'escalate' for external recipients
- Added rate limit of 5 emails per hour
Reviewers: @security-team, @compliance-officer
Two sets of eyes on every policy change reduces the risk of mistakes.
Write tests for your policies:
describe('production policy', () => {
test('blocks destructive shell commands', () => {
const decision = evaluate(policy, 'shell.execute', { command: 'rm -rf /' });
expect(decision.action).toBe('block');
});
test('allows read-only database queries', () => {
const decision = evaluate(policy, 'database.query', { query: 'SELECT * FROM users' });
expect(decision.action).toBe('allow');
});
test('escalates payments over threshold', () => {
const decision = evaluate(policy, 'payment.send', { amount: 500 });
expect(decision.action).toBe('escalate');
});
});
Run these tests in CI on every pull request. No policy change merges without passing tests.
Auditors love policy as code:
Authensor's control plane can load policies from a git repository or through its API. Automate deployments with your existing CI/CD pipeline:
# Deploy policy after PR merge
npx authensor policy deploy ./policies/production.yaml \
--endpoint https://control-plane.internal \
--api-key ${AUTHENSOR_API_KEY}
Explore more guides on AI agent safety, prompt injection, and building secure systems.
View All Guides