Learn 9router - Compliance & Auditability
Episode 14 of 23

Learn 9router - Compliance & Auditability

This episode turns logs into evidence: auditing route decisions and model usage, recording policy evaluations and access history, and handling data residency and privacy compliance with organized encryption and retention.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

Episode 13 made the gateway tough: inputs guarded, content moderated, PII redacted, and providers protected. But you still can't prove any of that happened. When an auditor asks "whose request ever called the payment tool?", or a regulator demands "in which country is our users' model data processed?", answering "it should be safe" isn't enough.

Episode 14 turns the behavior you've built into an accountable trail. We'll enable audit logs for route decisions and model usage, record policy evaluations and access history, then discuss compliance considerations: data residency, privacy, encryption, and retention.

Audit Log as the Source of Truth

An audit log isn't just a regular log. Operational logs answer "what's happening now", while audit logs answer "who did what, when, through which route, and how the decision was made" with enough context for post-incident investigation. After writing the audit configuration, run 9router audit enable to activate it. 9router records important events in a structured way:

Enabling the audit log
audit:
  enabled: true
  destination: stdout
  events:
    - auth_event
    - route_decision
    - policy_evaluation
    - tool_invocation
    - guardrail_trigger
    - cache_hit
  redact:
    - authorization
    - api_key
    - prompt_content

Note the redact here: prompt content is intentionally not recorded unless truly needed, because data that is never stored can never leak. Every entry has a standard format so it can be consumed by a SIEM, parsed, and joined with other infra logs.

Example audit log entry
{
  "ts": "2026-08-03T09:15:22Z",
  "event": "route_decision",
  "request_id": "req_9f2c1a",
  "consumer": "mobile-app",
  "region": "ap-southeast",
  "route": "chat-general",
  "selected_model": "gpt-4o-mini",
  "provider": "openai-prod",
  "tokens_in": 412,
  "tokens_out": 96,
  "latency_ms": 743,
  "policy_version": "v42"
}

Auditing Route Decisions and Model Usage

Routing decisions must be explainable after the fact. Why did this request land on gpt-4o and not gpt-4o-mini? The answer is in the route_decision entry: the chosen route, model, provider, and the policy_version in effect at that time. Policy version matters because old decisions must be auditable with the same rules as when they happened.

Tracing route decisions per request
9router audit query --event route_decision --consumer mobile-app --since 24h
9router audit show --request-id req_9f2c1a

Model usage is summarized into aggregatable metrics for cost and capacity reports: total tokens per model, per provider, and per consumer. This data is also the basis for cost attribution — knowing which business unit spends the most of the AI budget.

Model usage summary
9router audit summary --by model --window 7d
9router audit export --format csv --window 30d

Recording Policy Evaluations and Guardrails

One of the audit log's greatest values: proving that policies were actually evaluated on every request. The policy_evaluation entry records which policy was active, its outcome (passed, rejected, redacted), and the reason. This matters for compliance audits and also for tuning — if many requests are blocked, you know a policy is too strict.

Example policy evaluation
{
  "event": "policy_evaluation",
  "request_id": "req_a71b9d",
  "policy": "content-safety",
  "guard": "pii-scrub",
  "entity": "credit_card",
  "action": "redact",
  "result": "allowed_with_redaction"
}

Likewise, guardrail_trigger records when prompt_injection or moderation-in blocked a request. A suspicious number of blocks — for example a sudden spike from one IP — is a signal that must be followed up, and thanks to the audit log, that signal has evidence.

Access History and Credential Trails

Audit also records who accessed what. auth_event records authentication successes and failures; tool_invocation records which tool was called, by which consumer, and with what arguments. Access to the gateway admin panel and configuration changes must also enter the log — who changed a rate limit, when, and from which version to which.

Restricting who can view the audit
audit:
  access_control:
    viewers: [security-team, compliance-team]
    immutable: true
    export_require_mfa: true

Setting immutable: true makes audit entries unable to be edited or deleted — the foundation of evidence integrity. Access to the logs is limited to specific teams, and data export requires MFA. This pattern follows the least-privilege principle from episode 11, applied to the evidence itself.

Warning

Beware retention rules: keeping logs forever can violate privacy regulations, while deleting too quickly destroys investigation capability. Set retention aligned with your policy, then automate rotation and deletion.

Data Residency and Privacy

The awareness that "logs live on one server" is no longer enough when data crosses borders. Data residency demands that data be processed in approved regions — for example European citizens' data must stay in Europe. 9router supports region pinning: forcing specific routes to only use providers located in allowed regions.

Enforcing processing in a specific region
residency:
  region: eu-central
  enforce: true
  providers_allowed: [azure-eu]
  deny_cross_border: true
  audit_events: true

With enforce: true, a request that configurationally lands on a provider outside the allowed region is rejected — not just recorded. Combine this with the ABAC rule from episode 12 (request.region != eu denied) so the residency policy applies consistently at the routing layer and the request layer.

Encrypting data at rest
storage:
  encryption: aes-256
  kms_key_ref: kms/9router-audit
  retention:
    audit_log: 90d
    request_meta: 30d
  pii_tokenization: true

Encryption at rest ensures log files and metadata remain unreadable even if the storage media is stolen. PII data that slips into metadata — if any — is tokenized so it's not in its original form. The combination of residency pinning, encryption, and automated retention is the outline of compliance you can present to the compliance team, while waiting for episode 20 to dashboard the metrics.

Conclusion

Episode 14 makes your gateway accountable: structured audit logs for route decisions and model usage, records of policy and guardrail evaluations proving protection is running, access history for credentials and tools, plus data residency, at-rest encryption, and retention policies aligned with privacy.

Key takeaways:

  • Audit logs differ from regular logs in context: who, when, which route, what policy version.
  • Record the policy version on every decision so past events can be audited with the same rules.
  • PII redaction in logs matters as much as redaction in prompts — unstored data can't leak.
  • Make audit logs immutable and limit access to authorized teams.
  • Apply region pinning, at-rest encryption, and automated retention for privacy compliance.

Now every decision has a trail. In episode 15 we make that trail fast and cheap: Performance Optimization — optimizing routing latency and throughput, balancing cost/latency when choosing models, and caching responses and reusing embeddings. See you there!

Learn 9router - Compliance & Auditability | Learn 9router