Security¶
Threat model¶
kartoza-mcp runs as a child process of a trusted client (Claude
Desktop, Gemini CLI, your own bridge). It accepts JSON-RPC on stdin and
writes JSON-RPC on stdout. No network surface.
Threats worth thinking about:
| Threat | Mitigation |
|---|---|
| Adversarial GeoJSON (DoS via huge input) | Bridge enforces input-size caps; process resource limits via systemd / k8s. |
| Path traversal via file:// or similar | We don't take file paths — only inline JSON strings. |
Code injection via geojson content |
We parse via paulmach/orb/geojson. Strings are never eval'd. |
| Supply-chain (binary tampering) | Releases are GH-Actions-built, attested (SLSA), and signed. |
| Sensitive coordinates in logs | At INFO we log counts only; trace IDs only when MCP_TRACE=1. |
Hardening checklist¶
- Run under a non-root user (
uid=65532is convention). - Read-only root filesystem.
- No network capabilities (
CAP_NET_*dropped). - Memory cap (
MemoryMax=512M) sized for your largest expected input. - CPU quota to keep one tenant from starving others.
- Egress firewalled to nothing — the binary doesn't dial out.
Provenance¶
- Every release artefact has a SLSA provenance attestation.
- The Docker image has a Sigstore signature; verify with
cosign verify ghcr.io/kartoza/kartoza-mcp:vX.Y.Z. - All source files carry SPDX headers.
reuse lintis part of CI.
Reporting a vulnerability¶
Email security@kartoza.com with a description, reproduction steps,
and impact. We'll respond within 5 business days. Please do not
file public GitHub issues for security reports.