webhook
The webhook surface turns a machine into a receiver for external events. When Stripe sends a payment notification, GitHub sends a push event, or Slack sends an interaction payload, the webhook surface receives it, verifies the signature, and runs the machine.
Overview
Webhooks are inbound HTTP requests from external services. The webhook surface configures a path where these requests are received, an optional signature verification method, and an optional named provider for pre-configured verification. The incoming payload is mapped to the machine’s accepts contract and processed through governance before the machine executes.
Syntax
expresses webhook path: "/hooks/stripe" authentication: "hmac_sha256" provider: "stripe"A complete machine with a webhook surface:
machine stripe_handler
accepts event_type as text, is required data as map, is required
responds with status as text
ensures permissions allowed to reason, http
implements decide route_event when input.event_type is "payment_intent.succeeded" compute handle_payment {status: "processed"} when input.event_type is "charge.failed" compute handle_failure {status: "failed"} otherwise compute skip {status: "ignored"}
expresses webhook path: "/hooks/stripe" authentication: "hmac_sha256" provider: "stripe"Configuration options
| Config | Required | Default | Description |
|---|---|---|---|
path | Yes | - | URL path for the webhook receiver |
authentication | No | "none" | Signature verification: "hmac_sha256", "none" |
provider | No | - | Named provider for pre-configured signature verification |
Supported providers
| Provider | Signature header | Algorithm |
|---|---|---|
"stripe" | Stripe-Signature | HMAC-SHA256 with timestamp |
"github" | X-Hub-Signature-256 | HMAC-SHA256 |
"microsoft" | Client state validation | Token-based |
"slack" | X-Slack-Signature | HMAC-SHA256 with timestamp |
For providers not in this list, use authentication: "hmac_sha256" and configure the secret in your cell’s credentials with mashin secrets set.
Signature verification
When authentication: "hmac_sha256" is set, the handler:
- Reads the signature from the provider-specific header
- Computes HMAC-SHA256 of the raw request body using the webhook secret from cell credentials
- Compares (constant-time) the computed signature with the received signature
- Rejects the request with HTTP 401 if the signature does not match
Governance
Every webhook delivery is governed:
- Signature is verified (if configured)
- Payload is validated against the
acceptscontract - Governance permissions from
ensuresare checked - The machine executes
- A
SurfaceAccessevent is recorded with:webhooksurface in the behavioral ledger - The external service receives an HTTP 200 acknowledgment
Rejected webhooks return HTTP 403 (governance denied) or HTTP 401 (signature invalid). Most webhook providers retry on non-2xx responses.
Example
Multiple webhook sources on one machine:
expresses webhook path: "/hooks/stripe" provider: "stripe" webhook path: "/hooks/github" provider: "github"Registering the webhook URL with the external service requires a public URL. On cloud cells, use https://myorg.mashin.live/hooks/stripe. For local development, use mashin tunnel to get a public URL.
See also
- expresses - Parent section for all surfaces
- api - REST API surface
- websocket - WebSocket surface
- subscribes - Event subscription surface