Summary
Add a /api/github-webhook POST endpoint to the existing FastAPI server that receives GitHub webhook payloads and verifies their authenticity via HMAC-SHA256 signature checking.
RFC: #177 (GitHub Webhook to Swarm Notification Bridge)
Architecture decision: Option A -- dedicated endpoint on existing swarm server (not standalone service, not GitHub Actions).
Design
New File
src/server/routes/github_webhook.py -- route handler, registered in create_app()
Environment Variables
GITHUB_WEBHOOK_ENABLED (bool, default false) -- opt-in flag; when false, endpoint returns 404
GITHUB_WEBHOOK_SECRET (string) -- shared secret for HMAC-SHA256 signature verification
Endpoint Behavior
POST /api/github-webhook
- Read
X-Hub-Signature-256 header from request
- Compute HMAC-SHA256 of request body using
GITHUB_WEBHOOK_SECRET
- Compare signatures using
hmac.compare_digest() (constant-time)
- Return
403 Forbidden if signature missing or invalid
- Return
200 OK for valid webhooks with handled event types
- Return
202 Accepted for valid webhooks with unhandled event types (e.g., push, star)
- Return
404 Not Found if GITHUB_WEBHOOK_ENABLED is false
Security
- HMAC-SHA256 verification is mandatory -- no unsigned requests accepted
- Use constant-time comparison to prevent timing attacks
- Each agent manages their own webhook secret for their repos
Acceptance Criteria
Dependencies
None -- this is the foundation issue.
Summary
Add a
/api/github-webhookPOST endpoint to the existing FastAPI server that receives GitHub webhook payloads and verifies their authenticity via HMAC-SHA256 signature checking.RFC: #177 (GitHub Webhook to Swarm Notification Bridge)
Architecture decision: Option A -- dedicated endpoint on existing swarm server (not standalone service, not GitHub Actions).
Design
New File
src/server/routes/github_webhook.py-- route handler, registered increate_app()Environment Variables
GITHUB_WEBHOOK_ENABLED(bool, defaultfalse) -- opt-in flag; when false, endpoint returns 404GITHUB_WEBHOOK_SECRET(string) -- shared secret for HMAC-SHA256 signature verificationEndpoint Behavior
POST /api/github-webhookX-Hub-Signature-256header from requestGITHUB_WEBHOOK_SECREThmac.compare_digest()(constant-time)403 Forbiddenif signature missing or invalid200 OKfor valid webhooks with handled event types202 Acceptedfor valid webhooks with unhandled event types (e.g.,push,star)404 Not FoundifGITHUB_WEBHOOK_ENABLEDis falseSecurity
Acceptance Criteria
POST /api/github-webhookendpoint exists and is registered in FastAPI appX-Hub-Signature-256headerGITHUB_WEBHOOK_ENABLEDis falsehmac.compare_digest()for constant-time comparisonGITHUB_WEBHOOK_SECRETread from environment variableDependencies
None -- this is the foundation issue.