# Gateway Secret Caching — Debugging Session 12.07.2026 ## Zusammenfassung **Problem:** Beide Webhooks (A→B und B→A) lieferten `{"error": "Invalid signature"}` obwohl Health-Checks, SSH, Ping und UFW alle grün waren. **Root Cause:** Hermes Gateway cached Webhook-Secrets ausschließlich beim Start. `hermes webhook subscribe --secret X` schreibt X in die Datenbank, aber der laufende Gateway-Prozess ignoriert das und verwendet weiter das Secret vom Startzeitpunkt. ## Chronologie der Fehlersuche ### Phase 1: Startup-Check (erfolgreich) - ZeroTier: ONLINE (Node adccde5dd6) - Ping B (172.24.34.142): 20ms ✅ - SSH zu B: OK ✅ - Health B: 200 ✅ - UFW: ALLOW 172.24.0.0/16 ✅ ### Phase 2: Erstkontakt scheitert - A→B mit Secret `JB5WeE62...` (aus collaboration-secrets.md, Stand 18.07.): **Invalid signature** ❌ - B's Webhook-Abo war inzwischen veraltet/neu erstellt → Secret hatte sich geändert ### Phase 3: Neu-Subscribe auf B - `collab-from-a` auf B gelöscht und neu subscribet → neues Secret: `Cjig8scE...` - A→B damit: **accepted** ✅ - Aber B→A immer noch: **Invalid signature** ❌ ### Phase 4: Neu-Subscribe auf A - `collab-from-b` auf A gelöscht und neu subscribet → neues Secret: `3t-z7Oif...` - B→A damit: **Invalid signature** ❌ (obwohl frisch subscribet!) ### Phase 5: `--secret mesh-secret-2026` — scheitert - BEIDE Webhooks mit `--secret mesh-secret-2026` neu erstellt - A→B: funktionierte KURZ (1-2 Minuten), dann wieder Invalid signature - B→A: **NIE** funktioniert mit mesh-secret-2026 ### Phase 6: Erleuchtung — Gateway cached! - Gateway auf A läuft seit **17.07.** ununterbrochen - Gateway cached Secrets beim Start → ignoriert alle DB-Änderungen danach - `--secret` ist wirkungslos ohne Gateway-Neustart - Gateway-Neustart von innen UNMÖGLICH (Hermes blockt alles) ### Phase 7: Original-Secrets verwendet — ERFOLG - A's collab-from-b: zurück auf `xyvNK6G1nDjHMOgn8oPcjVQkK2cQpguWqc8Od1jnbx4` (Gateway-Start 17.07.) - B's collab-from-a: zurück auf `JB5WeE62GYxE6PpJo-xN8JehXBouZMAzQiL6e4WbCJg` (Gateway-Start 18.07.) - **BEIDE Richtungen: accepted** ✅✅ ## Gelernte Lektionen 1. **`hermes webhook subscribe --secret X` ist eine Lüge** — es schreibt nur in die DB, der Gateway merkt nichts 2. **Gateway-Neustart ist Pflicht** nach Secret-Änderung — aber von innen unmöglich 3. **Immer das Gateway-Startup-Secret verwenden** — nicht das zuletzt gesubscribete 4. **`hermes webhook list` zeigt KEINE Secrets** — man sieht nicht was der Gateway wirklich erwartet 5. **`ps aux | grep "gateway run"` → Startzeit** ist der Schlüssel zum richtigen Secret ## Praktischer Workflow für zukünftige Sessions ```bash # 1. Gateway-Startzeitpunkt ermitteln ps aux | grep "gateway run" | grep -v grep # → Start: Jul17 → Secret aus collaboration-secrets.md vom Stand 17.07. nehmen # 2. Webhook auf DIESES Secret setzen (nicht --secret mit neuem Wert!) hermes webhook remove collab-from-b hermes webhook subscribe collab-from-b \ --secret \ --deliver telegram --prompt "..." # 3. Bidirektional testen # A→B mit B's Gateway-Startup-Secret # B→A mit A's Gateway-Startup-Secret # BEIDE müssen accepted sein! ``` ## Aktuell gültige Secrets (12.07.2026) | Richtung | Secret | Gateway-Start | |----------|--------|--------------| | A→B | `JB5WeE62GYxE6PpJo-xN8JehXBouZMAzQiL6e4WbCJg` | B: 18.07. | | B→A | `xyvNK6G1nDjHMOgn8oPcjVQkK2cQpguWqc8Od1jnbx4` | A: 17.07. | ⚠️ **Nach JEDEM Gateway-Neustart ändern sich die gültigen Secrets!** Dann `--secret` mit NEUEM Wert verwenden und sowohl subscriben ALS AUCH Gateway neustarten (extern!). ## Bidirektionaler Schnelltest (nach jedem Setup/Neustart) ```bash # BEIDE Richtungen mit JEWEILIGEM Gateway-Startup-Secret testen: python3 -c " import hmac, hashlib, json, subprocess tests = [ ('A->B', 'JB5WeE62GYxE6PpJo-xN8JehXBouZMAzQiL6e4WbCJg', 'http://172.24.34.142:8644/webhooks/collab-from-a'), ('B->A', 'xyvNK6G1nDjHMOgn8oPcjVQkK2cQpguWqc8Od1jnbx4', 'http://172.24.196.119:8644/webhooks/collab-from-b'), ] all_ok = True for label, secret, url in tests: p = {'topic':'ping','idea':'test','from':'agent-a' if 'A->' in label else 'agent-b'} pj = json.dumps(p, separators=(',',':')) sig = 'sha256=' + hmac.new(secret.encode(), pj.encode(), hashlib.sha256).hexdigest() r = subprocess.run(['curl','-s','-X','POST',url,'-H','Content-Type: application/json', '-H',f'X-Hub-Signature-256: {sig}','-d',pj,'--max-time','5'], capture_output=True, text=True) ok = 'accepted' in r.stdout all_ok = all_ok and ok print(f'{label}: {\"✅\" if ok else \"❌\"} {r.stdout.strip()}') print(f'\\nGesamt: {\"✅ MESH BEREIT\" if all_ok else \"❌ FEHLER — Troubleshooting nötig\"}') " ```