What you’ll build

- A Cloud Endpoint is the public URL you give to GitHub.
Its Traffic Policy accepts only the
/github-webhook/path, verifies the GitHub signature, and rejects everything else. - An internal Agent Endpoint,
https://jenkins.internal, runs on the Jenkins host. Only the Cloud Endpoint can send traffic to it.
What you’ll need
- An ngrok account and an API key.
- The ngrok agent installed on the Jenkins host. The host needs outbound access on port 443.
- Admin access to the GitHub repository or organization that sends the webhooks.
- Jenkins with the GitHub plugin installed. Pipelines that use the GitHub Branch Source plugin also receive events through the GitHub plugin.
1. Give Jenkins a private address
On the Jenkins host, start an internal Agent Endpoint that points to Jenkins. Jenkins listens on port8080 by default.
Change the port if yours is different.
2. Store the signing secret in a vault
Keep the webhook secret out of your policy. Store the secret in Secrets for Traffic Policy instead. Add your API key to the ngrok CLI:openssl rand -hex 32.
Then create a vault and a secret:
<VAULT_ID> with the ID that the first command returns.
3. Create the Cloud Endpoint and policy
Go to Endpoints, click New +, then Cloud Endpoint. Enter the domain you want GitHub to send events to, for exampleci-webhooks.example.com.
Replace the default Traffic Policy with this policy:
- The first rule returns a
404for every path except/github-webhook/, so even a correctly signed request can only reach the webhook path. - The
verify-webhookaction checks the GitHub signature. A request with a bad or missing signature gets a403. - The
forward-internalaction sends verified requests tojenkins.internal. The path stays the same, so Jenkins receives the request at/github-webhook/.
4. Configure the GitHub webhook
In your GitHub repository, go to Settings → Webhooks → Add webhook. For an organization-wide webhook, go to the organization’s Settings → Webhooks instead. Set these fields:
Click Add webhook.
GitHub sends a
ping event right away.
5. Configure Jenkins
Turn on the webhook trigger for each job that should build on push:- Freestyle and Pipeline jobs: open the job’s Configure page. Under Build Triggers, select GitHub hook trigger for GITScm polling.
- Multibranch Pipeline and Organization Folder jobs: no trigger setting is needed. The GitHub Branch Source plugin reacts to the events.
Let GitHub own the webhook
The GitHub plugin can create webhooks for you, but it registers the Jenkins URL, which is private. Go to Manage Jenkins → System → GitHub and make sure Manage hooks is off for your GitHub server. Add the webhook in GitHub by hand, as in step 4.6. Test it
-
In GitHub, open the webhook, click the Recent Deliveries tab, and find the
pingevent. Click Redeliver. -
In the ngrok dashboard, open the Traffic Inspector.
The request to
/github-webhook/shows a200response from Jenkins. - Push a commit to the repository. A build starts on each job that has the trigger turned on.
-
Confirm that ngrok rejects a forged request:
You get a
403 Forbidden, and Jenkins doesn’t see the request. -
Confirm that other paths are blocked:
curl -i https://<YOUR_NGROK_DOMAIN>/loginreturns a404.