Testing webhooks locally with keenauth webhooks listen

keenauth webhooks listen lets you develop a webhook receiver on your own machine. It reads the event API of a development or staging environment and posts each new event to a local URL, signed exactly like a real webhook delivery (Standard Webhooks). You need no public endpoint and no tunnel: the events come to the CLI through the API, and the CLI forwards them on your machine.

Usage

keenauth webhooks listen --forward-to http://localhost:3000/webhooks

The command first prints a signing secret for this session on stderr:

Signing secret for this session (shown once; not sent to KeenAuth, not stored): idp_whsec_…
Forwarding new events to http://localhost:3000/webhooks. Press Ctrl-C to stop.

Configure your receiver with that secret while the command runs, for example as KEENAUTH_WEBHOOK_SECRET, and verify each delivery with the webhook verifier of the SDK (see Verify webhooks). The secret is created on your machine for this session only: it is never sent to KeenAuth, never stored, and a new run creates a new one. It is not the secret of any webhook endpoint you registered.

Flag Description
--forward-to Local URL that receives the events (required). It must be an http or https URL on localhost or a loopback address such as 127.0.0.1 or [::1].
--types Only these event types, comma separated or repeated.
--org Only events of this organization (org_…).
--payload thin (default) or full. full includes the resource and also needs the users:read permission.
--after Where to start: latest (default) forwards only events that happen from now on; a cursor from keenauth events tail starts there.
--interval Time between two checks when there are no new events, from 1s to 60s. Default: 5s.
--output, -o table, json or yaml for the delivery lines. Without the flag the CLI prints a table on a terminal and JSON otherwise.

The command needs the events:read permission and works with an API key and with a keenauth login session.

What your receiver gets

Each event is sent as POST with the event JSON as the body, exactly as the event API returned it, and these headers:

Header Value
webhook-id The event ID (evt_…), the same as in the body.
webhook-timestamp The time of the delivery, in Unix seconds.
webhook-signature v1,<base64 HMAC-SHA256> of <webhook-id>.<webhook-timestamp>.<body> with the session secret.
content-type application/json

Each delivery is tried once. The command prints one line per delivery with the time, event type, event ID, the status code your receiver answered (or the connection error) and the duration. A receiver that fails or is not running does not stop the command. Redirects are not followed.

Environments

The command works only with development and staging environments. With a production credential it stops before it sends any request and exits with code 3:

If the server refuses the request because the environment is a production environment, the CLI prints its problem response, code: test_feature_not_in_production, and also exits with code 3.

Exit codes

Code Meaning
0 Stopped with Ctrl-C.
1 A server error or a network failure towards KeenAuth, or the type of the current environment could not be determined.
2 Usage error: --forward-to is missing, not a local URL, or a filter or interval is invalid. No request was sent.
3 A production credential, a missing credential, or the server answered 401 or 403.
4 The plan does not include the feature (403 with plan_feature_unavailable).