Skip to content

privacykey/mantis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

86 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mantis

CLI release Homebrew tap CI Cloudflare Workers edge

Warning

Beta. APIs, DB schema, and CLI flags may still change before v1.0. Components are versioned independently — CLI v0.1.6, full server v0.1.1, edge v0.1.3 at time of writing. Pin a release tag for stability.

Self-hostable mantis key service. API-first.

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.

Highlights:

  • File keys in 10 formats (.docx / .xlsx / .pptx / .pdf / .svg / .html / .md / .eml / .ics / .vcf) plus a 9-file honey-directory .zip and Apple Wallet .pkpass passes (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 + 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 actionshome_assistant destination posts to a HA webhook automation, so a hit can flip a switch (e.g. cut a VLAN via the OPNsense integration), fire a scene, or push a phone notification (mantis install <key> --type homeassistant-receiver prints a ready-to-paste automation skeleton)
  • Direct notification destinations — webhook, email, Slack, Discord, Teams — with a Postgres-backed retry queue and per-key dedup
  • Optional stateless variant (mantis-edge/) — a Cloudflare Worker that decrypts URLs at the edge, no DB to host
  • Uptime Kuma integration — per-key status URL flips on hit, watched by Kuma for 80+ notification channel fan-out

Contents

Getting started

Stateful server or stateless edge? Run the full server (docker compose, Postgres-backed) when you want the web dashboard, notification queue, file/host-event keys, and history. Run the edge (mantis-edge/) — a Cloudflare Worker that decrypts URLs at the edge with no DB to host — when you only need fire-and-forget hit alerts and want zero infrastructure.

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 init

Quickstart (stateful server)

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 -d
# Wait for the boot banner, then read the one-time bootstrap admin key
docker compose logs -f mantis | grep -m1 -A1 "bootstrap API key"

setup.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), and the DB password is the single value you set in .env; the app's DATABASE_URL is derived from it.

The mantis_live_... value printed above is the bootstrap admin key — it is both your CLI token and your dashboard login. To know it up front instead, pre-set BOOTSTRAP_API_KEY=mantis_live_... in .env before the first boot.

Open http://localhost:3000 and paste that same key to sign in to the web dashboard. Then log in the CLI and mint a key:

mantis --key mantis_live_... login --url http://localhost:3000
mantis new "first mantis" -w http://localhost:3000/inbox/demo

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. For a real public-reachable deploy — Tailscale Funnel, Cloudflare Tunnel, Railway, Fly.io, or Render — see deployment options.

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. The compose setup keeps Postgres on an internal-only network with no published port, so the database is never reachable from the host or LAN.

Quickstart (no server / edge)

No DB to host: deploy the Cloudflare Worker, then mint URLs that decrypt at the edge.

mantis edge keygen                 # generate the AES key
mantis edge set-key <worker-url>   # link the deployed Worker
mantis edge mint                   # interactive wizard for a stateless URL

See mantis-edge/README.md for Worker deploy and full mantis edge usage.

Run from source

For contributors hacking on the web dashboard / server:

pnpm install
cp .env.example .env          # set DATABASE_URL and generate MANTIS_API_KEY_PEPPER
pnpm run db:migrate
pnpm dev

Generate the pepper with openssl rand -base64 32 and add it as MANTIS_API_KEY_PEPPER in .env.

Components

Each part of the repo has its own reference:

Docs

Full documentation: github.com/privacykey/mantis-docs.

Common starting points:

License

MIT License. See LICENSE.

About

open source serverless tripwires for detecting unwanted access.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors