Du hast einen hermes dump zum Helfen eingefügt — und darin steckte dein eigener API-Key

Es ist 1 Uhr nachts, dein cron-Job ist schon wieder fehlgeschlagen, also machst du, was du immer machst: hermes dump ausführen, das Ganze mit ein paar Logzeilen in einen Discord-Thread einfügen und um Hilfe bitten. Eine halbe Stunde später schreibt dir jemand eine DM — „hey, dein OpenRouter-Key steht noch im ersten Block.“
Das ist kein hypothetischer Fall. hermes dump existiert genau dafür, „eine kompakte Klartext-Zusammenfassung deines Setups zu erzeugen, die sich in Discord/GitHub kopieren lässt“ — und genau der Teil, der am einfachsten einzufügen war, hat früher den API-Key jedes Fallback-Providers im Klartext ausgegeben. Der Fix (PR #127207, aufgebaut auf #126132 und #126168) ist am 2026-09-29 auf main gelandet und hat die Redaktion von einem einzigen Durchlauf beim Upload auf zwei Durchläufe umgestellt: einen bei der Erzeugung des dumps, einen beim Verlassen des Rechners.
Zuerst: Wissen, was du tatsächlich teilst
Hermes kennt zwei Wege zum Teilen, und sie verschwimmen leicht miteinander:
hermes dumpgibt eine Konfigurationszusammenfassung aus, die zum Kopieren gedacht ist. Standardmäßig zeigt sie den Zustand eines Keys als gesetzt/nicht gesetzt an;--show-keyszeigt die ersten und letzten vier Zeichen.hermes debug sharepackt Logs zusammen (standardmäßig die letzten 200 Zeilen pro Logdatei), lädt sie zu einem Paste-Dienst hoch und gibt einen Link aus.
Der zweite Befehl verdient einen genauen Blick:
--lines LINES Lines included per log file (default: 200)
--expire EXPIRE dpaste.com fallback retention in days (minimum 1; default 1)
--local Print the report locally instead of uploading
-y, --yes Skip confirmation and upload (required in scripts/CI)
--no-redact Disable upload-time secret redaction
--nous Upload to Nous-internal storage (AWS S3), not a public paste
Wohin das Bundle gelangt, verändert den Schadenradius vollständig:
| Ziel | Sichtbarkeit | Aufbewahrung | Löschbar |
|---|---|---|---|
| paste.rs | öffentlicher Link | nach 6 Stunden gelöscht | läuft automatisch ab |
| dpaste.com (Fallback) | öffentlicher Link | Anzahl der Tage aus --expire (Standard 1) |
kann nicht gelöscht werden |
--nous (S3) |
nur Nous-Mitarbeiter und allowlistete Mods, hinter einem Viewer mit Google-Login | 14 Tage | läuft automatisch ab |
Ein öffentlicher Paste gibt dir also ein Fenster von sechs Stunden, und wenn der Upload auf dpaste zurückfällt, bleibt der Link so lange bestehen, wie du es bei der Aufbewahrung angefordert hast — und du kannst ihn nicht entfernen. Das vor dem Drücken der Eingabetaste zu entscheiden, ist weit mehr wert als jede Bereinigung danach.
Was schiefging: str() auf einem Objekt mit einem Key
Die Ursache ist fast banal. Ein Block im dump hat die Liste der Fallback-Provider wie jedes andere Objekt gerendert:
overrides["fallback_providers"] = str(fallbacks)
str() hat brav das api_key-Feld jedes Eintrags mit expandiert, dazu alle in seiner base_url eingebetteten Zugangsdaten (denk an https://user:token@gateway). Dann kam die zweite Ebene: _capture_dump() hat das Bundle ganz ohne Redaktion zurückgegeben — die Redaktion beim Upload lief nur über die Log-Snapshots, also reiste der Konfigurationsabschnitt nackt.
Du kannst ein Bundle, das du schon hast, mit einem einzigen grep prüfen (führe ihn nur nicht in einem öffentlichen Kanal aus):
hermes dump | grep -n -i "api_key\|base_url\|token\|signature"
Wenn du einen vollständigen api_key: sk-...-Wert siehst statt ***, ist dieses Bundle nicht sicher zu veröffentlichen.
Nach dem Fix: zwei erzwungene Durchläufe und drei Formen, die früher durchgerutscht sind
Der Patch macht drei Dinge, und jedes einzelne erklärt, warum das Einfügen wieder sicher ist.
Erstens: Der dump wird schon bei seiner Erzeugung redigiert. Einträge von Fallback-Providern durchlaufen jetzt zuerst eine Maskierung auf Feldebene und dann einen erzwungenen Textdurchlauf mit strikten Regeln für URL-Zugangsdaten:
overrides["fallback_providers"] = redact_sensitive_text(
str(_mask_fallback_keys(fallbacks)), force=True, redact_url_credentials=True
)
Zweitens: Die Upload-Grenze redigiert noch einmal eigenständig. _capture_dump() erzwingt jetzt die Redaktion des dumps und berücksichtigt --no-redact — selbst wenn ein Aufrufer es vergisst, wird das Bundle vor dem Verlassen noch einmal geprüft. Cloud-Signatur-Keys sind jetzt ebenfalls erfasst: GCS X-Goog-Signature, Azure SAS sig und X-Amz-Signature zählen alle als URL-Zugangsdaten.
Drittens: Die Maskierung auf Feldebene schließt drei blinde Flecken der Textredaktion. Das ist der subtile Punkt und der nützlichste zum Verstehen. Textregeln allein haben drei api_key-Formen übersehen:
- einen Key ohne Anführungszeichen, der numerisch ist (eine YAML-Ganzzahl, kein String);
- einen Key, der als Mapping statt als Skalar geschrieben wurde;
- einen Key, der bereits
***enthielt, was der Redaktor als schon maskiert behandelt.
Daher die Reihenfolge: zuerst nach Feldnamen maskieren, dann die Einträge in Text verwandeln. Dreh die Reihenfolge um, und es leckt weiterhin.
Was du auf deiner eigenen Maschine tun solltest
Drei Gewohnheiten, auf die man sich erst nach diesem Fix verlassen kann:
- Zieh
--nouseinem öffentlichen Paste vor. Wenn jemand deine Logs lesen muss, legthermes debug share --noussie in einen Speicher, der zum Ansehen ein Login verlangt und sich nach 14 Tagen selbst löscht. Greif nur dann auf einen öffentlichen Paste zurück, wenn die andere Person keinen internen Zugang hat, und akzeptiere das Fenster von sechs Stunden. - Greif nicht beiläufig zu
--no-redact. Seine Bedeutung ist „vor dem Upload nicht redigieren“, und der Befehl gibt einen Warnbanner aus, der genau das sagt. Benutze ihn nur, wenn du den Inhalt Zeile für Zeile geprüft hast und wirklich Rohbytes brauchst (etwa um einem Token-Präfix nachzugehen, den die Maskierung verdeckt hat). - Füge den dump in Issues ein, nie
config.yaml. Der dump ist darauf ausgelegt, gesetzt/nicht gesetzt zu melden; die Konfigurationsdatei trägt alles. Es ist dieselbe Regel, die wir im Leitfaden zum Session-Export ausgeführt haben: Redaktion auf einem Export- oder Share-Weg ist der Standard, und das Einzige, was du tun musst, ist, sie nicht abzuschalten.
Anzumerken: --show-keys „zeigt deine Keys“ auch nicht — es zeigt die ersten und letzten vier Zeichen, damit du bestätigen kannst, welcher Key im Einsatz ist, und nicht, um ihn zu kopieren.
Die eigene Installation kurz prüfen
Wenn du vor Ende September ein Bundle geteilt hast, sind zwei Minuten Prüfung billig:
hermes --version # v0.21.5 oder neuer; main trägt den Fix bereits
hermes dump | grep -c "api_key: \*\*\*" # erwartet größer als 0, d. h. die Feldmaskierung ist aktiv
Wenn der erste Befehl einen älteren Build meldet, aktualisiere und prüfe erneut. Und wenn schon ein öffentlicher dpaste-Link draußen ist, ist die einzige echte Abhilfe, diesen Key beim Provider zu rotieren — genau deshalb ist Hinschauen vor dem Einfügen besser als jeder Patch.
Für den umgebenden Mechanismus — Session-Spiegel sowie Egress-Regeln für Platform-Chat und Bot-Chat — siehe den Artikel zu den Redaktions-Spuren; die vollständige Flag-Liste findest du unter hermes dump und hermes debug.
Die Kurzfassung
- Die Liste der Fallback-Provider in
hermes dumphat früherapi_key-Werte und Zugangsdaten innerhalb vonbase_urlausgegeben — wegen einesstr()-Aufrufs und eines nicht redigierten dump-Pfads. - Jetzt gibt es zwei erzwungene Durchläufe: einen bei der Erzeugung des dumps (Feldmaskierung plus strikte URL-Zugangsdaten-Regeln), einen an der Upload-Grenze (kennt
--no-redact). - Die drei Formen, die die Textredaktion übersehen hat — numerische Keys, Mapping-Keys, Keys mit
***— werden durch die Maskierung nach Feldnamen zuerst abgedeckt. - Zieh
--nous(privat, 14 Tage) für geteilte Logs vor; öffentliche Pastes geben dir sechs Stunden, und der dpaste-Fallback lässt sich nicht löschen. --no-redactbedeutet „den Schutz aufgeben“, nicht „mehr Details“. Füge den dump ein, nicht deine Konfigurationsdatei.