GenAIHub
← Back to Technical Section

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."

— Policy as Code Principles

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

See: NVIDIA NeMo Guardrails

Policy Lifecycle

Define
Test
Review
Deploy
Monitor

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 →

LLM Guard

Security toolkit for LLMs with scanners for input/output validation.

View LLM Guard →

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

Related Topics