Boat.Webhook reference
SandboxEvents
Section titled “SandboxEvents”Source:
packages/boat/src/SandboxEvents.ts
Receive Boat sandbox lifecycle events (sandbox.ready,
sandbox.hydrated, sandbox.error, sandbox.archived,
sandbox.degraded, sandbox.recovered) in a Cloudflare Worker or any
other webhook host.
At deploy, a Webhook is created pointing at the host, and its
signing secret is given to the host as a secret (a Cloudflare secret on
a Worker). While the host runs,
each delivery’s X-Ascii-Signature (HMAC-SHA256 over the delivery id,
timestamp and raw body) is checked before the handler runs; an unsigned,
wrongly signed, altered or stale (over five minutes old) request is
refused with 401, and bodies over 1 MB are refused unread. Boat retries a
failed delivery, so handlers should be idempotent on event.id.
Boat sends a webhook the events of every sandbox in the account, and an
account has at most 10 webhooks. With the default scope: "stack", the
host looks each sandbox up with a key of its own, created at deploy and
deleted with the host, that can only read sandboxes (sandbox.read), and drops
events for sandboxes other stacks or stages own, and for sandboxes
already deleted. The scope is a filter, not an access boundary: anyone
in the account who can create sandboxes can label one with the stack’s
labels.
SandboxEvents: Handling lifecycle events
Section titled “SandboxEvents: Handling lifecycle events”Record when a sandbox stops
export default class Api extends Cloudflare.Worker<Api>()( "Api", { main: import.meta.url }, Effect.gen(function* () { yield* Boat.consumeSandboxEvents({ events: ["sandbox.archived"] }, (event) => Effect.log(`sandbox ${event.data.sandbox.id} stopped`), ); return { fetch: Effect.succeed(HttpServerResponse.text("ok")) }; }).pipe(Effect.provide(Boat.SandboxEventsLive)),) {}Every sandbox in the account
yield* Boat.consumeSandboxEvents({ scope: "account", events: ["sandbox.error"] }, (event) => Effect.logError(`sandbox ${event.data.sandbox.id} failed`),);SandboxEventsLive
Section titled “SandboxEventsLive”Source:
packages/boat/src/SandboxEventsLive.tsKind: Layer · Provides:Boat.SandboxEvents
SandboxEvents on any WebhookHost: every Cloudflare Worker
is one.
Webhook
Section titled “Webhook”Source:
packages/boat/src/Webhook.ts
A Boat webhook: Boat POSTs sandbox lifecycle events (sandbox.ready,
sandbox.error, sandbox.archived, sandbox.hydrated,
sandbox.degraded, sandbox.recovered) to your endpoint, signed with
secret.
Webhook: Receiving sandbox events
Section titled “Webhook: Receiving sandbox events”const receiver = yield* Receiver;const hook = yield* Boat.Webhook("Events", { url: Output.interpolate`${receiver.url}/boat`, events: ["sandbox.ready", "sandbox.archived"],});