Webhooks
The two inbound webhook receivers Minctrl exposes — Linear and GitHub — how signatures are verified, and what each currently does.
Inbound only
Minctrl's webhooks are inbound receivers — endpoints that accept events from Linear
and GitHub. There is no outbound webhook / event-subscription API: you cannot register a
URL for Minctrl to call when a run parks or completes. To observe run state, poll
GET /process-runs/{id} (see Run a governed process).
This page documents exactly what the two receivers do today — nothing more.
Two endpoints exist:
| Endpoint | Source | Auth |
|---|---|---|
POST /webhooks/linear | Linear | HMAC-SHA256 via X-Linear-Signature |
POST /webhooks/github | GitHub | HMAC-SHA256 via X-Hub-Signature-256 |
Both are public (no bearer token) and authenticate the sender by signature instead.
Signature verification
Each request body is verified against a shared secret:
- Linear sends
X-Linear-Signature: <hex_digest>; verified againstLINEAR_WEBHOOK_SECRET. - GitHub sends
X-Hub-Signature-256: sha256=<hex_digest>; verified againstGITHUB_WEBHOOK_SECRET.
A bad signature returns 401 ("Invalid Linear webhook signature" /
"Invalid GitHub webhook signature"). If the corresponding secret is not configured,
verification is skipped (dev mode) — set the secret in any real deployment.
POST /webhooks/linear
Verifies the signature, then accepts and acknowledges the event:
{ "received": true, "action": "<action from payload>" }Acting on Linear events (mirroring state to the kanban, resuming a workflow) is not yet implemented — the endpoint is a signature-verified accept-and-ack today.
POST /webhooks/github
Verifies the signature, then acknowledges:
{ "received": true, "event": "<X-GitHub-Event>", "action": "<action>" }It currently acts on exactly one case: a pull_request closed event where the PR was
merged on a minctrl/wf-* branch. When that matches, it resolves the branch to the
workflow that was awaiting_review and auto-resumes it (approving the review gate as
"PR merged"). This runs as a background task, so the HTTP response returns immediately;
any failure is logged, not raised. All other GitHub events are acknowledged without action.
This GitHub auto-resume applies to the internal workflow review gate, not to
process runs. Process runs are resumed only via
POST /process-runs/{id}/resume.