Trust · Security
Security
SignalPilot is designed to make AI access to your data safe by default. This page describes the full security model and how to report a problem.
Reporting a vulnerability
If you believe you have found a security vulnerability in SignalPilot, please report it privately. Do not open a public GitHub issue.
Email: security@signalpilot.ai
Please include:
- A description of the issue and its potential impact
- Steps to reproduce (proof-of-concept code or commands if available)
- The affected version, commit SHA, or deployment configuration
- Whether the issue is already public or coordinated with another party
What to expect:
- Acknowledgement within 3 business days
- Triage and initial assessment within 7 business days
- Coordinated disclosure. We will work with you on a fix timeline and credit you in the advisory if you would like.
We use GitHub Security Advisories to publish fixed vulnerabilities once a patch is available.
Scope
In scope:
- The SignalPilot gateway (FastAPI backend, MCP server, REST API)
- The web UI (Next.js frontend)
- The Claude Code plugin
- The sandbox manager (
sp-sandbox/) and the notebook and chat sandboxes - Database connectors and credential storage
Out of scope:
- Vulnerabilities in third-party dependencies (please report upstream)
- Issues that require a malicious admin user with full write access
- Denial-of-service via misconfiguration
Governance
- Read-only enforcement: DDL and DML statements are blocked at the parse layer. No
CREATE,DROP,ALTER,INSERT,UPDATE,DELETE. - Dangerous function denylist: 79+ functions blocked across PostgreSQL, MySQL, SQLite, SQL Server, Snowflake, Databricks, and BigQuery.
- LIMIT injection: Fail-closed. If LIMIT cannot be injected, the query is rejected.
- Multi-statement blocking: Prevents SQL stacking attacks.
- INTO clause detection: Blocks
SELECT INTO,COPY TO, and similar exfiltration patterns.
See Governance reference for the complete rule set.
Authentication
- Clerk JWT verification with JWKS rotation, clock leeway, and required claims (cloud mode)
- API keys with Fernet encryption at rest, org-scoped, with brute-force rate limiting (60/min/IP)
- Org role enforcement: Admin-only endpoints require the
org:adminrole
Network
- SSRF protection: Cloud warehouse connection parameters validated against allowed domains (Snowflake, Databricks, BigQuery)
- DNS rebinding defense: Hostnames resolved and validated before connection
- Non-root containers: Gateway and backend run as UID 10001
Sandboxed workspaces
Notebooks and chat sessions run user- and agent-supplied code, so each one is isolated from the gateway and from every other tenant:
- One microVM per session. Each session runs in its own isolated microVM. Nothing is shared with other sessions or with the host.
- Restricted egress. A sandbox can reach DNS, the gateway, and the hosts in the
SP_NOTEBOOK_EGRESS_ALLOWallowlist. Nothing else. - Fixed resources. CPU and memory are fixed per sandbox (
SP_NOTEBOOK_VCPUS,SP_NOTEBOOK_MEMORY_MB). - Per-org concurrency cap.
SP_NOTEBOOK_MAX_RUNNING_PER_ORG(default 20) bounds how many sandboxes one organization can run at once. - Short-lived. Idle sessions are snapshotted and destroyed after
SP_NOTEBOOK_IDLE_SNAPSHOT_SECONDS(15 minutes). Durable state is the committed workspace, not the sandbox.
Evaluation workloads
- Eval configuration, execution, evidence, and live-sandbox routes require a user ID listed in
SP_ADMIN_USER_IDSand an org listed inSP_EVAL_ALLOWED_ORGS. - Every task receives a short-lived API key bound to one run, one task, and one database connection. The key cannot access query history, workspace integrations, notebooks, connection mutation, or Xata branch-control tools.
- Write tasks receive a disposable branch credential. The local Postgres provider refuses to start a task while its role can connect to any other non-template database.
- Eval sandboxes run non-root with fixed CPU and memory limits and restricted egress. In cloud mode the runner image must be digest-pinned.
- The local eval runtime cannot join the control database or object-store networks. It receives artifacts through a signed, GET/HEAD-only proxy and uses a dedicated disposable warehouse service.
Eval containers execute model-authored commands and hold the task's source checkout and branch credential. The current cloud policy permits public HTTPS so the agent can reach its model provider. Deployments that treat eval repositories as hostile must route that egress through an allowlisting proxy; a network-level allowlist alone cannot restrict destinations by hostname.
Audit
- Every query logged with timestamp, org, user, connection, and SQL
- PII redaction: SQL string literals replaced with
<REDACTED>in audit logs - Query cost estimation before execution
Encryption
- Fernet with MultiFernet rotation for credential storage. Set the new key in
SP_ENCRYPTION_KEYand keep prior keys inSP_ENCRYPTION_KEY_OLD; prior keys are decrypt-only and rows are rewritten under the primary key on access.
Rate limiting
- 100 requests/min/IP on auth endpoints (brute-force protection); 60 failed authentications/min/IP
- 1000 MCP tool calls/min/API key (
SP_PER_KEY_RPM) - 5000 MCP tool calls/min/org, cloud mode (
SP_PER_ORG_RPM) - 10000 requests/min/IP general, 1000/min on expensive endpoints
Tenant isolation
In multi-tenant (cloud) mode, every API key is scoped to an org. A key can only access connections registered by that org. Cross-tenant access is blocked at the data layer, not just at the API layer.
Supported versions
Security fixes land on main. We recommend running the latest commit from main or the most recent tagged release.