Policy as Code
Defining, Version-Controlling & Enforcing AI Policies Programmatically
What is Policy as Code?
Policy as Code (PaC) is the practice of defining organizational policies, rules, and constraints in machine-readable code rather than natural language documents. For LLM applications, this means encoding content policies, usage limits, access rules, and safety guidelines into version-controlled, testable, and automatically enforceable configurations.
"When policies are code, they become testable, versionable, and reviewable just like application code. This transforms compliance from a manual checklist into an automated, continuous process."
Versioned
Git-controlled changes
Testable
Automated validation
Enforced
Auto-enforcement
Auditable
Complete history
Policy Types for LLM Applications
| Policy Type | Description | Example Rules |
|---|---|---|
| Content Policies | What content can/cannot be generated | Block hate speech, restrict NSFW |
| Usage Policies | Rate limits, quotas, token budgets | Max 10K tokens/day per user |
| Access Policies | Who can access what features/data | Only admins can use GPT-4-turbo |
| Data Policies | PII handling, data retention rules | Redact SSN, retain logs 90 days |
| Tool Policies | Which tools agents can call | Analysts can't call delete APIs |
| Topic Policies | Allowed/blocked conversation topics | Redirect legal questions to disclaimer |
Policy Definition (YAML)
# llm-policies.yaml
version: "1.0"
name: "customer-support-bot"
content_policies:
blocked_topics:
- "competitors"
- "legal_advice"
- "medical_advice"
- "financial_advice"
content_filters:
toxicity:
enabled: true
threshold: 0.7
action: "block"
pii:
enabled: true
entities: ["SSN", "CREDIT_CARD", "PHONE"]
action: "redact"
usage_policies:
rate_limits:
requests_per_minute: 60
tokens_per_day: 100000
model_access:
free_tier: ["gpt-3.5-turbo"]
pro_tier: ["gpt-3.5-turbo", "gpt-4"]
enterprise: ["gpt-3.5-turbo", "gpt-4", "gpt-4-turbo"]
tool_policies:
allowed_by_role:
viewer: ["search_docs", "get_product_info"]
agent: ["search_docs", "get_product_info", "create_ticket"]
admin: ["*"] # All tools
response_policies:
max_response_tokens: 1000
require_citations: true
disclaimer: "I'm an AI assistant. For critical issues, contact support."
Policy Engine Implementation
# Policy Engine for LLM applications
import yaml
from dataclasses import dataclass
from typing import List, Dict, Optional
@dataclass
class PolicyResult:
allowed: bool
reason: Optional[str] = None
modified_content: Optional[str] = None
class PolicyEngine:
def __init__(self, policy_path: str):
with open(policy_path) as f:
self.policies = yaml.safe_load(f)
def check_content_policy(self, content: str, user_context: dict) -> PolicyResult:
"""Check if content violates any content policies"""
# Check blocked topics
for topic in self.policies["content_policies"]["blocked_topics"]:
if self._matches_topic(content, topic):
return PolicyResult(
allowed=False,
reason=f"Topic '{topic}' is not allowed"
)
# Check content filters
filters = self.policies["content_policies"]["content_filters"]
if filters["toxicity"]["enabled"]:
score = self._check_toxicity(content)
if score > filters["toxicity"]["threshold"]:
return PolicyResult(allowed=False, reason="Toxic content detected")
if filters["pii"]["enabled"]:
clean_content = self._redact_pii(content, filters["pii"]["entities"])
return PolicyResult(allowed=True, modified_content=clean_content)
return PolicyResult(allowed=True)
def check_tool_access(self, tool_name: str, user_role: str) -> PolicyResult:
"""Check if user role can access a tool"""
allowed_tools = self.policies["tool_policies"]["allowed_by_role"].get(user_role, [])
if "*" in allowed_tools or tool_name in allowed_tools:
return PolicyResult(allowed=True)
return PolicyResult(
allowed=False,
reason=f"Role '{user_role}' cannot access tool '{tool_name}'"
)
NVIDIA NeMo Guardrails
# config.yml - NeMo Guardrails configuration
models:
- type: main
engine: openai
model: gpt-4
rails:
input:
flows:
- self check input
- check jailbreak
output:
flows:
- self check output
- check facts
# rails.co - Colang policy definitions
define user ask about competitors
"What do you think about [competitor]?"
"How do you compare to [competitor]?"
"Is [competitor] better?"
define bot refuse competitor discussion
"I'm focused on helping with our products. I can't discuss competitors."
define flow handle competitor questions
user ask about competitors
bot refuse competitor discussion
Policy Lifecycle
Policy as Code Tools
NeMo Guardrails
NVIDIA's toolkit for adding programmable guardrails to LLM apps using Colang policy language.
View on GitHub →Open Policy Agent (OPA)
General-purpose policy engine using Rego language. Great for access control policies.
View OPA →Guardrails AI
Python framework for building AI guardrails with RAIL specs for validation.
View Guardrails AI →Best Practices
Do This
- Store policies in version control (Git)
- Write tests for policy rules
- Require PR reviews for policy changes
- Use declarative formats (YAML, JSON)
- Monitor policy enforcement metrics
- Separate policy from application code
Avoid This
- Hardcoding policies in application code
- Deploying without testing policies
- Inconsistent policy formats across teams
- Skipping policy reviews for "small" changes
- Ignoring policy enforcement failures
- Missing audit trail for policy changes