Security
Last updated: April 23, 2026
Iris stores a lot of signal about your agents — inputs, outputs, tool calls, eval results. This page explains the concrete controls in place, the threat model we design against, and how to verify each claim for yourself.
Data location
Self-hosted (OSS): every trace, span, eval result, and audit entry is written to a SQLite database on your machine (default: ~/.iris/iris.db). No data ever leaves your environment. Iris does not phone home. There is no telemetry.
Cloud tier (v0.4+): data is stored in a per-tenant logical partition in our managed backend, which runs on hardened US-region infrastructure. Encryption at rest (AES-256) + encryption in transit (TLS 1.3) are table stakes. Cross-tenant isolation is enforced at four independent layers — see the architecture guide for the technical detail.
Tenant isolation
Every row in every data table carries a tenant_id column. Reads, writes, updates, and deletes require a tenant context parameter — there is no “get all traces” query path in the codebase. The four-layer defense:
- Type system.
TenantIdis a branded TypeScript type. Forgetting to pass tenant context is a compile error. - Runtime guard. Every storage method calls
assertTenant()which throws if the tenant is missing — even if the type checker was bypassed. - SQL scope. Every SQL statement carries an explicit
WHERE tenant_id = ?clause. - Composite indexes. Every hot-path index leads with
tenant_idso cross-tenant scans are physically impossible in the planner’s fast path.
In Cloud mode the tenant ID is resolved server-side from your auth token’s claims — never from a client-supplied query parameter or header. Regression coverage lives in tests/unit/storage/sqlite-adapter.test.ts (cross-tenant isolation) and migration-tenant.test.ts (upgrade path).
Supply-chain transparency
Every Iris release produces artifacts you can independently verify:
- npm provenance. Every published tarball carries a GitHub-signed attestation linking it to the source commit and workflow run. Verify with
npm audit signatures. - SPDX SBOMs. A Software Bill of Materials ships with every release, covering direct and transitive dependencies for both the npm package and the Docker image. Attached to the GitHub release page as
iris-npm-sbom.spdx.jsonandiris-docker-sbom.spdx.json. - Cosign signatures. Docker images are signed with Sigstore cosign using GitHub OIDC (no long-lived signing key). Verify with:
cosign verify ghcr.io/iris-eval/mcp-server:vX.Y.Z \ --certificate-identity-regexp='https://github.com/iris-eval/mcp-server' \ --certificate-oidc-issuer='https://token.actions.githubusercontent.com'
- SLSA build provenance. Both artifacts carry GitHub-signed
attest-build-provenanceattestations. Inspect withgh attestation verify.
Runtime defenses
- Helmet headers on the dashboard API (HSTS, X-Frame-Options, X-Content-Type-Options, strict CSP).
- Bearer-token auth on HTTP mode with
crypto.timingSafeEqual-based comparison to block timing side-channels. - Rate limiting: 20 req/min on MCP endpoints, 100 req/min on dashboard APIs, standard RateLimit headers.
- Zod input validation on every MCP tool and REST endpoint. Invalid requests fail fast with structured errors.
- ReDoS protection: custom regex rules are validated with
safe-regex2and length-capped at 1,000 characters before compilation. - Request size limit (1 MB default) to prevent memory-exhaustion attacks.
Threat model
We maintain an internal STRIDE threat model covering ingestion, storage, dashboard API, auth, file I/O, and multi-tenant boundaries. The summary:
- In scope: data confidentiality, tenant isolation, supply chain integrity, DoS resistance on the API surface, audit log tamper detection, prompt-injection-aware eval rules.
- Out of scope: physical access to the host machine (self-hosted), insider threats at the hosting provider, compromise of your LLM provider’s infrastructure, social engineering of your developers.
The full threat model is a private document reviewed and updated quarterly. We share redacted excerpts with enterprise customers under NDA on request.
Reporting a vulnerability
If you believe you’ve found a security issue, please email security@iris-eval.com. Please do not open a public GitHub issue for security matters.
We commit to:
- Acknowledge your report within 2 business days.
- Provide a preliminary assessment (confirmed / not a vulnerability / need more info) within 7 days.
- Coordinate a disclosure timeline with you — we ask for 90 days by default, negotiable for high-severity or widely-exploited issues.
- Credit you in the release notes and the
SECURITY.mdhall-of-thanks unless you prefer to remain anonymous.
Compliance roadmap
Iris is pre-SOC-2 today. For enterprise buyers asking about compliance posture:
- Today: security-by-design architecture, signed releases, SBOMs, internal STRIDE threat model.
- Cloud GA (v0.5): formal SOC 2 Type I readiness, independent penetration test, incident response playbook.
- Enterprise tier: single-tenant isolation option, custom data-residency, BAA/DPA support, SOC 2 Type II within 18 months of Cloud GA.
Related reading
- Privacy Policy — what data we collect and how we use it.
- Terms of Use — licensing, acceptable use, warranties.
- Architecture Guide — the full technical detail behind this page.