Execute conduct security and compliance review of OpenRouter integration. Use when preparing for audits or security assessments. Trigger with phrases like 'openrouter security review', 'openrouter compliance', 'openrouter audit', 'security assessment'.
OpenRouter is a proxy that routes requests to upstream providers (OpenAI, Anthropic, Google, etc.). Compliance depends on both OpenRouter's data handling and the selected provider's policies. Key considerations: data transit through OpenRouter infrastructure, provider-specific data retention, model selection for regulated data, and audit trail requirements.
Prerequisites
An OpenRouter API key (sk-or-v1-...) exported as OPENROUTER_API_KEY — see the openrouter-install-auth skill for setup
Python 3.8+ with the OpenAI SDK for provider-pinned requests and the automated checker in the references
curl and jq to run the Compliance Audit Script
An existing OpenRouter integration to review — the audit script scans its source tree for hardcoded sk-or-v1- keys
Knowledge of which regimes apply (SOC2, GDPR, HIPAA) and how your data is classified
Instructions
Work through the four areas of the Compliance Checklist — , , , and — recording pass/fail per item.
data_handling
access_control
audit_trail
provider_selection
Classify each workload with the Data Classification Matrix (Public → Internal → Confidential → Restricted/PHI) to determine allowed providers and required controls.
Pin regulated traffic per Provider Routing for Compliance: set provider.order plus allow_fallbacks: False, then verify response.model confirms the approved provider actually served the request.
For data-sovereignty requirements, configure BYOK per BYOK for Data Sovereignty so inference runs on your own provider account and OpenRouter only routes.
Run the Compliance Audit Script: key label/limit check via GET /api/v1/auth/key, a free-tier warning (free tier is unsuitable for regulated data), and the hardcoded-key scan.
Document the data flow for auditors — client → OpenRouter (routing) → provider (inference) — per Enterprise Considerations.
Compliance Checklist
COMPLIANCE_CHECKLIST = {
"data_handling": [
"Verify OpenRouter does NOT train on your data (confirmed in their privacy policy)",
"Confirm provider-level data policies (OpenAI, Anthropic, Google each differ)",
"Document data flow: your app -> OpenRouter -> provider -> OpenRouter -> your app",
"Identify if prompts contain PII, PHI, or regulated data",
"Implement PII redaction before sending to API",
],
"access_control": [
"Use per-service API keys (not shared keys)",
"Set credit limits per key to isolate blast radius",
"Rotate keys on a 90-day schedule",
"Store keys in secrets manager (not .env files in repos)",
"Enable management keys for programmatic key provisioning",
],
"audit_trail": [
"Log every API call with generation_id, model, user_id, cost",
"Hash prompts (SHA-256) instead of logging raw content",
"Retain audit logs per regulation (90d operational, 7yr financial)",
"Ship logs to append-only storage (S3, immutable DB)",
],
"provider_selection": [
"Route regulated data only to compliant providers",
"Use provider routing to exclude non-compliant providers",
"Document which models are approved for which data classifications",
"Test that fallback routing doesn't route to unapproved providers",
],
}
Provider Routing for Compliance
import os
from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
default_headers={"HTTP-Referer": "https://my-app.com", "X-Title": "my-app"},
)
# Route ONLY to specific providers (e.g., Anthropic for SOC2)
response = client.chat.completions.create(
model="anthropic/claude-3.5-sonnet",
messages=[{"role": "user", "content": "Analyze this contract..."}],
max_tokens=2048,
extra_body={
"provider": {
"order": ["Anthropic"], # Only Anthropic's infrastructure
"allow_fallbacks": False, # Do NOT fall back to other providers
},
},
)
# Verify which provider actually served the request
print(f"Served by: {response.model}") # Should match anthropic/claude-3.5-sonnet
Data Classification Matrix
Classification
Allowed Providers
Controls
Public
Any (including :free)
Standard logging
Internal
Tier 1 (OpenAI, Anthropic, Google)
Audit logging, key limits
Confidential
Anthropic, OpenAI (API-only)
PII redaction, no free models
Restricted/PHI
BYOK only or self-hosted
Full audit, encryption at rest
BYOK for Data Sovereignty
# Bring Your Own Key -- requests go directly to provider
# OpenRouter acts as router only; data doesn't persist on OpenRouter
response = client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Process this..."}],
max_tokens=1024,
extra_body={
"provider": {
"order": ["OpenAI"],
"allow_fallbacks": False,
},
},
# With BYOK, configure your provider key in OpenRouter dashboard
# Data flows: your app -> OpenRouter (routing only) -> OpenAI (your account)
)
A pass/fail/warn compliance report from the automated checker in the references, one line per control (API key storage, HTTPS enforcement, max_tokens, error handling, audit logging)
Key-configuration JSON (label, limit, is_free_tier) plus a free-tier warning and a count of hardcoded keys found in source, from the Compliance Audit Script
A provider-pinned client configuration (provider.order + allow_fallbacks: False) that cannot route regulated data to unapproved providers
A filled-in markdown compliance checklist (template in the references) covering security, data privacy, reliability, observability, and cost controls
Examples
Running run_compliance_review() from the references against a healthy integration: