A webhook is an event notification, not permission to execute arbitrary repository work. Reliable intake needs to verify the sender, identify duplicate deliveries, resolve repository authorization, and apply the current eligibility rules before dispatching a task.

Validate before interpreting

GitHub documents signature validation using a webhook secret and the X-Hub-Signature-256 header. Validation must use the received payload and an appropriate constant-time comparison. Keep the secret outside source control and make signature failure an explicit rejection rather than a warning followed by processing. See GitHub webhook validation.

Signature validity establishes a delivery boundary; it does not decide whether the issue should run. Resolve the installation and repository against your application's authorization records before treating the event as eligible work.

Make duplicate delivery harmless

Persist a delivery identity and use it to avoid processing the same notification repeatedly. Then distinguish event deduplication from business identity. Multiple different events can refer to one issue; separate issues can share the same branch. A uniqueness rule based only on repository and branch can incorrectly collapse unrelated work.

Choose keys that match the actual operation. If one delivery creates a run, define what happens when the same issue is edited, reassigned, or deliberately retried. A database constraint should reinforce that policy rather than accidentally invent it.

Apply policy at the right boundary

An installed app may receive events that do not satisfy your label or assignment rules. That is normal. Keep the reason for ignoring or holding work observable so operators can distinguish a healthy intake filter from a broken webhook endpoint.

A public homepage loading successfully does not prove webhook or GraphQL routing is healthy. Test the specific request path through the tunnel, proxy, application, and persistence layer. After a restart, check service readiness and the expected database rather than recreating volumes to make an error disappear.

Start with a reversible intake test

Create a clearly scoped issue and verify that it appears once in the queue under the expected repository. Confirm ineligible issues do not start work. Only then proceed to funded execution. ForgeLoop's setup overview explains the separate GitHub, repository, and runner setup steps.