Validation¶
What the project actually proves, and how. The aim is honesty: each control has a corresponding check.
Unit tests¶
Fast, database-free tests (run by make test) cover:
- the read-only SQL guard, including bypass classes (comma joins, subqueries, UNION, schema-qualified objects, dangerous functions, statement chaining);
- argument validation and rejection for every tool, before any SQL is issued;
- parameterization — values are passed as bound parameters, not interpolated;
- the database layer's guard call, row-limit application, and read-only session setup, using a fake connection;
- JSON-safe serialization (
Decimal → float, recursive, non-mutating); - audit logging (one line per call; secrets and
DATABASE_URLnever logged); - MCP tool registration and wrapper behavior.
Smoke test¶
make smoke runs the tools end to end against a running stack and checks sane
results, including a direct INSERT (bypassing the guard) that the database
must refuse. It exits with a clear setup message — not a stack trace — when the
database or configuration is missing.
Live-DB integration tests¶
Opt-in tests (enabled by MCP_GATEWAY_RUN_INTEGRATION=1) prove against real
PostgreSQL that:
- the configured read-only session refuses a direct write while reads work;
gateway_readerisSELECT-only — a raw connection'sINSERTfails with insufficient privilege, proving the role independently of the session;- the schema, passenger-lookup, and stats tools return correct results.
They are skipped by a normal make test, and run in the CI integration job
against a PostgreSQL service container.
Documentation build¶
The CI docs job runs make docs-check: a strict MkDocs build (broken links or
pages missing from the nav fail the build) followed by an internal link check over
the generated site, so no page ships with a dead relative link or fragment anchor.
Docker image build¶
The CI image job builds the container image with no database and no secrets,
then runs an import-only sanity check (import mcp_data_gateway.server) with the
entrypoint overridden so the stdio server does not hang.
Non-root container check¶
The same job asserts the image runs as the unprivileged gateway user by
checking id -un inside the container.