Skip to main content
Midplane secures one path: the path through Midplane. This page is the honest account of which attacks that path covers, which it doesn’t, what’s still exposed once it does its job, and the claims we will and won’t make. It mirrors THREAT_MODEL.md in the repo. If an attacker can reach your database without going through Midplane, Midplane never sees it.

Trust boundaries

Every query crosses the same boundaries in the same order:
The agent is untrusted input; the engine is where the decision is made — and it audits the attempt and the decision before any query reaches your database. For hosted, one boundary is added: your database URL is encrypted at rest with a per-region AWS KMS key.

Vectors covered

These are the attack shapes Midplane is built to stop. Each is pinned by the adversarial corpus.
The agent hands Midplane SQL as text. Midplane parses it into an AST with libpg_query, the real Postgres parser — no regex on SQL, ever. Anything that doesn’t parse is denied by parse_error. Midplane never enforces policy on text it can’t read.
The classic SELECT 1; DROP TABLE users vector — the same class disclosed by Datadog Security Labs against the deprecated Anthropic Postgres MCP. The parser counts statements, not semicolons, so comments and string literals don’t inflate the count. multi_statement denies anything that parses to more than one statement.
table_access denies any write whose target table isn’t read_write in your policy — INSERT, UPDATE, DELETE, MERGE, DROP, TRUNCATE, ALTER, GRANT, REVOKE, CREATE, EXECUTE, CALL, COPY, and more, at any AST depth. With no policy at all, every write denies. Grants are explicit and per-table.
WITH x AS (DELETE FROM y RETURNING *) SELECT * FROM x looks like a SELECT at the top level. The recursive AST walk catches the inner INSERT/UPDATE/DELETE at any depth and checks it against that target’s permission.

Vectors out of scope

These are deliberately not covered. Stating them plainly is the point — Midplane secures the path through it, and these sit outside that path.
“Out of scope” means Midplane makes no claim here — not that the risk doesn’t exist. The same spirit runs through what we claim, and what we don’t: we name what we don’t cover rather than imply we cover everything.

Self-host vs hosted

Both deployment models run the same open-source engine, so the enforcement is identical. The trust difference is entirely about where the container runs and who holds your credentials — where it runs, not what code runs. See Cloud vs self-host for the operational side.

Residual exposure

Even when Midplane does exactly its job, some exposure remains. Self-host has none of Midplane’s infrastructure in the picture — your database URL stays in your network and the audit log is a Postgres you run; the trust question reduces to whether you trust the MIT code you’re running, which you can read before you run it. Hosted adds the residual that comes with managing credentials for you:
  • Decrypted credentials in process memory for the cache TTL plus a short grace window — see credential encryption for the exact TTL. Never written to disk.
  • Connection pools held warm during the cache window; a process compromise inside that window exposes warm connections.
  • The Postgres index of audit data is queryable by Midplane operators with database access until retention expires.
  • In-flight session cookies and MCP tokens, as for any HTTP service.

What we claim, and what we don’t

Security marketing is full of claims that don’t survive contact with how a system actually works. Here’s what Midplane does not claim, stated plainly:
  • “We don’t see your queries.” We do. Every query is logged as the audit record — that’s the product.
  • “Your data never leaves your database.” Query results pass through Midplane in memory on the way back to your agent. We don’t persist results, but they exist in our process for the duration of the response.
  • “We’re SOC 2 certified.” Not yet. SOC 2 work is on the long-term roadmap, gated by enterprise demand.
If a security claim sounds absolute, read it twice. Midplane’s value is in what it provably denies and audits — not in promises it can’t keep.
These claims, by contrast, hold and are load-bearing:
  • AST-based parsing. No regex on SQL. Not now, not ever. Every query is parsed into a real syntax tree before any rule runs.
  • The same Docker image runs in our infrastructure and on your machine. The trust difference is where the container runs, not what code runs.
  • Audit-fail-fails-the-query. If the pre-execute audit write fails, the query does not execute. No query reaches your database unaudited.
  • The OSS engine is MIT. No copyleft, no BSL, no “source-available.” The license stays MIT.

Report a vulnerability

Found something the threat model missed? Report it privately — we treat security reports as the highest priority.
Please do not open a public issue for a vulnerability. Email the details privately so we can coordinate a fix before disclosure.
Email security@midplane.ai with a description and affected version(s), steps to reproduce or a proof-of-concept, and your proposed remediation if you have one. We aim to acknowledge within 2 business days, coordinate disclosure, and credit reporters in the release notes once a fix ships.
If you’ve found a SQL shape that bypasses a policy rule but isn’t a deeper vulnerability, the fastest path is often a corpus contribution — a markdown row plus a failing test. We treat a known bypass as a release blocker. See the adversarial corpus.
Scope. In scope: the engine (parse, policy, audit, execute), the MCP server (stdio and Streamable HTTP), and the published Docker image (midplane/midplane). Out of scope: third-party dependencies (libpg_query, the MCP SDK, the SQLite bindings — report those upstream), the hosted product (midplane.ai, covered by a separate disclosure policy), and your own database, network, or agent configuration (outside the engine’s boundary).

Next steps

Adversarial corpus

The bypass attempts that must stay denied, and the queries that must stay allowed.

How Cloud secures your data

Credential encryption, key isolation, and the exact cache TTL.