Cron fragt: „Ist es Zeit?“ Webhooks melden: „Das ist gerade geschehen, jetzt handeln.“ Bei der Arbeit mit Agenten ist dieser Unterschied entscheidend. Ein planmäßiges Durchsuchen des Posteingangs ist etwas anderes als „ein Stripe-Streitfall wurde erstellt“ oder „ein Pull Request gegen main wurde geöffnet“.
Hermes-Agent-Webhooks verwandeln authentifizierte HTTP-POST-Ereignisse in Agentenläufe, deren Ergebnisse an ein konfiguriertes Ziel zugestellt werden. Richtig eingesetzt sind sie kleine, verschlossene Türen mit klaren Aufgaben. Schlecht eingesetzt sind sie ein offener Port mit einem Mega-Prompt, der versucht, jedes JSON-Paket zu verarbeiten, das aus dem Internet eintrifft.
Dieser Artikel behandelt Routendesign, anbietergerechte Authentifizierung, den dokumentierten Health-Check und einen praktischen Smoke-Test. Kombinieren Sie ihn mit der Härtung der ersten Woche in /articles/hermes-first-week-memory-and-skills, bevor Sie etwas über localhost hinaus freigeben.
Wann Webhooks der richtige Trigger sind
Bevorzugen Sie Webhooks, wenn:
- Eine kurze Reaktionszeit wichtig ist (prüfen Sie einen PR, während der Autor gedanklich noch beim Thema ist).
- Das Quellsystem bereits Ereignisse aussendet (GitHub, GitLab, Jira, Stripe, interne Formulare).
- Jedes Ereignis zu einer fokussierten Aufgabe werden soll, nicht zu einer langen Konversation.
Bevorzugen Sie Cron, wenn:
- Sie auf Drift prüfen („läuft in 14 Tagen ein Zertifikat ab?“).
- Die Quelle keine Ereignisse senden kann.
- Sie lieber eine ruhige regelmäßige Zusammenfassung als Unterbrechungen bei jedem Ereignis möchten.
Die offizielle Hermes-Richtlinie entspricht dieser Aufteilung: Cron für geplante Prüfungen und Webhooks für ereignisgesteuerte Läufe.
Architektur in einem Bild
Quellsystem (GitHub / GitLab / n8n / eigene App)
| HTTPS POST + anbietergerechte Authentifizierung
v
Hermes-Webhook-Adapter (Standardport 8644)
| Route: /webhooks/<name>
v
Benannte Routenkonfiguration (Filter + Prompt + Zustellung)
v
Agentenlauf (Skills/Tools gemäß Ihrer Freigaberichtlinie)
v
Konfigurierte Zustellung (Chat-Kanal, GitHub-Kommentar oder Log)
n8n kann links als Validierungs- und Sammelschicht dienen: Felder validieren, irrelevante Daten verwerfen und anschließend eine minimierte Payload per POST an Hermes senden. Dies ist eine beispielhafte Architektur aus /articles/hermes-vs-n8n-choose-by-job, keine dokumentierte, sofort einsatzbereite Anbieterintegration. Wenn n8n das Ergebnis des Agenten im eigenen Workflow benötigt, rufen Sie den separaten Hermes-API-Server auf dem Standardport 8642 mit Bearer-Authentifizierung auf, statt den Webhook-Adapter wie einen synchronen Callback zu behandeln.
Einrichtungsweg (mit aktueller Dokumentation abgleichen)
Die Upstream-Webhook-Dokumentation beschreibt diesen Pfad:
- Aktivieren Sie die Webhook-Plattform (
hermes gateway setupoder Umgebungsvariable wieWEBHOOK_ENABLED=true). - Konfigurieren Sie für jede Route ein Secret. Verwenden Sie je nach Quelle den HMAC-Header von GitHub, den Token-Header von GitLab oder die generische V2-Methode mit zeitgestempeltem HMAC.
- Erstellen Sie eine benannte Route in der Konfiguration oder über
hermes webhook subscribe(Befehl laut aktueller Dokumentation). - Health-Check:
curl http://localhost:8644/health - Richten Sie das externe System auf
https://your-host/webhooks/<name>aus. - Senden Sie eine authentifizierte Test-Payload und prüfen Sie, ob Route, Prompt, Toolumfang und Zustellziel den Erwartungen entsprechen.
Der dokumentierte Standardport ist 8644. Die dokumentierten Voreinstellungen begrenzen eine Route außerdem auf 30 Anfragen pro Minute und lehnen Request-Bodies über 1 MB ab. Wenn Sie diese Werte geändert haben, testen Sie die tatsächlich konfigurierten Grenzen, statt sich auf die Voreinstellungen zu verlassen.
Statische Konfigurationsänderungen können die in Ihrer installierten Version dokumentierten Schritte zum Neustart oder Neuladen des Gateways erfordern. Dynamische Routen, die mit
hermes webhook subscribeerstellt werden, werden ohne Neustart neu geladen und erhalten ein automatisch generiertes Secret. Prüfen Sie in beiden Fällen, ob der Gateway-Prozess das vorgesehene Profil und die richtige Umgebung verwendet. Ein erfolgreicher Befehl in einer interaktiven Shell beweist nicht, dass der Daemon dieselbe Konfiguration hat.
Routenauthentifizierung ist Pflicht
Jede Route muss ein Secret erben oder selbst definieren, sonst schlägt der Adapter beim Start fehl. Die Authentifizierung ist anbieterspezifisch: GitHub verwendet X-Hub-Signature-256, GitLab den exakt abzugleichenden Header X-Gitlab-Token, und benutzerdefinierte Sender sollten die generische V2-Methode mit zeitgestempeltem HMAC verwenden. Die Absenderauthentifizierung weist nach, dass die Anfrage von jemandem mit Zugriff auf das Secret stammt; sie macht Anweisungen in der Payload nicht vertrauenswürdig.
Regeln, die im Produktivbetrieb standhalten:
- Generieren Sie ein langes zufälliges Secret; speichern Sie es in einem Secrets-Manager oder einer Umgebungsdatei mit restriktiven Berechtigungen, niemals in einer Skill-Markdown-Datei, die der Agent beiläufig lesen kann.
- Bevorzugen Sie ein eigenes Secret pro Route, wenn Systeme unterschiedliche Vertrauensstufen haben (GitHub-App gegenüber internem Formular oder Partner-Webhook).
- Lehnen Sie Anfragen mit fehlender oder ungültiger Signatur am Netzwerkrand ab; „protokollieren und weitermachen“ ist nicht akzeptabel.
- Verwenden Sie
INSECURE_NO_AUTHnur für temporäre Loopback-Tests. Der Adapter verweigert den Start, wenn dieser Wert mit einem Nicht-Loopback-Bind wie0.0.0.0oder einer LAN-Adresse kombiniert wird.
Verwenden Sie für benutzerdefinierte Sender die aktuelle generische V2-Methode von Hermes: X-Webhook-Timestamp enthält Unix-Sekunden; X-Webhook-Signature-V2 enthält den hexadezimalen HMAC-SHA256-Digest von <timestamp>.<raw-body> in Kleinbuchstaben. Hermes lehnt Zeitstempel außerhalb eines Fensters von ±300 Sekunden ab. V1 signiert nur den Request-Body und bietet keinen Schutz vor wiederholten Anfragen. Entwickeln Sie deshalb keine neuen Sender auf dieser Grundlage (offizieller Webhook-Sicherheitsvertrag).
Reproduzierbarer signierter Smoke-Test
Legen Sie nach dem Erstellen einer Route namens support-triage eine nicht sensible Payload in payload.json ab. Sorgen Sie dafür, dass Ihr freigegebener Mechanismus zur Secret-Bereitstellung WEBHOOK_SECRET setzt, bevor diese Shell startet; tippen Sie kein produktiv genutztes Secret in die Befehlshistorie. Der folgende Node-Befehl liest den Schlüssel aus der Umgebung, statt ihn in die Prozessargumente einzusetzen, und signiert die exakten Dateibytes:
: "${WEBHOOK_SECRET:?inject a disposable route secret before running this test}"
timestamp="$(date +%s)"
signature="$(TIMESTAMP="$timestamp" node -e '
const { createHmac } = require("node:crypto");
const { readFileSync } = require("node:fs");
const hmac = createHmac("sha256", process.env.WEBHOOK_SECRET);
hmac.update(`${process.env.TIMESTAMP}.`, "utf8");
hmac.update(readFileSync("payload.json"));
process.stdout.write(hmac.digest("hex"));
')"
curl --fail-with-body \
-H 'Content-Type: application/json' \
-H "X-Webhook-Timestamp: $timestamp" \
-H "X-Webhook-Signature-V2: $signature" \
--data-binary @payload.json \
http://127.0.0.1:8644/webhooks/support-triage
Wiederholen Sie den Test anschließend einmal ohne die beiden Signatur-Header und einmal mit einem Zeitstempel, der älter als 300 Sekunden ist. Beide Anfragen müssen abgewiesen werden. Fügen Sie kein echtes Secret in Screenshots, Tickets oder die Shell-Historie ein. Verwenden Sie für Dokumentationstests ein temporäres Routen-Secret und wechseln Sie es danach aus.
Ein öffentlich erreichbarer Webhook, der von Angreifern kontrollierten Text an einen Agenten mit Terminalzugriff weiterreichen kann, schafft das Risiko einer entfernten Toolausführung. Die Authentifizierung begrenzt, wer Ereignisse einreichen kann, doch auch authentifizierte Payload-Texte können bösartig sein. Verwenden Sie TLS und Netzwerkkontrollen, minimieren Sie Payloads, beschränken oder deaktivieren Sie Tools für Terminal, Dateien und ausgehende Aktionen und isolieren Sie die Ausführung vom Host. Freigabeprompts schützen die beabsichtigten Bedienhandlungen; sie sind keine Sandbox gegen feindliche Eingaben.
Was in die Payload gehört
Senden Sie dem Agenten einen klaren Vertrag, keinen ungefilterten Datenstrom:
{
"event_type": "github.pull_request.opened",
"repo": "acme/api",
"pr_number": 1842,
"title": "Add billing retry worker",
"author": "ada",
"base_ref": "main",
"html_url": "https://github.example.invalid/acme/agent-service/pull/1842",
"task": "Summarize risk for main. List missing tests. Do not approve or merge."
}
Entfernen Sie ungenutzte Felder. Umfangreiche Workflow-Dumps verschwenden Kontext und fördern ungezielte Toolaufrufe. „Kleine, explizite Payloads mit einer klaren Aufgabe“ ist die Designempfehlung dieses Artikels, keine Behauptung über eine offizielle n8n-Integration.
Routendesign: viele kleine Türen
Bauen Sie nicht /webhooks/everything. Bauen Sie benannte Routen mit Filtern und Prompts:
| Routenname | Quelle | Aufgabe | Zustellung |
|---|---|---|---|
gh-pr-opened | GitHub PR geöffnet | Risikoübersicht + Testlücken | Telegram-Thema des Engineering-Teams |
stripe-dispute | Stripe-Streitfall erstellt | Checklistenentwurf | Finance-Slack + Log |
support-form | n8n nach Validierung | Klassifizieren + Antwortentwurf | Konfigurierter privater Slack-Kanal |
uptime-alert | Monitoring-Webhook | Kontext zu jüngsten Deployments sammeln | Bereitschaftskanal |
Jede Route sollte beantworten:
- Welche Ereignisse werden akzeptiert?
- Was ist die einzige erwartete Ausgabe?
- Welche Tools sind für das Agent-Profil dieser Route erlaubt?
- Wohin geht das Ergebnis?
- Was geschieht bei einem Fehler (Wiederholung? Dead-Letter-Queue? Einen Menschen benachrichtigen?)?
Webhook-Payloads enthalten häufig E-Mail-Adressen, Konto-IDs oder Nachrichtentexte. Reduzieren Sie die Felder, bevor sie Hermes erreichen. Das Routenschema dokumentiert keinen routenspezifischen Schalter für Schreibvorgänge ins Gedächtnis. Verwenden Sie ein eigenes Profil mit deaktiviertem Gedächtnis oder aktivierter
memory.write_approvalund testen Sie, was dauerhaft gespeichert wird. Wenn keine Schlussfolgerungen durch einen Agenten nötig sind, verwenden Sie den dokumentierten Modusdeliver_only, statt einen Agenten auszuführen.
Health-Checks und Betrieb
Dokumentierter Health-Endpunkt: http://localhost:8644/health (oder Ihr Host/Port). Verwenden Sie ihn für:
- Lokale Smoke-Tests nach der Aktivierung
- Docker/Kubernetes Readiness-Probes
- Externe Uptime-Checks gegen eine private Health-URL, nicht gegen eine unauthentifizierte Webhook-Route
Protokollieren Sie außerdem:
- Signaturfehler (möglicher Angriff oder falsch konfiguriertes Geheimnis)
- Fehler bei der Payload-Validierung
- Dauer des Agentenlaufs und verweigerte Toolfreigaben
- Fehler bei der nachgelagerten Zustellung (etwa eine ausgefallene Chat-API)
Ohne diese Signale bleibt „der Agent wirkte unzuverlässig“ Ihr einziger Vorfallbericht. Diese Aufzeichnungen verbessern die Beobachtbarkeit; sie bilden nicht automatisch einen vollständigen, manipulationssicheren Audit-Trail.
Beispiel: GitHub PR geöffnet → gezielter Lauf
Ziel: Wenn ein PR gegen main geöffnet wird, entwirft Hermes eine Risikoeinschätzung für Menschen. Er führt weder einen Merge noch eine Genehmigung oder einen Kommentar aus, sofern Sie später nicht ausdrücklich einen geprüften Zustellweg hinzufügen.
- Erstellen Sie die Route
gh-pr-opened. Für die direkte GitHub-Zustellung konfigurieren Sie das gemeinsame Geheimnis zur Überprüfung vonX-Hub-Signature-256; für ein generisches n8n-Relay implementieren Sie den V2-Zeitstempel-HMAC-Vertrag. - Filtern auf
pull_request/opened/ Basemain. - Prompt-Vertrag: Zweck, Auswirkungsradius, fehlende Tests und Rollout-Risiko zusammenfassen; Unbekanntes markieren; keine Merge-Anweisungen.
- Tools: schreibgeschützter GitHub-Abruf, falls konfiguriert; Shell deaktiviert oder freigabepflichtig.
- Zustellung: Markdown in einen internen Kanal posten; der Mensch entscheidet die nächsten Schritte.
Beispiel für den Aufbau einer guten Agentenausgabe (die Struktur ist illustrativ; die Formulierungen Ihres Modells werden abweichen):
PR #1842: Worker für erneute Abrechnungsversuche hinzufügen (ada nach main)
Fakten
- Betrifft den Abrechnungs-Worker und die Warteschlangenkonfiguration (laut Titel und Dateiliste).
- Verlinkte URL: `https://github.example.invalid/acme/agent-service/pull/1842` (illustrativ)
Risiken
- Stürme erneuter Versuche, falls Backoff fehlt [inference; verify in diff]
- Keine Erwähnung von Idempotency-Keys im Titel [unclear]
Fehlende Tests zur Bestätigung
- Verhalten bei doppelter Zustellung oder schädlichen Warteschlangennachrichten
- Alarmierung, wenn das Budget für erneute Versuche erschöpft ist
Nicht auf Grundlage dieser Notiz zusammenführen. Menschliche Prüfung erforderlich.
Das ist ein ereignisgesteuerter Agentenlauf mit einer Stoppregel. Er ist kein autonomer Code Owner.
Übung: Entwerfen Sie drei Routen, bevor Sie eine aktivieren
Schreiben Sie auf Papier (oder in Ihrem Runbook) drei Webhook-Routen für Ihren Stack. Füllen Sie für jede aus:
- Name
- Quelle + Ereignisfilter
- Authentifizierungsmethode und Geheimnisbesitzer
- Payload-Felder: Beginnen Sie mit höchstens 10, als bewusst kleinem Übungsumfang
- Prompt: Beginnen Sie mit höchstens 8 Zeilen und fügen Sie nur hinzu, was die Evaluationen der Route erfordern
- Erlaubte Tools
- Zustellungsziel
- Fehlerverhalten
Implementieren Sie zuerst nur die risikoärmste Route, meist eine interne Warnung oder eine PR-Zusammenfassung als reinen Entwurf. Führen Sie zunächst curl gegen /health aus, senden Sie dann einen authentifizierten Test-POST und einen Test mit ungültiger Authentifizierung und lösen Sie schließlich ein echtes Ereignis in einem nicht produktiv genutzten Repository oder Staging-Projekt aus.
Fehlermodi, die Sie erwarten sollten
- Secret stimmt nach dem Wechsel nicht überein: Die Authentifizierung schlägt fehl; korrigieren Sie die vom Gateway-Prozess verwendete Umgebung, nicht nur die Shell auf Ihrem Laptop.
- Zu breiter Prompt: Der Agent improvisiert bei der Toolnutzung; teilen Sie die Route auf.
- Wiederholungsstürme: Die Quelle sendet POST-Anfragen erneut. Hermes speichert Zustell-IDs eine Stunde lang zwischen, doch eine wirksame Deduplizierung erfordert eine stabile
X-GitHub-DeliveryoderX-Request-ID. Für kundensichtbare Aktionen ist weiterhin dauerhafte fachliche Idempotenz nötig, deren Aufbewahrungszeit zum Wiederholungsfenster passt. - Verschmutztes Gedächtnis: Eine große Zahl von Warnungen gelangt ins persistente Gedächtnis; verwenden Sie ein eigenes Profil und explizite Gedächtniseinstellungen.
- Öffentlich erreichbarer Port: Health- und Webhook-Endpunkte sind ohne die vorgesehenen TLS- und Netzwerkkontrollen erreichbar; sichern Sie das Netzwerk, bevor Sie Tools hinzufügen.
Referenzen, die offen bleiben sollten
- Hermes-Webhook-Adapter
- Hermes-API-Server
- Hermes-Sicherheitsmodell
- Hermes-Dokumentation
- Intern: /articles/first-ai-agent-in-n8n, /articles/hermes-vs-n8n-choose-by-job
Ereignisgesteuerte Agenten lohnen sich, wenn jede Route klar eingegrenzt, authentifiziert und beobachtbar ist und ein konfiguriertes Zustellziel besitzt. Der Webhook-Adapter ist der Eingang für Ereignisse, nicht die mit Bearer-Token authentifizierte Request/Response-API. Entwerfen und testen Sie ihn entsprechend.



