Skip to main content

Configure GitHub to Send Webhooks

Configure GitHub repository webhooks to send event notifications to Harness AI SRE for deployments, releases, and security alerts.

Before you begin

  • Harness webhook endpoint: Create a GitHub webhook in Harness AI SRE using the GitHub webhook template.
  • GitHub permissions: Admin access to the repository or organization.
  • Webhook URL: Copy the webhook URL from your Harness webhook configuration.
  • GitHub webhooks documentation: Go to Webhooks Documentation to understand webhook configuration and event types.
  • Event payloads reference: Go to Webhook Events and Payloads for event-specific payload structures.

Create repository webhook

  1. Go to your GitHub repository
  2. Click SettingsWebhooks
  3. Click Add webhook

Configure webhook

  • Payload URL: Your Harness webhook URL
    https://<your-harness-instance>/gateway/ai-sre/api/webhooks/<webhook-id>
  • Content type: application/json
  • Secret: (Optional) Webhook secret for signature verification
  • SSL verification: Enable SSL verification
  • Which events: Select events to trigger webhook

Activate webhook

  • Check Active to enable the webhook
  • Click Add webhook

Select events to monitor

Deployment events

Monitor deployment activities:

Events:

  • Deployments: Deployment created
  • Deployment statuses: Deployment status changed (pending, success, failure, error)

Use cases:

  • Track deployment failures
  • Alert on production deployments
  • Monitor deployment rollbacks

Release events

Monitor software releases:

Events:

  • Releases: Release published, created, edited, deleted

Use cases:

  • Notify on new releases
  • Track release cadence
  • Monitor hotfix releases

Pull request events

Monitor code changes:

Events:

  • Pull requests: Opened, closed, merged, reopened
  • Pull request reviews: Submitted, edited, dismissed
  • Pull request review comments: Created, edited, deleted

Use cases:

  • Track deployment-related PRs
  • Monitor high-impact changes
  • Alert on emergency merges

Security events

Monitor security findings:

Events:

  • Code scanning alerts: Created, fixed, dismissed, reopened
  • Secret scanning alerts: Created, resolved, reopened
  • Dependabot alerts: Created, dismissed, fixed, reintroduced

Use cases:

  • Alert on critical security vulnerabilities
  • Track secret leaks
  • Monitor dependency vulnerabilities

Configure field mapping in Harness

In your Harness webhook configuration, map GitHub payload fields to alert properties.

GitHub webhook payload structure

Payload varies by event type. Common structure:

{
"action": "created",
"deployment_status": {
"id": 123,
"state": "failure",
"description": "Deployment failed",
"environment": "production",
"target_url": "https://example.com/deployment/123",
"created_at": "2025-07-01T10:30:00Z",
"updated_at": "2025-07-01T10:35:00Z"
},
"deployment": {
"id": 456,
"sha": "abc123def456",
"ref": "main",
"task": "deploy",
"payload": {},
"environment": "production",
"description": "Deploy to production",
"creator": {
"login": "deployer"
}
},
"repository": {
"name": "my-app",
"full_name": "myorg/my-app",
"html_url": "https://github.com/myorg/my-app"
},
"sender": {
"login": "github-actions[bot]"
}
}

Field mapping by event type

Basic mapping:

title: "Deployment {{webhook.deployment_status.state}}: {{webhook.repository.full_name}}"
message: |
Deployment to {{webhook.deployment_status.environment}} {{webhook.deployment_status.state}}

Description: {{webhook.deployment_status.description}}
SHA: {{webhook.deployment.sha}}
Ref: {{webhook.deployment.ref}}

View: {{webhook.deployment_status.target_url}}
severity: "{{webhook.deployment_status.state}}"
source: "github"
link: "{{webhook.deployment_status.target_url}}"
tags:
- "repository:{{webhook.repository.full_name}}"
- "environment:{{webhook.deployment_status.environment}}"
- "state:{{webhook.deployment_status.state}}"
- "ref:{{webhook.deployment.ref}}"

CEL mapping:

title: "Deployment " + webhook.deployment_status.state + ": " + webhook.repository.full_name
message: "Deployment to " + webhook.deployment_status.environment + " " +
webhook.deployment_status.state + "\n\n" +
webhook.deployment_status.description

// Map deployment state to severity
severity: webhook.deployment_status.state == "failure" ? "critical" :
webhook.deployment_status.state == "error" ? "high" :
webhook.deployment_status.state == "pending" ? "info" : "info"

source: "github"
link: webhook.deployment_status.target_url

// Filter: only failures and errors
filter: webhook.deployment_status.state in ["failure", "error"]

Test the integration

Test with webhook delivery

  1. Go to SettingsWebhooks in your repository
  2. Click on your webhook
  3. Go to Recent Deliveries tab
  4. Click Redeliver on any past delivery to test

Trigger real events

Create a test deployment using GitHub API:

curl -X POST \
-H "Authorization: token YOUR_GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/OWNER/REPO/deployments \
-d '{
"ref": "main",
"environment": "staging",
"description": "Test deployment for Harness integration"
}'

