A self-hosted approval broker between your automations and you.
Your automation asks for permission → you get a push notification → you tap Approve or Reject → the automation continues. Don't answer in time and a configurable default fires automatically.
- An automation hits
POST /api/requestswith its details and its n8n Wait-node resume URL. - Greenlight stores it, then pushes a notification with a deep link.
- You open the link and Approve or Reject (optionally with a comment).
- Greenlight calls the resume URL — the workflow continues down the right branch.
- No response before the timeout? The default action fires and resumes the workflow the same way, marked as auto-decided.
→ Full walkthrough with sequence & state diagrams in docs/architecture.md.
- 🟢 One-tap approvals from a clean, mobile-friendly web UI (installable as a PWA).
- ⏱️ Timeout defaults per source/category — approve or reject automatically if you're away.
- 🔁 Restart-safe & exactly-once — deadlines survive restarts; a decision racing a timeout resolves exactly once.
- 📡 Push via your own ntfy — or run notification-free and just watch the dashboard.
- 🔒 Built to expose — API-key auth, rate-limited login, HMAC sessions, CSRF, hashed keys.
- 📦 Single self-contained binary — Go + embedded templates/assets + SQLite. No external services required.
Local (no Docker):
export GREENLIGHT_ADMIN_PASSWORD='pick-a-password'
export GREENLIGHT_SESSION_SECRET="$(openssl rand -hex 32)"
export GREENLIGHT_PUBLIC_URL='http://localhost:8080'
go run ./cmd/greenlightOpen http://localhost:8080 and log in. The first run prints a bootstrap API
key to the logs — use it as the X-API-Key header for /api/*.
Create a test request:
curl -X POST http://localhost:8080/api/requests \
-H "X-API-Key: <your-key>" -H "Content-Type: application/json" \
-d '{
"title": "Deploy v2.1 to prod",
"source": "manual-test",
"priority": "high",
"timeout_seconds": 300,
"default_action": "reject",
"resume_url": "https://webhook.site/your-uuid"
}'It appears on the dashboard; approving/rejecting POSTs the decision to
resume_url.
Docker: see docs/deployment.md.
| Guide | |
|---|---|
| 🏗️ Architecture | Components, flow, lifecycle, timeout engine. |
| ⚙️ Configuration | Env vars + default-rule resolution. |
| 🔌 API reference | Endpoints, payloads, callback shape. |
| 🔧 n8n integration | Wait-node wiring + importable workflow. |
| 📡 Notifications | ntfy setup. |
| 🚀 Deployment | Docker, tunnels, backups. |
| 🔒 Security | Auth model & guarantees. |
| 🛠️ Development | Build, test, layout. |
Go (net/http + html/template) · SQLite (mattn/go-sqlite3) · HTMX (vendored,
no build step) · a background goroutine for the timeout engine. Everything ships
in one binary.
