Einer Browser-Erweiterung sicher Hermes' Browser-Tools überlassen: Der Guide zum authentifizierten Controller

Du hast eine Seite in deinem Browser offen und möchtest, dass Hermes sie für dich bearbeitet – das Formular ausfüllt, durch Seiten blättert, Beweise per Screenshot festhält. Die alte Antwort war, es auf ein „Browser-Backend“ zu zeigen: einen Cloud-Browser oder lokales CDP. Aber der Tab, den du tatsächlich benutzt, und das „Browser-Backend“, das Hermes startet, sind zwei verschiedene Dinge. Die ideale Form ist: Die Browser-Erweiterung, die du installiert hast, wird zum Steuerkanal, sodass der Agent genau die Seite vor dir bedient. Das wirft allerdings eine scharfe Sicherheitsfrage auf – warum sollte man einer Erweiterung vertrauen, und wo genau liegt die Grenze dessen, was sie darf?
Die Antwort von Hermes ist eine authentifizierte Spur namens Browser-Erweiterungs-Controller: Eine Erweiterung registriert sich über ein Einmal-WebSocket-Ticket als exakter Controller für die browser_*-Tools einer Sitzung, und Fähigkeiten werden durch eine strenge Allowlist gefiltert – kein rohes CDP, keine beliebige Skriptauswertung, kein Konsolenzugriff. Einmal gebunden, schlägt sie Fail-closed fehl: Ein fehlender, mehrdeutiger, getrennter oder unfähiger Controller lässt den Aufruf fehlschlagen, statt still auf ein anderes Browser-Backend umzuschalten. Das Feature landet in PR #91535 (eine Rettung von #85351 mit den Cherry-picked-Commits des ursprünglichen Autors, die erhalten bleiben), gemergt in main upstream – in keinem Release-Tag bisher.
Warum überhaupt eine „Controller“-Spur?
Hermes’ Browser-Tools (browser_navigate, browser_click, browser_snapshot, …) sitzen auf mehreren Backends: Browserbase Cloud, Browser Use, lokales Chromium-CDP, Camofox … – alle sind „ein Browser, den Hermes selbst startet“. Aber der Browser, den du benutzt, ist eine andere Spezies: nicht von Hermes gestartet, sondern die Instanz, die du jeden Tag bedienst.
Der Erweiterungs-Controller füllt genau diese Lücke: Die Erweiterung hält deinen echten Browser-Tab, Hermes sendet browser_*-Befehle über einen authentifizierten WebSocket-Kanal, und die Erweiterung führt sie in der echten Seite aus und meldet zurück. Befehle, Fähigkeiten und Eigentümerschaft werden alle durch eine serverseitige Allowlist und Einmal-Tickets begrenzt.
Die Konfiguration aktivieren
Das Feature ist standardmäßig aus und muss per Opt-in aktiviert werden – und der lokale API-Pfad erfordert zusätzlich den Bearer-Key des API-Servers:
browser:
extension_control:
enabled: true
Ein Controller darf sich nur für eine bestehende Server-Sitzung registrieren; das Controller-Prinzipal wird aus dem authentifizierten Serverzustand abgeleitet, und eine clientgelieferte principal_id wird ignoriert – Identität ist nichts, was der Client deklarieren darf.
Die Fähigkeiten-Allowlist: 11 Punkte, kein nacktes CDP
GET /v1/capabilities zeigt, ob das Feature aktiviert ist, die Protokollversion, die Transportnamen und die exakte Fähigkeiten-Allowlist:
controller.noop
browser_back
browser_click
browser_navigate
browser_press
browser_screenshot
browser_scroll
browser_snapshot
browser_tab_activate
browser_tabs
browser_type
Angeforderte Fähigkeiten außerhalb dieser Liste werden herausgefiltert. Beachte den bewussten Trade-off: rohes CDP, beliebige Skriptauswertung, Konsolenzugriff, Uploads, Bildextraktion und Vision sind nicht Teil des Controller-Protokolls – die Erweiterung kann dem Agenten beim Klicken, Tippen, Scrollen und Screenshotten helfen, aber kein beliebiges JavaScript in der Seite ausführen. Das ist eine bewusst enge Sicherheitsgrenze: fähig, aber nicht beängstigend.
Registrierung und Verbinden: Einmal-Ticket, 30-Sekunden-TTL
Der Ablauf besteht aus drei Schritten (lokale API-Registrierung):
- Sende ein authentifiziertes
POST /v1/browser-control/registermitprotocol_version,session_id,controller_id,browser_profile_idund den angefordertencapabilities; - Hermes gibt ein Einmal-Ticket (30-Sekunden-TTL) mit dem gefilterten, serverseitig gebundenen Controller-Bereich zurück;
- Öffne
GET /v1/browser-control/wsmit beiden WebSocket-Subprotokollen:hermes-browser-control-v1undhermes-browser-control-ticket.<ticket>.
Das Ticket wird nie in der Query-String akzeptiert; unbekannte, abgelaufene, wiederverwendete oder fehlerhafte Tickets scheitern vor dem WebSocket-Upgrade. Nach dem Verbinden sendet Hermes browser.controller.command-Frames (mit command_id, action, unveränderlichen arguments und der ursprünglichen tool_call_id), und der Controller antwortet mit browser.controller.result (gleiche command_id, exaktes boolesches ok und entweder result oder error). Abbruch und Timeouts erzeugen browser.controller.cancel; verspätete Ergebnisse werden ignoriert.
Fail-closed: kein stiller Browser-Wechsel nach der Bindung
Das ist der Teil, den man am stärksten betonen sollte:
- Mit keiner gebundenen Controller-Identität oder wenn das Feature deaktiviert ist → Hermes behält das bestehende Browser-Backend bei;
- Sobald das Gateway ein Controller-Prinzipal und eine Transportfamilie an die Anfrage bindet, ist diese Erweiterungs-Spur maßgeblich: fehlende, mehrdeutige, getrennte oder unfähige Controller schlagen Fail-closed fehl, statt still auf einen anderen lokalen oder Cloud-Browser umzuschalten;
- Nach der Auswahl eines exakten Controllers ist sein Ergebnis oder Fehler maßgeblich, und Hermes wiederholt dieselbe Aktion nie über ein anderes Backend.
Mit anderen Worten: Eine „Steuere diesen Tab“-Sitzung springt nie still hinter deinem Rücken zu einem Cloud-Browser. Ein unerwarteter Socket-Verlust wird als behebbare Trennung behandelt (laufende Arbeit überlebt bis zum Deadline jedes Befehls); ein explizites browser.controller.detach auf dem authentifizierten Transport ist die harte Trennung und bricht laufende Arbeit sofort ab. Eine andere Controller-ID oder ein anderes Browser-Profil in derselben authentifizierten Sitzungsspur ist ein harter Ersatz: Alte laufende Arbeit wird abgebrochen, bevor der Nachfolger routbar wird.
Aktueller Status und wie du es ausprobierst
- Code:
feat(browser): authenticated extension controller (salvage #85351), PR #91535, gemergt inmainam 21.08.2026. - Release-Status: noch in keinem Release-Tag – das Tag v2026.8.19 von v0.20.5 wurde vor diesem Merge geschnitten. Es lebt derzeit nur auf
main; sobald es mit einem künftigen Release mitkommt, bekommst du es perhermes update. - Begleitender Ablauf: Der Loopback-Pairing-Ablauf der Browser-Erweiterung (PR #88203, die „ein Genehmigungsklick für ein gescopetes Token“-Gateway-Hälfte) ist noch offen – die Installieren-und-Klicken-zum-Genehmigen-Erfahrung ist also noch nicht gemergt; vorerst gehst du selbst durch die API-Server-Auth und den Register-Ablauf.
Zum Ausprobieren: Besorge dir einen Build von main, der den PR enthält, aktiviere browser.extension_control.enabled, konfiguriere den Bearer-Key des API-Servers und nutze deinen bevorzugten WebSocket-Client, um einen Test-Controller gemäß den drei Schritten oben zu registrieren – beginne mit controller.noop, um den Kanal zu validieren. Mehr zur Auswahl und den Modi der Browser-Backends findest du in unserem Browser-Use-CLI-3.0-Modus-Guide und im Desktop-Read-Preview-Browser-Guide.
Der eigentliche Wert dieses Features ist nicht „noch eine Verbindungsmöglichkeit“ – es ist, dass der Browser, den du tatsächlich benutzt, zum ersten Mal eine sicher steuerbare Ausführungsumgebung für den Agenten wird: Die Allowlist verkleinert die Angriffsfläche, das Einmal-Ticket blockiert Replay, und Fail-closed macht stilles Backend-Driften unmöglich. Wenn der Pairing-Ablauf landet, installierst du die Erweiterung, klickst auf Genehmigen, und Hermes arbeitet in der Seite vor dir.