Verify in Harness

  1. Navigate to Alerts in Harness AI SRE
  2. Check that the event appears
  3. Verify field mapping is correct

Available GitHub webhook headers

GitHub sends these headers with all webhooks:

HeaderDescriptionExample
X-GitHub-EventEvent typedeployment_status, release, code_scanning_alert
X-GitHub-DeliveryUnique delivery ID12345678-1234-1234-1234-123456789012
X-Hub-Signature-256HMAC-SHA256 signaturesha256=... (if secret configured)
X-GitHub-Hook-IDWebhook configuration ID123456
X-GitHub-Hook-Installation-Target-IDInstallation/org ID456789
X-GitHub-Hook-Installation-Target-TypeTarget typerepository, organization

Advanced configuration

Filter by environment

Only process production deployments:

filter: has(webhook.deployment_status) &&
webhook.deployment_status.environment == "production" &&
webhook.deployment_status.state in ["failure", "error"]

Filter by branch

Only process events from main branch:

filter: (has(webhook.deployment) && webhook.deployment.ref == "refs/heads/main") ||
(has(webhook.release) && webhook.release.target_commitish == "main")

Route by repository

Create separate webhooks for different repositories or use routing:

// Tag by repository for routing
tags: [
"repository:" + webhook.repository.full_name,
"repo_name:" + webhook.repository.name,
"event:" + // Extract from X-GitHub-Event header if available
]

Security alert prioritization

Prioritize critical security alerts:

severity: has(webhook.alert) && webhook.alert.rule.severity == "error"
? "critical"
: "high"

// Filter: only security errors
filter: has(webhook.alert) &&
webhook.alert.rule.severity == "error" &&
webhook.alert.state == "open"

Troubleshooting

Webhook not sending

Cause: Webhook configuration error or GitHub can't reach endpoint.

Solution:

  • Check webhook Recent Deliveries for errors
  • Verify webhook URL is publicly accessible
  • Ensure SSL certificate is valid
  • Review response codes (200 = success, 4xx/5xx = error)

Events not triggering

Cause: Event not selected in webhook configuration.

Solution:

  • Edit webhook in GitHub
  • Go to Which events would you like to trigger this webhook?
  • Select Let me select individual events
  • Enable required events
  • Click Update webhook

Signature verification failing

Cause: Secret mismatch or signature not verified.

Solution:

  • Ensure secret in GitHub matches Harness configuration
  • Verify Harness is checking X-Hub-Signature-256 header
  • GitHub uses HMAC-SHA256, not HMAC-SHA1 (legacy)

Payload fields missing

Cause: Event type doesn't include expected fields.

Solution:

  • Check GitHub webhook documentation for event-specific payload structure
  • Use CEL has() to check field existence:
message: has(webhook.deployment_status)
? webhook.deployment_status.description
: "No description"

Example: Complete integration

GitHub webhook configuration

  • Payload URL: https://app.harness.io/gateway/ai-sre/api/webhooks/wh_abc123
  • Content type: application/json
  • Secret: your-secure-secret
  • Events:
    • Deployment statuses
    • Releases
    • Code scanning alerts
  • Active: ✓

Harness webhook field mapping

# Deployment status events
title: |
webhook.deployment_status ?
"Deployment " + webhook.deployment_status.state + ": " + webhook.repository.full_name :
webhook.release ?
"Release " + webhook.release.tag_name + ": " + webhook.repository.full_name :
webhook.alert ?
"Security: " + webhook.alert.rule.name + " in " + webhook.repository.full_name :
"GitHub Event"

message: |
webhook.deployment_status ?
"Deployment to " + webhook.deployment_status.environment + " " + webhook.deployment_status.state :
webhook.release ?
"Release published: " + webhook.release.name :
webhook.alert ?
webhook.alert.rule.description + " (" + webhook.alert.most_recent_instance.location.path + ")" :
"GitHub event received"

severity: |
webhook.deployment_status && webhook.deployment_status.state == "failure" ? "critical" :
webhook.deployment_status && webhook.deployment_status.state == "error" ? "high" :
webhook.alert && webhook.alert.rule.severity == "error" ? "critical" :
webhook.alert && webhook.alert.rule.severity == "warning" ? "high" :
webhook.release ? "info" : "medium"

source: "github"

link: |
webhook.deployment_status ? webhook.deployment_status.target_url :
webhook.release ? webhook.release.html_url :
webhook.alert ? webhook.alert.html_url :
webhook.repository.html_url

tags:
- "source:github"
- "repository:{{webhook.repository.full_name}}"

filter: |
(webhook.deployment_status && webhook.deployment_status.state in ["failure", "error"]) ||
(webhook.release && !webhook.release.prerelease && !webhook.release.draft) ||
(webhook.alert && webhook.alert.rule.severity in ["error", "warning"] && webhook.alert.state == "open")

Next steps


Further reading

GitHub Official Documentation