AI Governance & Compliance in Production
Shipping an AI feature is the easy part. Keeping it compliant, auditable, and safe in production is where most teams struggle. This guide walks through building a complete governance stack — policy engines, PII redaction, tamper-proof audit trails, RBAC, cost controls, content guardrails, approval gates, and AI firewalls — all with ElsiumAI’s TypeScript primitives.
Why Governance Matters
Regulated industries — finance, healthcare, legal, government — don’t get to treat LLMs as black boxes. Auditors want to know who accessed which model, what data was sent, what the model returned, and whether any policies were violated. Without governance, you’re flying blind.
The cost of getting it wrong is severe:
- Data leakage — PII or proprietary data sent to a third-party model becomes a breach notification event
- Runaway costs — a single agentic loop without budget limits can burn through thousands of dollars in minutes
- Compliance violations — SOC 2 requires access controls and audit logs; HIPAA demands PHI safeguards; GDPR requires data minimization
- Prompt injection — without input filtering, attackers can hijack your agents to exfiltrate data or perform unauthorized actions
- Reputational damage — a model generating harmful, biased, or off-brand content in a customer-facing application
ElsiumAI treats governance as a first-class concern — not a bolted-on afterthought. Every primitive composable, every policy declarative, every audit entry immutable.
Policy Engine
Policies are the foundation of your governance stack. A policy is a pure function that receives a request context and returns allow, deny, or flag. You compose them into policy sets that evaluate in order.
import {
createPolicySet,
contentPolicy,
costLimitPolicy,
tokenLimitPolicy,
modelAccessPolicy,
} from '@elsium-ai/core'
const policies = createPolicySet({
name: 'production-governance',
policies: [
// Block requests that exceed 100K tokens
tokenLimitPolicy({ maxTokens: 100_000 }),
// Enforce per-request cost ceiling
costLimitPolicy({ maxCostPerRequest: 0.50 }),
// Restrict which models each role can access
modelAccessPolicy({
rules: [
{ role: 'intern', allow: ['gpt-4o-mini', 'claude-haiku'] },
{ role: 'engineer', allow: ['gpt-4o', 'claude-sonnet-4-6', 'gemini-pro'] },
{ role: 'admin', allow: ['*'] },
],
}),
// Block harmful content categories
contentPolicy({
blocked: ['violence', 'self-harm', 'illegal-activity'],
action: 'deny',
}),
],
onViolation: (violation) => {
console.error(`Policy violated: ${violation.policy} — ${violation.reason}`)
},
})
Policy sets are composable. You can merge multiple sets for different environments:
import { mergePolicySets } from '@elsium-ai/core'
const production = mergePolicySets(
basePolicies,
compliancePolicies,
costPolicies,
)
Every policy evaluation is synchronous and adds less than 10μs of overhead per request. Policies never call external services — they operate purely on the request context already in memory.
PII Redaction
Sending personally identifiable information to a third-party LLM is a compliance risk. ElsiumAI provides middleware that strips PII from requests before they leave your infrastructure — and scrubs it from responses before they reach your users.
import { redactSecrets, checkBlockedPatterns } from '@elsium-ai/agents'
// Define patterns to detect and redact
const piiRedactor = redactSecrets({
patterns: [
{ name: 'ssn', regex: /\b\d{3}-\d{2}-\d{4}\b/g, replacement: '[SSN_REDACTED]' },
{ name: 'email', regex: /\b[\w.-]+@[\w.-]+\.\w{2,}\b/g, replacement: '[EMAIL_REDACTED]' },
{ name: 'phone', regex: /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g, replacement: '[PHONE_REDACTED]' },
{ name: 'credit-card', regex: /\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/g, replacement: '[CC_REDACTED]' },
],
onRedaction: (match) => {
audit.log({ event: 'pii_redacted', pattern: match.name, timestamp: Date.now() })
},
})
// Check for blocked content patterns (e.g., internal URLs, API keys)
const blockedPatterns = checkBlockedPatterns({
patterns: [
{ name: 'internal-url', regex: /https?:\/\/internal\.corp\.com[\S]*/g },
{ name: 'aws-key', regex: /AKIA[0-9A-Z]{16}/g },
{ name: 'bearer-token', regex: /Bearer\s+[A-Za-z0-9\-._~+\/]+=*/g },
],
action: 'deny', // reject the entire request
})
Wire these into your gateway as middleware so every request and response passes through the redaction layer:
import { gateway } from '@elsium-ai/gateway'
const gw = gateway({
mesh,
middleware: [
piiRedactor.requestMiddleware(), // Scrub PII from outgoing prompts
piiRedactor.responseMiddleware(), // Scrub PII from model responses
blockedPatterns.middleware(), // Block requests with forbidden patterns
// ... other middleware
],
})
Redaction is deterministic and runs in-process. No data leaves your infrastructure before it passes through the redactor. Every redaction event is logged for audit purposes.
Audit Trails
An audit trail records every significant action in your AI system — who did what, when, and what the outcome was. ElsiumAI’s audit trail uses a hash chain for tamper detection: each entry includes a SHA-256 hash of the previous entry, forming an immutable linked chain.
import { createAuditTrail } from '@elsium-ai/observe'
const audit = createAuditTrail({
hashChain: true, // Each entry references the previous hash
storage: 'persistent', // Write to disk / database
retention: { days: 2555 }, // 7-year retention for SOC 2
encryption: {
algorithm: 'aes-256-gcm',
keyId: 'audit-key-prod-01',
},
})
Every LLM interaction is recorded automatically:
// Entries are created automatically by gateway middleware,
// but you can also create them manually:
await audit.record({
actor: { id: 'user-1234', role: 'engineer' },
action: 'llm.chat.completion',
resource: { model: 'claude-sonnet-4-6', provider: 'anthropic' },
input: { tokenCount: 1520, redacted: true },
output: { tokenCount: 890, latencyMs: 340 },
policies: { evaluated: 4, passed: 4, violated: 0 },
cost: { amount: 0.0124, currency: 'USD' },
})
The hash chain makes tampering detectable. If any entry is modified or deleted, the chain breaks:
const verification = await audit.verifyChain()
if (!verification.valid) {
console.error(`Tamper detected at entry ${verification.brokenAt}`)
console.error(`Expected hash: ${verification.expectedHash}`)
console.error(`Actual hash: ${verification.actualHash}`)
}
For compliance audits, you can export the trail in structured formats:
const report = await audit.export({
format: 'json', // also: 'csv', 'parquet'
from: new Date('2026-01-01'),
to: new Date('2026-03-06'),
filter: { action: 'llm.*' },
})
RBAC for AI
Traditional RBAC controls who can access which endpoints. AI RBAC goes further — it controls which models a user can invoke, which tools an agent can call, and what cost tier each role operates under.
import { createRBAC } from '@elsium-ai/app'
const rbac = createRBAC({
roles: {
intern: {
description: 'Limited access to small models only',
permissions: [
'model:use:gpt-4o-mini',
'model:use:claude-haiku',
'tool:use:search',
'budget:tier:free',
],
rateLimit: { rpm: 20 },
},
engineer: {
description: 'Standard access to production models',
permissions: [
'model:use:gpt-4o',
'model:use:claude-sonnet-4-6',
'model:use:gemini-pro',
'tool:use:*',
'budget:tier:standard',
'agent:create',
'agent:execute',
],
rateLimit: { rpm: 200 },
},
admin: {
description: 'Full access with governance controls',
permissions: [
'model:use:*',
'tool:use:*',
'budget:tier:unlimited',
'agent:*',
'audit:read',
'audit:export',
'policy:manage',
'rbac:manage',
],
rateLimit: { rpm: 1000 },
},
},
})
Integrate RBAC into your gateway so every request is authorized:
import { createApp } from '@elsium-ai/app'
const app = createApp({
gateway: gw,
rbac,
auth: {
strategy: 'jwt',
jwksUri: 'https://auth.example.com/.well-known/jwks.json',
rolesClaim: 'elsium_roles',
},
port: 3000,
})
app.listen()
When a request comes in, the RBAC middleware extracts the user’s role from their JWT, checks permissions against the requested model and tools, and rejects unauthorized requests with a 403 before they touch the provider mesh.
Cost Controls
Without cost controls, a single runaway agent can burn through your entire monthly budget in hours. ElsiumAI’s cost engine tracks spending in real time and enforces hard limits at multiple levels.
import { createCostEngine, costLimitPolicy } from '@elsium-ai/gateway'
const cost = createCostEngine({
pricing: 'auto', // Fetches latest pricing from provider APIs
budgets: [
{
scope: 'global',
limit: { monthly: 10_000, daily: 500 },
alerts: [
{ threshold: 0.75, action: 'notify', channel: 'slack' },
{ threshold: 0.90, action: 'notify', channel: 'pagerduty' },
{ threshold: 1.00, action: 'deny' }, // Hard cutoff
],
},
{
scope: 'role',
limits: {
intern: { daily: 5 },
engineer: { daily: 50 },
admin: { daily: 500 },
},
},
{
scope: 'tenant',
defaultLimit: { monthly: 1_000 },
overrides: {
'tenant-enterprise-01': { monthly: 5_000 },
},
},
],
})
// Wire into the gateway
const gw = gateway({
mesh,
middleware: [
cost.middleware(),
costLimitPolicy({ maxCostPerRequest: 1.00 }),
// ... other middleware
],
})
The cost engine emits events you can subscribe to for real-time monitoring:
cost.on('threshold', (event) => {
console.warn(`Budget alert: ${event.scope} at ${event.percentUsed}%`)
console.warn(`Spent: $${event.spent} / $${event.limit}`)
})
cost.on('denied', (event) => {
console.error(`Request denied: ${event.scope} budget exhausted`)
audit.record({
actor: event.actor,
action: 'cost.budget.exceeded',
resource: { scope: event.scope, spent: event.spent, limit: event.limit },
})
})
Content Guardrails
Content guardrails filter both input prompts and model outputs to ensure they comply with your content policies. This prevents users from sending harmful prompts and prevents models from generating prohibited content.
import { contentPolicy } from '@elsium-ai/core'
import { outputGuardrailMiddleware } from '@elsium-ai/gateway'
// Input filtering — blocks prompts with prohibited content
const inputPolicy = contentPolicy({
blocked: ['violence', 'self-harm', 'illegal-activity', 'sexual-content'],
flagged: ['political', 'medical-advice', 'legal-advice'],
action: 'deny', // 'deny' rejects; 'flag' allows but logs
onFlag: (result) => {
audit.record({
action: 'content.flagged',
resource: { categories: result.flaggedCategories },
})
},
})
// Output filtering — catches harmful model responses
const outputGuardrail = outputGuardrailMiddleware({
policies: [inputPolicy],
fallback: {
content: 'I cannot provide a response to this request due to content policy restrictions.',
},
onBlock: (result) => {
audit.record({
action: 'content.output.blocked',
resource: { model: result.model, categories: result.blockedCategories },
})
},
})
Add both layers to the gateway middleware stack:
const gw = gateway({
mesh,
middleware: [
inputPolicy.middleware(), // Filter inputs before the LLM sees them
outputGuardrail, // Filter outputs before the user sees them
// ... other middleware
],
})
Content policies are evaluated locally using pattern matching and classification rules — they don’t send data to external moderation APIs unless you explicitly configure a remote classifier.
Approval Gates
Some actions are too risky for full automation. Approval gates pause execution and require human sign-off before proceeding. This is critical for agentic workflows that can take irreversible actions — deleting data, sending emails, executing financial transactions.
import { createApprovalGate } from '@elsium-ai/agents'
const approvalGate = createApprovalGate({
rules: [
{
// Any action costing more than $5 requires approval
condition: (ctx) => ctx.estimatedCost > 5.00,
approvers: ['admin'],
timeout: { minutes: 30 },
onTimeout: 'deny',
},
{
// Destructive tool calls always require approval
condition: (ctx) => ctx.tool?.category === 'destructive',
approvers: ['admin', 'security-team'],
timeout: { hours: 4 },
onTimeout: 'deny',
},
{
// External API calls with write access
condition: (ctx) => ctx.tool?.permissions?.includes('write') && ctx.tool?.external,
approvers: ['engineer', 'admin'],
timeout: { minutes: 15 },
onTimeout: 'deny',
},
],
notifier: {
channel: 'slack',
webhook: process.env.SLACK_APPROVAL_WEBHOOK,
},
})
Integrate the gate into an agent’s tool execution pipeline:
import { createAgent } from '@elsium-ai/agents'
const agent = createAgent({
model: 'claude-sonnet-4-6',
tools: [deleteRecordTool, sendEmailTool, queryDatabaseTool],
middleware: [approvalGate.middleware()],
onApprovalRequired: async (request) => {
console.log(`Waiting for approval: ${request.tool} — ${request.reason}`)
const decision = await request.waitForDecision()
return decision // 'approved' | 'denied'
},
})
The agent pauses execution at the gate, sends a notification to the configured channel, and resumes only when an authorized approver responds. All approval decisions are recorded in the audit trail.
AI Firewall
Prompt injection and jailbreak attacks are the biggest security threat to production AI systems. ElsiumAI’s agent security module provides a layered defense that inspects every input before it reaches the model.
import {
createAgentSecurity,
detectPromptInjection,
detectJailbreak,
} from '@elsium-ai/agents'
const firewall = createAgentSecurity({
layers: [
// Heuristic detection — fast pattern matching
detectPromptInjection({
mode: 'strict', // 'strict' | 'balanced' | 'permissive'
patterns: [
'ignore previous instructions',
'disregard all prior',
'you are now',
'system prompt override',
'act as if you have no restrictions',
],
action: 'deny',
}),
// Jailbreak detection — structural analysis
detectJailbreak({
techniques: [
'role-playing', // "Pretend you are DAN..."
'encoding', // Base64 / ROT13 encoded payloads
'context-switching', // Mid-conversation persona changes
'instruction-hierarchy',// Attempts to override system prompt
],
sensitivity: 0.8, // 0.0 – 1.0 threshold
action: 'deny',
}),
],
onThreat: (threat) => {
audit.record({
action: 'security.threat.detected',
resource: {
type: threat.type,
confidence: threat.confidence,
input: threat.redactedInput,
},
})
},
})
Mount the firewall as the first middleware in your gateway — before any other processing:
const gw = gateway({
mesh,
middleware: [
firewall.middleware(), // First line of defense
rbac.middleware(), // Then check authorization
piiRedactor.requestMiddleware(),
inputPolicy.middleware(),
cost.middleware(),
outputGuardrail,
piiRedactor.responseMiddleware(),
],
})
The firewall operates in sub-millisecond time for heuristic checks. It never sends data to external services — all detection runs in-process. For high-confidence threats, it returns a 403 immediately without forwarding the request to any provider.
Compliance Patterns
Different regulatory frameworks map to different ElsiumAI features. The table below shows how to achieve compliance across SOC 2, HIPAA, and GDPR using the primitives covered in this guide.
| Requirement | SOC 2 | HIPAA | GDPR | ElsiumAI Feature |
|---|---|---|---|---|
| Access control | CC6.1 | § 164.312(a) | Art. 25 | createRBAC with role-based model & tool permissions |
| Audit logging | CC7.2 | § 164.312(b) | Art. 30 | createAuditTrail with hash chain and 7-year retention |
| Data minimization | CC6.5 | § 164.502(b) | Art. 5(1)(c) | redactSecrets and checkBlockedPatterns middleware |
| Encryption at rest | CC6.7 | § 164.312(a)(2)(iv) | Art. 32 | Audit trail with encryption: { algorithm: 'aes-256-gcm' } |
| Incident detection | CC7.3 | § 164.308(a)(6) | Art. 33 | createAgentSecurity threat detection with alerting |
| Change management | CC8.1 | § 164.308(a)(5) | — | createPolicySet with versioned, declarative policies |
| Cost accountability | CC6.3 | — | — | createCostEngine with per-role and per-tenant budgets |
| Content safety | CC7.1 | — | Art. 22 | contentPolicy and outputGuardrailMiddleware |
| Human oversight | — | — | Art. 22 | createApprovalGate for high-risk automated decisions |
| Tamper detection | CC7.2 | § 164.312(c) | Art. 5(1)(f) | audit.verifyChain() for hash-chain integrity checks |
The key insight is that compliance isn’t a single feature — it’s the composition of many features working together. ElsiumAI’s primitives are designed to compose: the same audit instance records PII redactions, policy violations, cost overages, security threats, and approval decisions. The same rbac instance controls model access, tool permissions, and budget tiers.
Putting It All Together
Here’s the full governance stack wired into a single gateway:
import { createApp } from '@elsium-ai/app'
import { gateway, createProviderMesh, createCostEngine } from '@elsium-ai/gateway'
import { createAuditTrail } from '@elsium-ai/observe'
import { createPolicySet, contentPolicy, costLimitPolicy } from '@elsium-ai/core'
import { createAgentSecurity, redactSecrets } from '@elsium-ai/agents'
// 1. Infrastructure
const mesh = createProviderMesh({ providers: [/* ... */] })
const audit = createAuditTrail({ hashChain: true, retention: { days: 2555 } })
const cost = createCostEngine({ pricing: 'auto', budgets: [/* ... */] })
const firewall = createAgentSecurity({ layers: [/* ... */] })
const pii = redactSecrets({ patterns: [/* ... */] })
const policies = createPolicySet({ policies: [/* ... */] })
// 2. Gateway with full governance middleware stack
const gw = gateway({
mesh,
middleware: [
firewall.middleware(),
rbac.middleware(),
pii.requestMiddleware(),
policies.middleware(),
cost.middleware(),
outputGuardrail,
pii.responseMiddleware(),
],
})
// 3. Serve
const app = createApp({ gateway: gw, rbac, audit, port: 3000 })
app.listen()
Every request passes through the full governance pipeline: security screening, authorization, PII scrubbing, policy evaluation, cost tracking, output filtering, and audit logging. Total overhead for the entire stack stays under 10μs at P95 — governance doesn’t have to mean slow.
Check out the Fundamentals guide for a deep dive into each primitive, or explore the API references for @elsium-ai/core, @elsium-ai/agents, @elsium-ai/observe, and @elsium-ai/app.
Eric Utrera
Creator of ElsiumAI. Building production AI infrastructure.