Who owns what
You own every Sentry-shaped thing. Checkfu never verifies Sentry’s signature, never holds your Client Secret, and never operates the Sentry integration.
Register the webhook URL with your Sentry integration for the resources you
actually map. Subscribing to everything and filtering in code builds a
router you then have to operate; subscribing to
issue only is the smaller
surface.
Create the reviewed Automation pair per mapped project
A regressed issue must not be suppressed by the firing that handled its original appearance, and webhook predicates are a conjunction — “action iscreated” and “substatus is regressed” cannot live in one trigger. So
each mapped Sentry project gets a pair of Automations that share the same
reviewed resource bindings and differ only in their filter:
resources are the reviewed Session resource bindings — the writable
file-tree volumes, each carrying the pull-request publication policy a fix
PR targets. A mount without that policy is a writable overlay that never publishes a change. They freeze at
create time; the payload never selects or authors them, only your frozen
mapping decides which pair a delivery forwards to. Both members dedupe on
/data/issue/id, and occurrence identity is per-Automation, so each
converges its own redeliveries while the other class stays free to fire —
that is the whole regression story. Predicates run before the dedupe
claim, and a filtered delivery is recorded as a filtered delivery, not
silence.
The environment_id freezes the Environment every child Session admits
against; a missing Environment fails closed before the Session exists.
Verify Sentry’s signature over the exact bytes
Sentry signs each delivery with your integration’s Client Secret: an HMAC-SHA256 digest, hex-encoded, in theSentry-Hook-Signature header.
Sentry’s documented verification snippet signs the re-serialized parse of
the body, while compact raw-bytes signing is what integrations commonly
observe. Verify the raw bytes first and accept the documented
canonicalization as a fallback — an attacker without the secret can produce
neither digest, and a body that is not JSON never gets the second chance:
Classify the occurrence, then consult your mapping
Two derivations decide everything downstream, and both refuse rather than guess. The occurrence key carries identity coordinates only — installation, issue id, and the class derived from action and substatus. Titles, culprits, stack hashes, and breadcrumbs never enter it: text that changes must not change dedupe identity, and provider text must not sit in coordination stores.created maps to new, unresolved with regressed maps to
regression, and everything else maps to a non-firing class.
The firing map is frozen configuration keyed by the pair actually present
in the payload — the installation UUID and the project slug — and each
entry names the reviewed Automation pair plus the resource bindings those
firings freeze:
Forward the exact bytes through the relay
The stock relay helper orders verify-before-forward, refuses a verifier that rewrites the body, and produces the ordinary ingest signature for the same bytes — your HTTP transport stays yours:targetAutomationId comes from your occurrence class — new deliveries
to the mapped pair’s new-issue member, regressions to its regression
member. The
platform does the rest: the predicate ladder re-decides relevance, the
dedupe pointer converges redeliveries, and an accepted event becomes one
AutomationRun linked to its Session.
Keep the webhook out of the Run
The webhook body told you where the work is, not what the work is. Inside the Session, fetch the full issue, stacktrace, and events through a governed connection — your provider client operating under credentials the platform never copies — and build the fix brief from that fresh read. A prompt template that interpolates webhook text has made provider bytes into trusted Run input, which is the exact inversion this recipe exists to prevent. Delivery back to Sentry is read-only in this shape: the fix PR link lands in the Session log, and your delivery worker projects it wherever your reviewed provider capability honestly supports. Do not bolt a write path on without the same custody review any provider call gets.Prove it before you wire Sentry to it
The reference relay ships with deterministic suites that need no credentials: signature acceptance and forgery rejection (including the re-serialization fallback boundary), occurrence-class stability and regression separation, closed-decode refusals, mapping refusal, and the admission verdicts. Run them before the webhook URL exists:Next
Trigger Automations from providers
The Automation side this recipe forwards into: sources, registrations, and the admission ladder.
Follow a Linear issue as one conversation
The other half of the error-to-fix loop: a continuing thread instead of a fresh Session per event.