GitHub Webhook Receiver fuer die AI-Engineering-at Org — Bauteil #83.
Stand: 2026-05-27
Status: Bauteil (Reife 5 — Mac-LIVE; Tests gruen, lokal lauffaehig)
Visibility: private (internal compliance/automation infrastructure)
Bauteil-ID: #83 (W83-F)
Cross-Ref: kb/raw/2026-05-27-w83-f-aie-github-bridge-bauteil.md, kb/raw/2026-05-27-w82-a-github-org-automation.md (Phase B Punkt 4 Spec)
FastAPI-Service der GitHub-Webhook-Events fuer die AI-Engineering-at-Org empfaengt,
HMAC-verifiziert und an die richtigen internen Surfaces routet:
| Event-Typ | Route | Mattermost-Ziel | Severity |
|---|---|---|---|
pull_request |
alerts | @alerts |
info |
issues |
alerts | @alerts |
info |
workflow_run (failure/timed_out/cancelled) |
alerts | @alerts |
error |
workflow_run (success/in_progress) |
debug-only | — | info |
push |
debug-only | — | info |
ping |
debug-only | — | info |
| unbekannt | debug-only | — | info |
Jeder eingehende Event wird Tier-1 audit-geloggt ueber aie-action-log-writer
(append-only Hash-Chain JSONL unter ~/kb/ops/agent-actions/YYYY-MM-DD.jsonl).
- CLAUDE.md Regel 8 (Konzept ≠ Bauteil): Code + Tests (14 pytest gruen) +
lauffaehig (uvicorn auf :8190) + reproduzierbar (Dockerfile + docker-compose)
- bedienbar (Joe-Klick-Sektion unten).
- CLAUDE.md Regel 19 (KEIN-MOCK-ABSOLUT): Wenn
MM_ALERTS_WEBHOOK_URLfehlt, meldet die Response"forwarded": false, "reason": "MM_ALERTS_WEBHOOK_URL not set"— kein erfundener Mattermost-Erfolg. - CLAUDE.md Regel 21 (ISC2-CC):
- Integrity: HMAC-SHA256 ueber den rohen Request-Body (GitHub
X-Hub-Signature-256). - Constant-time compare:
hmac.compare_digestschuetzt vor Timing-Side-Channels. - Logging (EU AI Act Art. 12 / DSGVO Art. 32): Tier-1 action-log Eintraege mit prev/this Hash-Chain pro Webhook-Delivery.
- Least privilege: Service oeffnet nur GET
/healthund POST/webhook/github.
- Integrity: HMAC-SHA256 ueber den rohen Request-Body (GitHub
- Fallback-Chain (CLAUDE.md Regel 16): Falls Mattermost-Forward fehlschlaegt,
bleibt die action-log-Spur erhalten → Rekonstruktion via
aie-action-log-writer --verify. GitHub-Side erhaelt weiterhin HTTP 200, damit das Delivery-Retry nicht den Log-Stream verdoppelt.
aie-github-bridge/
├── src/aie_github_bridge.py # FastAPI app + classify_event + HMAC verify
├── tests/test_github_bridge.py # 14 pytest (PR/Issue/Workflow/Push/HMAC/Health)
├── Dockerfile
├── docker-compose.yml
├── README.md
├── LICENSE
└── .github/workflows/ci.yml
# 1) Tests
cd ~/code-aie/aie-github-bridge
python3 -m pytest tests/ -v
# 14 passed in 0.20s
# 2) Self-test (kein Port-Bind)
python3 src/aie_github_bridge.py --self-test
# aie-github-bridge self-test: PASS
# 3) Run service (Port 8190)
export GITHUB_WEBHOOK_SECRET='<dein-secret-aus-github-org-settings>'
export MM_ALERTS_WEBHOOK_URL='https://mm.aie/hooks/<incoming-webhook-id>' # optional
python3 -m pip install uvicorn fastapi httpx
python3 src/aie_github_bridge.py
# 4) Health-Check
curl -s http://localhost:8190/health | python3 -m json.tooldocker compose up -d --build
docker compose logs -f| Variable | Pflicht | Default | Zweck |
|---|---|---|---|
GITHUB_WEBHOOK_SECRET |
ja | — | HMAC-Verify-Schluessel (GitHub Org-Setting) |
MM_ALERTS_WEBHOOK_URL |
nein | — | Mattermost Incoming-Webhook fuer @alerts |
AIE_BRIDGE_PORT |
nein | 8190 |
uvicorn-Port |
AIE_BRIDGE_LOG_DIR |
nein | ~/kb/ops/agent-actions |
action-log Zielverzeichnis |
Diese Schritte muss Joe einmalig durchfuehren — Brain hat keinen Org-Admin-Schreibzugriff:
- Webhook-Secret generieren (z.B.
openssl rand -hex 32oder 1Password):- Erzeugt ein 64-Zeichen-Hex-Token.
- GitHub → Org-Settings:
https://github.com/organizations/AI-Engineering-at/settings/hooks- "Add webhook"
- Payload URL:
https://github-bridge.aie/webhook/github(oder Cloudflare-Tunnel-URL wenn lokal getestet — siehe Tunnel-Sektion unten). - Content type:
application/json - Secret: das in Schritt 1 erzeugte Hex-Token.
- SSL verification: Enable (Default).
- Which events: "Let me select individual events":
- Pull requests
- Issues
- Workflow runs
- Pushes
- Active: an.
- Add webhook.
- Bridge starten mit dem gleichen Secret als
GITHUB_WEBHOOK_SECRETenv-var. - GitHub liefert sofort einen
ping-Event — pruefe die action-log Datei:Erwartet:tail -1 ~/kb/ops/agent-actions/$(date -u +%Y-%m-%d).jsonl | python3 -m json.tool
"action": "github.webhook.ping","success": true.
cloudflared tunnel --url http://localhost:8190
# Tunnel-URL als "Payload URL" oben eintragen.classify_event(event_type, payload) ist die zentrale Decision-Funktion.
Aenderungen an der Routing-Matrix gehen ueber diese Funktion + neuer Test
(Tests sind die Single-Source-of-Truth fuer die Matrix).
# Pruefe Hash-Chain-Integritaet der heutigen Webhook-Logs:
python3 ~/code-aie/aie-action-log-writer/src/action_log_writer.py --verify \
~/kb/ops/agent-actions/$(date -u +%Y-%m-%d).jsonl| Kriterium | Status |
|---|---|
| Code geschrieben | ✅ |
| Tests gruen (lokal) | ✅ 14/14 |
| Lauffaehig (uvicorn :8190) | ✅ |
| Reproduzierbar (Dockerfile + compose) | ✅ |
| Bedienbar (Joe-Klick-Sektion + Quick-Start) | ✅ |
In AI-Engineering-at Org gepusht |
✅ |
| GitHub Org Webhook konfiguriert | ⏳ Joe-Klick |
| Auf .82 deployed | ⏳ phase-N+1 |
Reife-5 (Mac-LIVE-fertig) erreicht. Reife-6 (1.Bekannter bedient ohne Coaching) erst nach Org-Webhook-Konfig + .82-Deploy.
Proprietary — siehe LICENSE. Internal infrastructure tooling.