Self-hostable canary key service. API-first.
Warning
Pre-1.0 — no stable release yet. Anything can change in any release, including a patch: APIs, CLI flags, config keys, file formats, and data already on disk. Keep your own backups. Project status. The badge above is generated from the privacykey status list, which says what I promise for this project and every other one.
Caution
Serve it over HTTPS, never plain HTTP. Mantis authenticates with an API key sent as a bearer token and a session cookie — over plain HTTP on a routable address both travel in cleartext and can be sniffed. Put it behind a tunnel (the tailscale / cloudflared compose profiles terminate TLS for you) or a TLS reverse proxy.
You mint a unique URL; when something fetches it, you get notified through the destinations you configure. Useful for honeypot files on shared drives, fake credentials in .envs, SSH-login alarms on jump boxes, detecting site clones, or any "did someone touch the thing they shouldn't" tripwire.
There are two ways to run it. The full server (docker compose, Postgres-backed) gives you the web dashboard, the notification queue, file and host-event keys, and hit history. The edge variant (mantis-edge/) is a Cloudflare Worker that decrypts URLs at the edge with no database to host. Use it when you only need fire-and-forget hit alerts and want zero infrastructure.
Components are versioned independently: the server, the CLI, and the edge worker each carry their own version and release on their own cadence.
- File keys in 10 formats (
.docx/.xlsx/.pptx/.pdf/.svg/.html/.md/.eml/.ics/.vcf) plus a honey-directory.zipand Apple Wallet.pkpasspasses (install / uninstall / fetch callbacks each fire the key) - Host-event installers — shell, sudo, login, boot, wake, network — for macOS, Linux, and Windows, with parsed
X-Mantis-*context including SSH client IP - Web canaries — CSS-background and JS clone-detector — plus NFC NDEF tag URLs and printable QR/NFC sticker labels
- Smart-home triggers via Home Assistant, Scrypted, and an optional LAN watcher
- Smart-home actions — the
home_assistantdestination posts to a HA webhook automation, so a hit can flip a switch, fire a scene, or push a phone notification;mantis install <key> --type homeassistant-receiverprints the automation skeleton - Direct notification destinations — webhook, email, Slack, Discord, Teams — with a Postgres-backed retry queue and per-key dedup
- Uptime Kuma integration — a per-key status URL flips on hit, so Kuma can fan out to its own notification channels
- Fleet provisioning — idempotent key creation keyed on an
external_id, plus create-only enrollment API keys safe to embed in MDM scripts. Seedocs/FLEET-PROVISIONING.md
The fastest path either way is the guided CLI: mantis init asks server-or-edge and walks you through login and your first key.
brew install privacykey/tap/mantis
mantis initTo stand the server up yourself:
git clone https://github.com/privacykey/mantis && cd mantis
./scripts/setup.sh # creates .env with a random DB password + API-key pepper
docker compose up -dsetup.sh is idempotent — re-running it leaves existing secrets untouched. Postgres is never published to the host; it sits on an internal-only docker network.
Full walkthrough, including reading the bootstrap admin key, the one-command Fly.io launch and the stateless edge path: docs/GETTING-STARTED.md.
This is fine for evaluation, but don't rely on a laptop deploy for canaries that need to fire when you're away from your machine.
Every component — CLI, edge worker, LAN helper, benchmarks, deploy assets — has its own reference, indexed at the end of docs/GETTING-STARTED.md.
The prose documentation lives at docs.mantis.privacykey.org, built with Mintlify from privacykey/docs-mantis.
- Getting started — five steps from
brew installto first key - Use cases — defensive, detective, operational and adversarial patterns
- HTTP API — endpoints, response kinds, webhook payload shape
- File keys, host-event keys, deployment, updating
The repo is a pnpm workspace and pnpm is the only supported package manager — the version is pinned in packageManager and CI reads it from there. Node comes from .nvmrc.
pnpm install --frozen-lockfile
pnpm run check # typecheck: server + CLI + edge + iot-helper
pnpm test # unit tests
pnpm run build # next buildCI also runs the integration and tier-2 suites against a real Postgres, builds the CLI, and audits production dependencies. CONTRIBUTING.md has local setup and how to reproduce each job.
MIT. See LICENSE.
