If you discover a security vulnerability in Iris, please report it responsibly.
Do NOT open a public GitHub issue for security vulnerabilities.
Instead, please email security@iris-eval.com or submit through GitHub's Private Vulnerability Reporting at https://github.com/iris-eval/mcp-server/security/advisories/new — this delivers the report privately to maintainers, supports attachments, and avoids email entirely. A PGP public key for the email channel is available on request to the same address.
We aim to acknowledge receipt within 48 hours and provide a detailed response within 5 business days. These are best-effort targets — Iris is currently maintained by a solo founder, so a brief delay during travel or focused-work periods is possible. Critical vulnerabilities (active exploitation, RCE, data exposure) get top priority regardless.
This security policy applies to everything this repository builds and releases:
- The Iris MCP server (
@iris-eval/mcp-serveron npm) - The Iris web dashboard, which the server serves
- The container image (
ghcr.io/iris-eval/mcp-server) - The MCPB bundle (
iris-eval.mcpb, attached to each GitHub release) - The
iris-evallauncher package on npm - The JavaScript SDK (
@iris-eval/sdk) and the LangChain.js handler (@iris-eval/langchain) - The Python client (
iris-evalon PyPI) - The GitHub Action in
.github/actions/gate - The Iris website (
iris-eval.com)
For every open Dependabot advisory on this repo, SECURITY-EXPOSURE.md records the per-surface threat-model assessment: load-graph reachability, code-path reachability, untrusted-input reachability, downstream guards, and the resulting decision (override / dismiss-as-not-used / dismiss-as-tolerable-risk / track / patch). CI fails any PR that surfaces a new ≥medium advisory without a corresponding row in that file. This is the substance behind any "open alerts" count you see on the GitHub Security tab.
Iris has one maintainer. Every change reaches main through a pull request that must pass the required CI checks listed in CONTRIBUTING.md — lint and typecheck, unit and integration tests on two Node versions, end-to-end, build, the Docker image started as shipped, the security-exposure gate, the hardcoded-claim scanner and the truthbase regeneration — and CodeQL runs on every pull request; the maintainer reviews and squash-merges it. There is no second human reviewer today, and this policy says so rather than implying one. If that is not enough for your threat model, pin a version and verify the signed release assets (SBOMs, Sigstore bundles, the image signature) the way each release's notes describe; the release workflow runs that verification itself before it reports success.
The current minor receives every fix. The previous minor receives security fixes for 90 days after the current minor's first release, so an upgrade has a window rather than a deadline. Older minors receive none — upgrade to the current 0.19.x line.
| Version | Supported |
|---|---|
| 0.19.x | Yes |
| 0.18.x | Yes, security fixes until 2026-12-24 |
| 0.17.x and lower | No |
Verify what you are running: npx @iris-eval/mcp-server --version, or read the first startup log line.
- Remote code execution
- PII/data exposure in eval outputs
- Injection attacks through MCP tool inputs
- Authentication or authorization bypasses in the dashboard
- Denial of service affecting the MCP server
- Supply chain vulnerabilities in dependencies
- Self-hosted deployment misconfigurations
- Rate limiting on self-hosted instances (user responsibility)
- Vulnerabilities in third-party MCP clients
We follow coordinated disclosure. We will:
- Acknowledge receipt within 48 hours
- Confirm the vulnerability and determine its impact
- Develop and test a fix
- Release the fix and publish an advisory
- Credit the reporter (unless they prefer anonymity)
We ask that you:
- Allow us 90 days by default before public disclosure — negotiable for high-severity or actively exploited issues, where a shorter window is in everyone's interest
- Make a good-faith effort to avoid privacy violations and data destruction
- Do not exploit the vulnerability beyond what is necessary to demonstrate it
- Run Iris behind a reverse proxy with TLS
- Restrict dashboard access to trusted networks
- Keep the API key out of the environment block:
IRIS_API_KEY_FILEreads it from a mounted secret file, andsecurity.apiKeys[].keyHashletsconfig.jsonhold only the sha256 of a key - Rotate keys without a gap: add the new key to
security.apiKeys, move the clients, remove the old key; give a temporary key anexpiresAt. No restart is needed: the server re-readsconfig.jsonand its key files when they change. - Revoke a leaked key at once by removing it from
security.apiKeysor deleting its key file: the next request with it is refused, and its browser sessions end. A key given inIRIS_API_KEYor--api-keyneeds a restart to change - Encrypt the disk or volume that holds the Iris home (
~/.iris,IRIS_HOME, or the image's/data). Iris does not encrypt data at rest:iris.dband its write-ahead-log files are created owner-only (mode 600), and the Iris home directory is created mode 700; on Windows, file ACLs govern instead. The database stores no LLM provider keys:IRIS_ANTHROPIC_API_KEYandIRIS_OPENAI_API_KEYare read from the environment and never written to disk. It does store trace inputs and outputs verbatim. Full-disk encryption covers what file permissions do not: a lost or stolen disk, or a backup. - Keep Iris updated to the latest version
- Review eval rule configurations for your specific compliance requirements