Skip to main content
POST
/
webhooks
/
github
GitHub Webhook
curl --request POST \
  --url https://api.example.com/webhooks/github \
  --header 'Content-Type: application/json' \
  --header 'X-GitHub-Event: <x-github-event>' \
  --header 'X-Hub-Signature-256: <x-hub-signature-256>' \
  --data '
{
  "ref": "<string>",
  "after": "<string>",
  "repository": {
    "full_name": "<string>",
    "clone_url": "<string>"
  }
}
'
{
  "success": true,
  "data": {
    "status": "scan_triggered",
    "scan_id": 42,
    "repo_id": 7,
    "commit_sha": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0",
    "ref": "refs/heads/main"
  }
}
Receives GitHub push event webhooks to automatically trigger security scans when code is pushed to repositories.

Authentication

This endpoint is publicly accessible (no API key required) but requires HMAC-SHA256 signature verification using the configured webhook secret.

Signature Verification

GitHub signs webhook payloads with HMAC-SHA256. The signature is sent in the X-Hub-Signature-256 header:
X-Hub-Signature-256: sha256=<hex_digest>
The server computes the HMAC using the configured WEBHOOK_SECRET and verifies it matches the signature from GitHub. Implementation (see src/routes/webhooks.rs:327):
  • Extracts signature from X-Hub-Signature-256 header
  • Strips sha256= prefix and decodes hex
  • Computes HMAC-SHA256 of raw request body using WEBHOOK_SECRET
  • Compares computed signature with provided signature

Headers

X-Hub-Signature-256
string
required
HMAC-SHA256 signature of the request body, prefixed with sha256=
X-GitHub-Event
string
required
Event type. Must be push for the webhook to be processed. Other event types are ignored.
Content-Type
string
default:"application/json"
Request content type

Request Body

GitHub push event payload. Key fields:
ref
string
required
Git reference that was pushed (e.g., refs/heads/main)
after
string
required
SHA of the commit after the push
repository
object
required
Repository information

Example Payload

{
  "ref": "refs/heads/main",
  "after": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0",
  "repository": {
    "full_name": "acme/web-app",
    "clone_url": "https://github.com/acme/web-app.git"
  }
}

Event Handling

  1. Signature Verification - Validates HMAC-SHA256 signature (see src/routes/webhooks.rs:69)
  2. Event Type Check - Only processes push events, ignores others (see src/routes/webhooks.rs:82)
  3. Payload Parsing - Deserializes JSON payload (see src/routes/webhooks.rs:91)
  4. Repository Lookup - Finds registered repository by clone_url (see src/routes/webhooks.rs:218)
  5. Scan Creation - Creates a new full scan for the pushed commit (see src/routes/webhooks.rs:245)
  6. Pipeline Trigger - Queues or runs scan pipeline (see src/routes/webhooks.rs:265)

Response

success
boolean
Whether the request was successful
data
object
Response data
{
  "success": true,
  "data": {
    "status": "scan_triggered",
    "scan_id": 42,
    "repo_id": 7,
    "commit_sha": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0",
    "ref": "refs/heads/main"
  }
}

Error Responses

{
  "success": false,
  "error": {
    "code": 401,
    "message": "Invalid signature"
  }
}

Configuration

Set the WEBHOOK_SECRET environment variable to enable webhook signature verification. This secret must match the secret configured in your GitHub repository webhook settings.

GitHub Webhook Setup

  1. Go to your repository settings → Webhooks → Add webhook
  2. Set Payload URL to https://your-heimdall-instance.com/api/webhooks/github
  3. Set Content type to application/json
  4. Set Secret to match your WEBHOOK_SECRET
  5. Select Just the push event
  6. Ensure Active is checked

Build docs developers (and LLMs) love