Security overview
Security objectives S1–S6, threat model summary, and Phase 1 validated invariants.
IBEX Harness sits on a high-value data path — LLM traffic, persistent memory, org-scoped tokens, and billing events. Security is an invariant, not a phase. This page summarizes what must always be true and what we defend against in Phase 1 (auth + proxy).
Security objectives
These six objectives (S1–S6) are non-negotiable across every release.
S1 — Tenant isolation
Org A must never access Org B data via API, database, cache, logs, analytics, or exports. Cross-tenant resource access returns 403 (PERMISSION_DENIED), never 404.
S2 — Confidentiality of secrets
Tokens, API keys, passwords, and signing keys must never appear in git history, logs, crash dumps, analytics payloads, or client-side bundles.
S3 — Integrity of billing and audit records
Billing events and audit logs are append-only, tamper-resistant, and recorded at least once — never silently dropped.
S4 — Least privilege authorization
Authentication is not authorization. Every operation checks token validity, permission bitmap, org ownership, and explicit roles for sensitive actions.
S5 — Safe prompt and memory handling
Memory content is untrusted input. Write-time quarantine, retrieval-time delimiters, and directive rules prevent prompt injection from stored content.
S6 — Secure failure modes
Auth and tenant isolation fail closed. Memory and context injection fail gracefully (degraded quality, still safe). Missing checks never accidentally allow operations.
Threat model summary
| Category | Examples | Primary controls (Phase 1) |
|---|---|---|
| External | Token theft, brute force, cost amplification | PAT hashing (Argon2id), org RPM limits, input size caps |
| Internal | Broad service tokens, missing org filters | RLS + application-layer org checks, bounded permission bitmap |
| AI-specific | Injection stored in memory, role confusion | Quarantine thresholds (Phase 2+), nonce-wrapped retrieval |
Fail closed vs fail open
| Scenario | Behavior |
|---|---|
| org_id context not set | Fail closed — deny access |
| Token validation incomplete (no safe cache) | Fail closed — 503 AUTH_UNAVAILABLE |
| Permission check ambiguous | Fail closed — 403 |
| Redis unavailable (rate limit) | Fail open — allow request, log warning (ADR-0015) |
| Memory retrieval timeout | Fail open — directive-only context |
Phase 1 validated invariants
The following behaviors are enforced by automated security tests in CI:
| Invariant | Expected behavior |
|---|---|
| Missing or invalid token | Rejected before handler (401) |
| Cross-org agent header | 403, not 404 |
| Revoked token | Rejected promptly |
| Auth service down | 503 with stable JSON envelope |
| Rate limits | Per-org RPM with correct headers |
| Permission bitmap | Enforced on protected routes |
Related pages
- Authentication — token types and fail-closed pipeline
- Tenant isolation — RLS and Redis namespacing
- Secrets and keys — rotation and env var contract
- Auth service — gRPC validation surface
Was this page helpful?
Last updated on