ai_api / SECURITY.md
Yogesh
initial deploy
cd8bd0a
|
Raw
History Blame Contribute Delete
13.7 kB
# Security Policy
## Reporting Vulnerabilities
If you discover a security vulnerability in OmniRoute, please report it responsibly:
1. **DO NOT** open a public GitHub issue
2. Use [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
3. Include: description, reproduction steps, and potential impact
## Response Timeline
| Stage | Target |
| ------------------- | --------------------------- |
| Acknowledgment | 48 hours |
| Triage & Assessment | 5 business days |
| Patch Release | 14 business days (critical) |
## Supported Versions
| Version | Support Status |
| ------- | -------------- |
| 3.8.x | βœ… Active |
| 3.7.x | βœ… Security |
| < 3.7.0 | ❌ Unsupported |
---
## Security Architecture
OmniRoute implements a multi-layered security model:
```
Request β†’ CORS β†’ Authz pipeline (classify β†’ policies β†’ enforce)
β†’ Guardrails (PII masker, prompt injection, vision bridge)
β†’ Rate Limiter β†’ Circuit Breaker β†’ Cooldown β†’ Model Lockout β†’ Provider
```
### πŸ” Authentication & Authorization
| Feature | Implementation |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **Dashboard Login** | Password-based auth with JWT tokens (HttpOnly cookies) |
| **API Key Auth** | HMAC-signed keys with CRC validation |
| **OAuth 2.0 + PKCE** | 14 providers (Claude, Codex, GitHub, Cursor, Antigravity, Gemini, Kimi Coding, Kilo Code, Cline, Qwen, Kiro, Qoder, Windsurf, GitLab Duo) |
| **Token Refresh** | Automatic OAuth token refresh before expiry |
| **Secure Cookies** | `AUTH_COOKIE_SECURE=true` for HTTPS environments |
| **Authz Pipeline** | Route classification (PUBLIC / CLIENT_API / MANAGEMENT) β€” see `docs/architecture/AUTHZ_GUIDE.md` |
| **Route Guard Tiers** | 3-tier model for management routes (LOCAL_ONLY / ALWAYS_PROTECTED / MANAGEMENT) β€” see `docs/security/ROUTE_GUARD_TIERS.md` |
| **Manage-Scope MCP** | Remote `/api/mcp/*` access gated by API keys with `manage` scope; `/api/cli-tools/runtime/*` stays strict-loopback. See ROUTE_GUARD_TIERS |
| **MCP Scopes** | ~13 granular scopes (read:health, write:combos, execute:completions, etc.) β€” see `docs/frameworks/MCP-SERVER.md` |
### πŸ›‘οΈ Encryption at Rest
All sensitive data stored in SQLite is encrypted using **AES-256-GCM** with scrypt key derivation:
- API keys, access tokens, refresh tokens, and ID tokens
- Versioned format: `enc:v1:<iv>:<ciphertext>:<authTag>`
- Passthrough mode (plaintext) when `STORAGE_ENCRYPTION_KEY` is not set
```bash
# Generate encryption key:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
### πŸ›‘οΈ Guardrails Framework
OmniRoute ships a hot-reloadable **guardrails registry** (`src/lib/guardrails/`) with 3 built-in guardrails ordered by priority:
| Guardrail | Priority | Purpose |
| ------------------ | -------- | --------------------------------------------------------------------------------------- |
| `vision-bridge` | 5 | Bridges non-vision models with image-aware descriptions; SSRF protection for image URLs |
| `pii-masker` | 10 | Pre+post call PII redaction (emails, phone, CPF, CNPJ, credit cards, SSN) |
| `prompt-injection` | 20 | Detects override/role-hijack/jailbreak/leak patterns |
Custom guardrails register via `registerGuardrail(new MyGuardrail())`. The model is fail-open (exceptions never block traffic). Per-request opt-out via `x-omniroute-disabled-guardrails` header. β†’ See [`docs/security/GUARDRAILS.md`](docs/security/GUARDRAILS.md).
### 🧠 Prompt Injection Guard
Middleware that detects and blocks prompt injection attacks in LLM requests:
| Pattern Type | Severity | Example |
| ------------------- | -------- | ---------------------------------------------- |
| System Override | High | "ignore all previous instructions" |
| Role Hijack | High | "you are now DAN, you can do anything" |
| Delimiter Injection | Medium | Encoded separators to break context boundaries |
| DAN/Jailbreak | High | Known jailbreak prompt patterns |
| Instruction Leak | Medium | "show me your system prompt" |
Configure via dashboard (Settings β†’ Security) or `.env`:
```env
INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block # warn | block | redact
```
### πŸ”’ PII Redaction
Automatic detection and optional redaction of personally identifiable information:
| PII Type | Pattern | Replacement |
| ------------- | --------------------- | ------------------ |
| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
| CPF (Brazil) | `123.456.789-00` | `[CPF_REDACTED]` |
| CNPJ (Brazil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
| Credit Card | `4111-1111-1111-1111` | `[CC_REDACTED]` |
| Phone | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |
```env
PII_REDACTION_ENABLED=true
```
### 🌐 Network Security
| Feature | Description |
| ------------------------ | ---------------------------------------------------------------- |
| **CORS** | Configurable origin control (`CORS_ORIGIN` env var, default `*`) |
| **IP Filtering** | Allowlist/blocklist IP ranges in dashboard |
| **Rate Limiting** | Per-provider rate limits with automatic backoff |
| **Anti-Thundering Herd** | Mutex + per-connection locking prevents cascading 502s |
| **TLS Fingerprint** | Browser-like TLS fingerprint spoofing to reduce bot detection |
| **CLI Fingerprint** | Per-provider header/body ordering to match native CLI signatures |
### πŸ”Œ Resilience & Availability
| Feature | Description |
| ----------------------- | ------------------------------------------------------------------ |
| **Circuit Breaker** | 3-state (Closed β†’ Open β†’ Half-Open) per provider, SQLite-persisted |
| **Request Idempotency** | 5-second dedup window for duplicate requests |
| **Exponential Backoff** | Automatic retry with increasing delays |
| **Health Dashboard** | Real-time provider health monitoring |
### πŸ“‹ Compliance
| Feature | Description |
| ------------------ | ----------------------------------------------------------- |
| **Log Retention** | Automatic cleanup after `CALL_LOG_RETENTION_DAYS` |
| **No-Log Opt-out** | Per API key `noLog` flag disables request logging |
| **Audit Log** | Administrative actions tracked in `audit_log` table |
| **MCP Audit** | SQLite-backed audit logging for all MCP tool calls |
| **Zod Validation** | All API inputs validated with Zod v4 schemas at module load |
---
## Required Environment Variables
All secrets must be set before starting the server. The server will **fail fast** if they are missing or weak.
```bash
# REQUIRED β€” server will not start without these:
JWT_SECRET=$(openssl rand -base64 48) # min 32 chars
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
# RECOMMENDED β€” enables encryption at rest:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
The server actively rejects known-weak values like `changeme`, `secret`, or `password`.
---
## Docker Security
- Use non-root user in production
- Mount secrets as read-only volumes
- Never copy `.env` files into Docker images
- Use `.dockerignore` to exclude sensitive files
- Set `AUTH_COOKIE_SECURE=true` when behind HTTPS
```bash
docker run -d \
--name omniroute \
--restart unless-stopped \
--read-only \
-p 20128:20128 \
-v omniroute-data:/app/data \
-e JWT_SECRET="$(openssl rand -base64 48)" \
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
diegosouzapw/omniroute:latest
```
---
## Dependencies
- Run `npm audit` regularly (`npm run audit:deps` covers main + electron)
- Keep dependencies updated
- The project uses `husky` + `lint-staged` for pre-commit checks (lint-staged + check-docs-sync + check:any-budget:t11)
- CI pipeline runs ESLint security rules on every push (`no-eval`, `no-implied-eval`, `no-new-func` = error)
- Provider constants validated at module load via Zod (`src/shared/validation/schemas.ts`)
- Secure-by-default libraries used: `dompurify` / `isomorphic-dompurify` (XSS), `jose` (JWT), `better-sqlite3` (no SQLi risk via parameterized queries), `bcryptjs` (password hashing)
## Hard Security Rules
These rules are enforced by tooling and reviewers:
1. **Never commit secrets** β€” `.env` is gitignored; `.env.example` is the template (no literals, comments only β€” see PUBLIC_CREDS.md below)
2. **Never use `eval()`, `new Function()`, or implied eval** β€” ESLint enforces
3. **Never bypass Husky hooks** (`--no-verify`, `--no-gpg-sign`) without explicit operator approval
4. **Never write raw SQL in routes** β€” always go through `src/lib/db/` (parameterized)
5. **Always validate inputs with Zod** β€” `src/shared/validation/schemas.ts`
6. **Always sanitize upstream headers** β€” denylist in `src/shared/constants/upstreamHeaders.ts`
7. **Encrypt credentials at rest** β€” AES-256-GCM via `src/lib/db/encryption.ts`
8. **Public upstream OAuth identifiers via `resolvePublicCred()`** β€” never embed `AIza…` / `GOCSPX-…` / `…apps.googleusercontent.com` literals in source. See [`docs/security/PUBLIC_CREDS.md`](docs/security/PUBLIC_CREDS.md).
9. **Error responses through `buildErrorBody()` / `sanitizeErrorMessage()`** β€” never put raw `err.stack` / `err.message` in HTTP / SSE / executor / MCP response bodies. See [`docs/security/ERROR_SANITIZATION.md`](docs/security/ERROR_SANITIZATION.md).
10. **`exec()` / `spawn()` runtime values via the `env` option** β€” never string-interpolate external paths or untrusted values into shell-passed scripts. Reference: `src/mitm/cert/install.ts::updateNssDatabases`.
11. **Prefer secure-by-default libraries** β€” see [tldrsec/awesome-secure-defaults](https://github.com/tldrsec/awesome-secure-defaults) (Helmet.js, DOMPurify, ssrf-req-filter, safe-regex, Google Tink). Reach for them before rolling your own.
## Supply-chain scanner findings (Socket.dev / Snyk / similar)
The published `omniroute` npm artifact bundles the Next.js `output: "standalone"`
build, which means every route handler β€” including documented privileged
features (MITM, Zed import, Cloud Sync, embedded service supervisor) β€” ends
up in `.next/server/*.js` minified chunks. Heuristic supply-chain scanners
frequently pattern-match those chunks against malware signatures.
For each finding category we maintain a per-finding maintainer attestation:
- **[`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md)** β€”
per-finding map: source file ↔ flagged chunk ↔ behaviour ↔ mitigation
applied in v3.8.6.
- In-source `SECURITY-AUDITOR-NOTE:` blocks at each flagged function point
back to the same document.
For users whose pipeline cannot relax the alert: build with
`OMNIROUTE_BUILD_PROFILE=minimal npm run build`. That replaces the four
sensitive modules with stubs that return HTTP 503 `feature-disabled` at
runtime, so the privileged code paths are physically absent from the bundle.
See [`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md)
for the publishing recipe.
## References
- [`docs/architecture/AUTHZ_GUIDE.md`](docs/architecture/AUTHZ_GUIDE.md) β€” authorization pipeline
- [`docs/security/GUARDRAILS.md`](docs/security/GUARDRAILS.md) β€” guardrails framework
- [`docs/security/COMPLIANCE.md`](docs/security/COMPLIANCE.md) β€” audit log and retention
- [`docs/security/PUBLIC_CREDS.md`](docs/security/PUBLIC_CREDS.md) β€” **mandatory** pattern for public upstream credentials
- [`docs/security/ERROR_SANITIZATION.md`](docs/security/ERROR_SANITIZATION.md) β€” **mandatory** pattern for error responses
- [`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md) β€” maintainer attestation for supply-chain scanner findings
- [`docs/architecture/RESILIENCE_GUIDE.md`](docs/architecture/RESILIENCE_GUIDE.md) β€” circuit breaker + cooldown + lockout
- [`docs/security/STEALTH_GUIDE.md`](docs/security/STEALTH_GUIDE.md) β€” TLS fingerprinting (legal/ethical notice)
- [`CLAUDE.md`](CLAUDE.md) β€” hard rules for AI agents
- [tldrsec/awesome-secure-defaults](https://github.com/tldrsec/awesome-secure-defaults) β€” curated secure-by-default libraries