This guide explains how to configure GitHub webhooks for Git-Bridge.
Webhook setup is required when the mirror direction is target-to-source or bidirectional. If you only use source-to-target with CodeCommit as source, SQS handles event delivery automatically and no webhook is needed.
- GitHub repository with Admin access
- Git-Bridge deployed and accessible (e.g.,
http://git-bridge.example.com) WEBHOOK_GITHUB_SECRETconfigured in K8s Secret (optional but recommended)
Navigate to your GitHub repository:
Settings > Webhooks > Add webhook
| Field | Value |
|---|---|
| Payload URL | http://git-bridge.example.com/webhook/github |
| Content type | application/json (MUST be JSON, not form-urlencoded) |
| Secret | Value of WEBHOOK_GITHUB_SECRET |
| Which events would you like to trigger this webhook? | Just the push event |
| Active | Checked |
Select Just the push event. GitHub's push event covers both branch pushes and tag pushes.
Do not select "Send me everything" — Git-Bridge only processes push events and will ignore all other event types.
- Click Add webhook
- GitHub will send a
pingevent automatically. Git-Bridge answers it with 200{"status":"accepted"}— the handler never inspectsX-GitHub-Event, and a ping payload is valid JSON carryingrepository, so it parses like a push with an emptyref. That means the ping also kicks off a background sync for the matching repo (a full sync of every enumerated ref, since no ref is named); if no repo matches the payload'sfull_name, the sync ends in the log withno matching repo for provider=...and nothing is mirrored. Either way the delivery shows 200, not 400 - Push a commit to the repository to trigger a real push event
- Go to Settings > Webhooks > (your webhook) > Recent Deliveries to verify HTTP 200 response
You can also verify by checking Git-Bridge logs:
kubectl logs -n git-bridge -l app=git-bridge -fGitHub uses HMAC-SHA256 to sign webhook payloads. This is different from GitLab's simple token comparison.
- Set
WEBHOOK_GITHUB_SECRETink8s/secret.yamlto any value you choose - Use the same value in the GitHub webhook Secret field
- GitHub sends the signature in the
X-Hub-Signature-256header - Git-Bridge verifies the signature by computing HMAC-SHA256 of the payload with the shared secret
- If
WEBHOOK_GITHUB_SECRETis empty, Git-Bridge skips signature verification
Each GitHub repository that acts as a target (in target-to-source or bidirectional direction) needs its own webhook configured. The same secret can be used across all repositories.
If your k8s/configmap.yaml has:
repos:
- name: app
source: codecommit
target: github
target_path: org/app
direction: bidirectional # webhook required
- name: lib
source: codecommit
target: github
target_path: org/lib
direction: source-to-target # webhook NOT required
- name: docs
source: codecommit
target: github
target_path: org/docs
direction: target-to-source # webhook requiredThen you need to configure webhooks on:
org/app(bidirectional)org/docs(target-to-source)
No webhook is needed for org/lib (source-to-target).
| Symptom | Cause | Fix |
|---|---|---|
| HTTP 401 Unauthorized | HMAC signature mismatch | Ensure WEBHOOK_GITHUB_SECRET matches the GitHub webhook secret |
| HTTP 401 Unauthorized | Missing X-Hub-Signature-256 header |
Ensure secret is set in both K8s Secret and GitHub webhook config |
| HTTP 405 Method Not Allowed | Wrong HTTP method | Verify webhook URL is correct and GitHub is sending POST |
| HTTP 400 Bad Request | Body could not be read, or the payload is not valid JSON | Almost always a content-type problem — see the row below. A ping event does not cause this: it returns 200 |
parse failed: invalid character |
Content type is application/x-www-form-urlencoded |
Change Content type to application/json in GitHub webhook settings |
| HTTP 413 Payload Too Large | The push payload is over the configured cap | Raise webhook.max_body_size_mb and the body limit of the proxy in front, together — the app refusing what the proxy forwarded is the silent case |
| Nothing in the git-bridge log at all, and GitHub records a failure | The request never reached the app; a proxy in front rejected it | Check the proxy's own body limit. The app cannot log a request it never received, so GitHub's delivery record is the only evidence |
| Mirror sync not triggered | Wrong direction | Verify the repo's direction is target-to-source or bidirectional |
| Mirror sync not triggered | Wrong target_path |
Ensure target_path in config matches the GitHub repository's full_name (e.g., org/repo) |
| Push to source fails (403) | IAM permission denied | Add codecommit:GitPush to the IAM policy for the mirror user |
In GitHub, go to:
Settings > Webhooks > (your webhook) > Recent Deliveries
Each delivery shows the request headers, payload, and response for debugging.