Skip to content

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=65532 is 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 lint is 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.