Receive a Clerk webhook
Authenticate with a Svix webhook signature.
Called by Clerk, never by a client of this API. The delivery is authenticated by its Svix signature, not by a bearer token (a bearer token sent here is ignored): svix-signature is an HMAC-SHA256 of {svix-id}.{svix-timestamp}.{raw body} under the endpoint’s signing secret, svix-timestamp must be within five minutes of now either way, and the body is at most 64 KiB. It is verified against the raw bytes before the body is parsed or the database is touched. A delivery that cannot be verified, for any reason, is answered 400 with one fixed body. A verified event is answered 204 whether or not it changed anything: an event type this server does not act on, a duplicate and a person who is not here are all 204 with the same empty body, so the answer says nothing about what is stored. A 5xx means the database work failed, or that an event which would have taken access away (an account deleted) could not be read; Clerk should redeliver it. An event that would only have changed a profile and cannot be read is 204. The route does not exist unless FOLIOT_CLERK_WEBHOOK_SECRET is set: it answers exactly as any other path this server does not serve. Events acted on: user.updated, user.deleted. Clerk holds no organizations: workspaces and membership live only in Foliot, so every organization.* and organizationMembership.* event is acknowledged with 204 and ignored, like user.created and any other type not listed. Nothing in a payload (a role, a permission, metadata) is read, and the webhook never adds a person to a workspace or changes a role: people join by invitation, and roles are managed in Foliot.