Skip to main content

GitHub Post-Cloud Validation Runbook

Status: Requires Cloud Deploy + Live Credentials Audience: Operators Priority: P0

Objective​

Validate the GitHub package against the production cloud endpoint with live GitHub credentials and webhook events. This is the first-time live validation for GitHub — its live_e2e_status is currently cloud_gated.

Prerequisites​

  • ✅ Public cloud endpoint deployed (control plane reachable)
  • ✅ GitHub personal account or organization with webhook-capable repository
  • ✅ GitHub personal access token (classic, with admin:repo_hook scope)
  • ✅ GitHub webhook secret configured at repository or organization level
  • ✅ Cloud endpoint URL registered as GitHub webhook payload URL
  • ✅ gh CLI installed (optional, for repo management)
  • ❌ No live credentials in docs or generated evidence artifacts

Validation Sequence​

1. Positive Test — Send GitHub Webhook Event​

Trigger a GitHub webhook event and verify delivery:

# Option A: Trigger via GitHub API (create a repository dispatch event)
curl -X POST \
-H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/${OWNER}/${REPO}/dispatches \
-d '{"event_type": "validation-test"}'

Expected: GitHub delivers the webhook to the cloud endpoint.

2. Positive Test — Verify Delivery via Platform API​

curl -s -H "Authorization: Bearer ${PLATFORM_TOKEN}" \
https://api.zen-mesh.io/v1/deliveries?provider=github&limit=1 | jq .

Checks:

  • ✅ Delivery recorded with status: delivered
  • ✅ Event type matches the expected GitHub event
  • ✅ Timestamp is recent (within 60s of trigger)

3. Signature Validation — Verify X-Hub-Signature-256 Header​

Confirm the platform validated the GitHub HMAC-SHA256 signature:

# Retrieve raw webhook headers from delivery evidence
curl -s -H "Authorization: Bearer ${PLATFORM_TOKEN}" \
https://api.zen-mesh.io/v1/deliveries/${DELIVERY_ID}/evidence | jq '.headers["X-Hub-Signature-256"]'

Manually re-verify:

zen package verify-signature github \
--payload payload.json \
--signature-header "$GITHUB_SIGNATURE" \
--secret "$GITHUB_WEBHOOK_SECRET"

Checks:

  • ✅ X-Hub-Signature-256 header is present
  • ✅ Signature verification returns valid: true
  • ✅ X-Hub-Request-Id is present and non-empty

4. Negative Test — Invalid HMAC Signature​

curl -X POST https://api.zen-mesh.io/v1/webhooks/github \
-H "X-Hub-Signature-256: sha256=invalidsignature" \
-H "X-GitHub-Event: push" \
-H "Content-Type: application/json" \
-d '{"ref": "refs/heads/main", "repository": {"full_name": "test/repo"}}'

Checks:

  • ✅ Response status is 401 or 403
  • ✅ Error body indicates signature_verification_failed
  • ❌ No delivery recorded for the rejected event

5. Negative Test — Missing X-Hub-Signature-256 Header​

curl -X POST https://api.zen-mesh.io/v1/webhooks/github \
-H "X-GitHub-Event: push" \
-H "Content-Type: application/json" \
-d '{"ref": "refs/heads/main"}'

Checks:

  • ✅ Response status is 401
  • ✅ Error body indicates missing_signature_header

6. Negative Test — Missing X-GitHub-Event Header​

TIMESTAMP=$(date +%s)
PAYLOAD='{"ref":"refs/heads/main"}'
SIGNED=$(printf '%s' "$PAYLOAD" | openssl dgst -sha256 -hmac "$GITHUB_WEBHOOK_SECRET" | awk '{print $2}')
curl -X POST https://api.zen-mesh.io/v1/webhooks/github \
-H "X-Hub-Signature-256: sha256=$SIGNED" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"

Checks:

  • ✅ Response status is 400
  • ✅ Error body indicates missing_event_type_header

7. Evidence Capture​

# Create evidence directory
mkdir -p docs/80-EVIDENCE/public-docs/github-post-cloud-$(date +%Y%m%d)

# Capture delivery logs
curl -s -H "Authorization: Bearer ${PLATFORM_TOKEN}" \
https://api.zen-mesh.io/v1/deliveries?provider=github > \
docs/80-EVIDENCE/public-docs/github-post-cloud-$(date +%Y%m%d)/delivery-log.json

# Capture validation results
zen package evidence github --output=json > \
docs/80-EVIDENCE/public-docs/github-post-cloud-$(date +%Y%m%d)/validation-evidence.json

# Generate summary
cat > docs/80-EVIDENCE/public-docs/github-post-cloud-$(date +%Y%m%d)/README.md << 'SUMMARY'
# GitHub Post-Cloud Validation

Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)
Validator: $(whoami)
Cloud Endpoint: <endpoint-url>
GitHub Account: <account/repo>
Results: <PASS / FAIL>
SUMMARY

Evidence artifacts:

  • Delivery log showing received GitHub events
  • Signature verification results (positive and negative)
  • Error responses showing rejection of invalid signatures
  • Summary document with pass/fail per test

Exit Codes​

CodeMeaning
0All tests pass
1Positive test fails (no delivery)
2Negative test fails (invalid event not rejected)
3Signature verification fails
4Evidence capture fails
5Credential or access error

Validation Success Criteria​

Validation passes when ALL of the following are true:

  • ✅ GitHub webhook event received and delivered (positive test)
  • ✅ X-Hub-Signature-256 header present and verified by platform
  • ✅ Manual signature re-verification matches platform result
  • ✅ Invalid signature events are rejected
  • ✅ Missing required headers are rejected
  • ✅ Evidence is captured and stored
  • ❌ No live credentials appear in evidence artifacts
  • ❌ No claim of "live validated" or "GA" in evidence output

Troubleshooting​

GitHub Webhook Not Delivered​

  • Payload URL mismatch: Verify the cloud endpoint URL in GitHub repository Settings > Webhooks matches the platform's GitHub webhook endpoint
  • Secret mismatch: Ensure the webhook secret in GitHub matches the one configured in the platform
  • SSL verification: GitHub enforces SSL; verify the cloud endpoint has a valid TLS certificate

Signature Verification Fails​

  • Algorithm mismatch: GitHub signs with sha256= prefix; verify the platform expects this format
  • Payload encoding: GitHub signs the raw body; verify exact byte encoding

No Webhook Events Received​

  • Repository permissions: Ensure the token has admin:repo_hook scope
  • Webhook active: Verify the webhook is not paused or disabled in GitHub
  • Rate limiting: Check GitHub API rate limits on the account