Customer publish-event trigger
This page is auto-generated from
src/triggers/webhook.ts. Do not edit by hand — seedocs/dev/docs-auto-sync.md.
Inbound webhook customers point at their private registry to trigger scans.
| Method | Path |
|---|---|
POST | /api/v1/triggers/scan |
Signature verification
Section titled “Signature verification”Mechanism: HMAC-SHA256 (per-tenant Upwarden secret)
Transport: X-Vanguard-Signature header (sha256=<hex>)
Per-org HMAC-SHA256 of the raw request body, signed with the tenant’s webhook_secret and encoded as sha256=<hex>. Same shape as GitHub’s signature scheme; constant-time hex comparison. The tenant is resolved by the orgSlug field in the body (with slug-history fallback) — the (slug, signature) pair is the auth.
Idempotency
Section titled “Idempotency”No explicit dedup gate at the receiver. The downstream action is naturally idempotent (e.g. unbind on an already-unbound row is a no-op).
Retry posture
Section titled “Retry posture”Retry posture is governed by the upstream’s webhook delivery contract. Upwarden responds 2xx on accepted deliveries (including known-no-op events) so the upstream stops retrying; transient failures return 5xx so the upstream re-delivers within its retry budget.
Request body
Section titled “Request body”ParsedPayload
Section titled “ParsedPayload”| Field | Type | Optional |
|---|---|---|
orgSlug | string | no |
ecosystem | string | no |
packageName | string | no |
version | string | no |
source | string | no |
sourceRef | string | yes |
artifactUrl | string | yes |
Dispatch tables
Section titled “Dispatch tables”ECOSYSTEMS (Set)
Section titled “ECOSYSTEMS (Set)”npmpypicratesrubygemsnugetmavengo
SOURCES (Set)
Section titled “SOURCES (Set)”customer-webhookgithub-releasemanual
Architecture preamble
Section titled “Architecture preamble”The leading doc-comment block from the source file, reproduced verbatim. This is the canonical narrative explanation of the receiver — the auto-generated sections above are derived from it.
#149 trigger-on-publish — case 1 (customer-triggered) ingestion endpoint.
A customer who publishes a new (package, version) to their own privateregistry — Artifactory, Nexus, GCP Artifact Registry — points a webhookat this endpoint. We record the event in the `triggers` table so adownstream consumer (SIEM export, notification fan-out, scan dispatch)can react before the first customer install resolves the new version.
Auth model: per-org HMAC-SHA256 of the raw body, using the tenant's`webhook_secret`. Header: `X-Vanguard-Signature: sha256=<hex>`. Sameshape as the GHSA webhook in src/blocklist/webhook.ts and as GitHub'sown webhook signature.
First-slice scope: record + audit. Scan dispatch off the trigger rowis the natural follow-up — same `dispatchQuarantineScans` shape theexisting quarantine path uses; deferred so the auth + recording surfacecan land independently.
Tenant resolution: the body carries `orgSlug` and the signature provesthe sender holds that org's secret. So we don't need a `host`-basedresolver here — the (slug, secret) pair is the auth.