8 Min. Lesezeit

MCP stdio oder Unix-Sockets hängt von der Vertrauensgrenze ab

MCP stdio und Unix-Sockets für Desktop-Secret-Broker im Vergleich: Laufzeit, Rechte, Aufruferidentität, Bereinigung und Bereitstellung.

MCP stdio oder Unix-Sockets hängt von der Vertrauensgrenze ab

Ein Desktop-Secret-Broker sollte stdio verwenden, wenn die Befugnis zu einem einzelnen Agentenprozess gehört, und einen Unix Domain Socket, wenn sie zu einem gemeinsam genutzten lokalen Dienst gehört. Das klingt nach einer Transportentscheidung, doch das Übertragen von Bytes ist der einfache Teil. Schwierig ist die Entscheidung, wer eine Aktion auslösen darf, wie lange diese Erlaubnis gilt und welche Belege nach dem Absturz einer Seite übrig bleiben.

Ich habe Teams mit einem Socket anfangen sehen, weil er nach Infrastruktur aussieht. Danach haben sie wochenlang die Zuordnung des Aufrufers und die Lebenszykluskontrollen neu gebaut, die der Prozessbaum bereits lieferte. Ich habe auch erlebt, wie stdio mit Schichten aus Startern, Multiplexern und verborgenem Zustand zu einem residenten Dienst gedehnt wurde. Beide Transporte können sicher sein. Jeder von ihnen kann das Bedrohungsmodell stillschweigend aushebeln, wenn seine Annahmen über Laufzeit und Identität nicht zur gewährten Befugnis passen.

Dieser Vergleich geht von einem macOS-Desktop-Broker aus, der API- oder SSH-Zugangsdaten hält und Aktionen für lokale KI-Agenten ausführt. Der Agent darf das Secret nie erhalten. Der Broker schützt daher mehr als einen lokalen Cache: Er entscheidet, welcher Prozess gespeicherte Befugnisse in eine externe Wirkung umsetzen darf.

Wählen Sie zuerst die Vertrauensgrenze

Der passende Transport folgt aus der Autorisierungseinheit. Genehmigt ein Mensch genau einen Agentenlauf, gibt ein untergeordneter stdio-Server dieser Genehmigung eine natürliche Grenze: Die Pipe besteht für diese Prozessbeziehung und schließt, sobald eine Seite endet. Sollen mehrere Werkzeuge einen entsperrten Broker teilen, bietet ein Unix-Socket einen stabilen Treffpunkt. Der Broker muss darüber jedoch eine eigene Sitzungsgrenze errichten.

Beschreiben Sie das Bedrohungsmodell mit Akteuren und Aktionen, nicht als allgemeinen Wunsch nach sicherer IPC. Benennen Sie die lokalen Prozesse mit Verbindungsrecht, die gespeicherten Zugangsdaten, die dadurch möglichen Operationen und die Ereignisse, die den Zugriff beenden müssen. Beziehen Sie Schadsoftware unter demselben Anmeldekonto ein. Dateirechte halten oft andere Benutzer ab, helfen aber wenig gegen einen weiteren Prozess desselben Kontos. Berücksichtigen Sie eine Kopie des Agentenprogramms, ein verändertes Plugin, eine vom Agenten gestartete Shell und einen alten Prozess, der nach dem sichtbaren Auftrag weiterlebt.

Legen Sie dann fest, was eine Genehmigung bedeutet. Sie kann eine signierte Programmdatei, einen Betriebssystemprozess, einen Prozessbaum, einen Terminalauftrag oder alle Clients des angemeldeten Benutzers autorisieren. Das sind unterschiedliche Zusagen. Ein Transport kann nicht zwischen ihnen wählen. Er kann nur manche leichter durchsetzbar machen.

Der Widerruf ist ein guter Entwurfstest. Fragen Sie, was der Broker sofort widerrufen kann, ohne den gesamten Tresor zu sperren. Bei stdio beendet das Schließen einer Pipe oder das Beenden des Kindprozesses den Kanal, wobei Nachkommen bei einem fehlerhaften Starter Deskriptoren geerbt haben können. Bei einem Socket beendet das Schließen einer angenommenen Verbindung diesen Client, während der Listener verfügbar bleibt. Lebt der Autorisierungsdatensatz länger als die Verbindung, reicht keines der beiden Ereignisse aus.

Stellen Sie Netzwerkangreifer nicht in den Mittelpunkt dieser lokalen Entscheidung, sofern der Broker keinen Netzwerk-Listener anbietet. Präzisere Risiken sind eine verwechselte Identität, umgebungsbedingte Befugnis aus der Anmeldung, Deskriptorvererbung, der Austausch eines Dateisystem-Sockets und eine Autorisierung, die länger als die genehmigte Arbeit besteht.

Stdio bindet den Kanal an die Prozesslaufzeit

MCP über stdio passt am besten, wenn der Broker-Shim mit dem Agentenprozess starten und enden soll. Der Client startet einen Serverbefehl, schreibt JSON-RPC-Nachrichten in dessen Standardeingabe und liest Antworten aus der Standardausgabe. EOF ist ein Lebenszyklussignal des Betriebssystems, keine in einem Anwendungs-Heartbeat versteckte Konvention.

Die Transportspezifikation des Model Context Protocol stellt außerdem eine nützliche Betriebsanforderung: Ein stdio-Server darf keine protokollfremden Daten nach stdout schreiben. Protokolleinträge gehören nach stderr. Das wirkt wie reine Framing-Hygiene, verhindert aber, dass eine Diagnosezeile innerhalb einer Sicherheitsgrenze zur ungültigen Nachricht wird. Behandeln Sie stdout als Protokollspeicher. Konfigurieren Sie Bibliotheken und Absturzberichte vor der ersten Antwort, damit sie ihn nicht verunreinigen.

Stdio braucht keinen Dateisystemnamen, kein Socket-Verzeichnis, keinen Rechtemodus, keine Discovery-Datei und keinen residenten Listener. Die Agentenkonfiguration verweist auf ein Programm und seine Argumente. Das ist ein echter Vorteil bei einem Desktop-Produkt, denn es gibt keinen zu suchenden Endpoint und keinen veralteten Pfad zu reparieren. Auch der Aktivierungszeitpunkt eines Updates ist klar: Der nächste gestartete Shim verwendet das neue Programm. Eine laufende Sitzung kann auf der alten Version bleiben. Erfassen Sie deshalb Programmidentität und Version mit der Sitzung, statt nach der Installation alle aktiven Clients als aktualisiert anzusehen.

Die Prozessbeziehung liefert nützliche Belege, aber keine vollständige Identität. Der Broker kann den Shim an seinem privaten Backend prüfen, und der Shim kann seinen Elternprozess prüfen. Prozesskennungen können nach dem Ende erneut vergeben werden, und zwischen dem sichtbaren Agenten und dem Shim kann ein Starter liegen. Erfassen Sie Audit-Token oder Codesignatur, solange der Prozess lebt. Speichern Sie nicht nur eine PID, um sie später aufzulösen.

Pipes haben auch Vererbungsfallen. Markiert ein Starter Deskriptoren als vererbbar, kann ein Enkel das Schreibende nach dem Ende des Agenten offen halten. Der Broker wartet dann auf ein EOF, das nie kommt. Setzen Sie close on exec, wo die Plattform es nicht automatisch tut, schließen Sie ungenutzte Enden direkt nach dem Start und überwachen Sie sowohl die Pipe als auch den erwarteten Clientprozess. EOF sollte den Zugriff widerrufen, und das Prozessende sollte ihn unabhängig widerrufen.

Parallelität ist bewusst eng gehalten. Eine stdio-Serverinstanz bedient normalerweise einen Clientprozess. Das schafft klare Isolation und kostet einen zusätzlichen Prozess je Agent. Liegt der eigentliche Tresor in einer Desktop-Anwendung, ist das stdio-Programm meist ein kleiner Shim, der typisierte Anfragen an die Anwendung weiterreicht. Dieser interne Sprung benötigt weiterhin Authentifizierung und Sitzungsbindung. Stdio am MCP-Rand macht ein nicht authentifiziertes gemeinsames Backend nicht sicher.

Ein Unix-Socket schafft die Laufzeit eines Dienstes

Ein Unix Domain Socket passt zu einem Broker, der bereits als residenter Dienst läuft und im Zeitverlauf unabhängige Clients erwartet. Der lauschende Endpoint überlebt das Ende der Clients. Eine Menüleistenanwendung kann daher Aufrufe annehmen, ohne dass jeder Agent den Brokerprozess besitzt. Mehrere Clients, Rückstau und zentrale Aktualisierungen sind leicht umzusetzen. Dafür muss der Dienst jede Grenze definieren, die ein einzelner Clientprozess implizit mitbrachte.

Der Socket-Pfad dient der Auffindbarkeit, nicht der Authentifizierung. Ein Client, der ihn findet, braucht weiterhin Verbindungsrechte, und ein verbundener Client braucht eine Autorisierungsentscheidung. Legen Sie den Socket in ein vom Benutzer oder von der Anwendung kontrolliertes Verzeichnis, erstellen Sie das Verzeichnis mit Modus 0700 und den Socket mit 0600. Vermeiden Sie einen vorhersehbaren Pfad in einem gemeinsam beschreibbaren Verzeichnis. Das Sticky Bit eines temporären Verzeichnisses verhindert einige Löschangriffe, macht den Namensraum aber nicht vertrauenswürdig.

Rechte hängen von mehr als dem endgültigen Modus ab. Die Prozess-umask beeinflusst die Erstellung. Vorhandene Elternverzeichnisse entscheiden, ob ein anderes Konto Namen durchlaufen oder ersetzen kann. Ein symbolischer Link oder ein veralteter Knoten kann den gewählten Pfad bereits belegen. Der Dienst sollte ein vertrauenswürdiges Elternverzeichnis öffnen, einen Eintrag ohne Linkverfolgung prüfen und ihn erst entfernen, wenn er als Socket einer beendeten Instanz oder als Pfad der aktuellen Installation erwiesen ist. Ein blindes unlink eines bekannten Namens erzeugt ein Austauschrennen.

Unter macOS liefert ein angenommener lokaler Socket Peer-Zugangsdaten über Systemaufrufe wie getpeereid; tiefer liegende APIs geben ein Audit-Token aus. Benutzer- und Gruppenkennungen sagen, welchem Konto der Peer-Prozess gehört. Sie sagen nicht, welche Anwendung der Benutzer autorisieren wollte. Lösen Sie dazu das Audit-Token zum lebenden Prozess auf und bewerten Sie Signaturidentität, Programmpfad und Startkontext nach der erklärten Produktregel.

Ein Socket erleichtert Multiplexing, aber dabei können Sitzungen verschwimmen. Behandeln Sie eine erfolgreiche Verbindung nie als Genehmigung für jede Anfrage mit beliebiger Sitzungskennung. Der Server weist die Verbindungsidentität zu, bindet die Autorisierung daran und weist Versuche des Clients zum Identitätswechsel ab. Verbindet sich ein Hilfsprogramm nach einem Dienstneustart neu, verlangen Sie eine neue Entscheidung, sofern das Bedrohungsmodell das Fortbestehen nicht ausdrücklich erlaubt.

Leistung entscheidet diese Wahl selten. Lokale Pipes und Unix-Sockets übertragen kleine JSON-RPC-Anfragen deutlich schneller, als eine HTTP-API- oder SSH-Operation endet. Messen Sie bei großen Antwortkörpern, aber tauschen Sie kein verständliches Befugnismodell gegen eine vermutete Verringerung lokaler IPC-Kosten.

Socket-Rechte beweisen keine Benutzerabsicht

Modus 0600 bedeutet, dass Prozesse mit anderen Benutzerkennungen den Socket nicht über normale diskretionäre Prüfungen öffnen können. Er bedeutet nicht, dass jeder Prozess desselben Benutzers die gespeicherten Zugangsdaten verdient. Desktop-Schadsoftware, ein nicht vertrauenswürdiges Paketskript, eine Editorerweiterung und der genehmigte Agent teilen häufig dieselbe Kennung.

Diese Unterscheidung verschwimmt, weil Unix-Rechte konkret und leicht prüfbar sind. Ein Team sieht einen privaten Socket und nennt den Endpoint authentifiziert. Authentifiziert ist nur die Kontogrenze. Das kann reichen, wenn das Bedrohungsmodell bei anderen Anmeldekonten endet. Ein Secret-Broker für autonome Werkzeuge verspricht gewöhnlich Kontrolle innerhalb einer Anmeldung und braucht deshalb eine engere Identität.

Unter macOS können Codesignaturdaten diese Identität eingrenzen. Prüfen Sie den lebenden Peer, nicht einen in der Anfrage genannten Pfad. Der Pfad kann auf eine ausgetauschte Datei zeigen, und ein Prozess kann nach einem Update ein altes geladenes Abbild weiter ausführen. Erfassen Sie die vom System gemeldete Signaturstelle und designated requirement. Legen Sie das Verhalten für ad hoc signierte Entwicklungsbuilds fest; ihre stillschweigende Behandlung als Produktionsanwendung macht eine Entwicklerbequemlichkeit zum Umgehungsweg.

Aufruferidentität und Aufruferbefugnis unterscheiden sich ebenfalls. Die Identität beantwortet, welcher Prozess die Verbindung öffnete. Die Befugnis beantwortet, ob dieser Prozess diese Zugangsdaten jetzt für diese Aktion verwenden darf. Ein gültig signierter Agent kann in einem ungeprüften Repository laufen oder sein Prompt kann von schädlichem Inhalt beeinflusst sein. Jede Aktion wegen einer vertrauten Programmdatei zu genehmigen, verwechselt Herkunft mit Zustimmung.

Bei stdio kann der Starter beim Start des Shims die Identität des direkten Elternprozesses vorlegen, und der Broker kann diesen Beleg an einen neuen Kanal-Nonce binden. Bei einem Socket ermittelt der Broker die Peer-Identität bei accept und bindet sie an den angenommenen Deskriptor. In beiden Entwürfen ist der Broker die Quelle der Identität. Ein Feld wie client_name ist nur Anzeigedaten, kein Beleg.

Eine ehrliche Genehmigungskarte zeigt, was das Betriebssystem feststellen kann und was der Benutzer genehmigt. Verhindert ein Wrapper-Skript die zuverlässige Zuordnung zum obersten Agenten, zeigen Sie das an oder lehnen Sie den Aufruf ab. Im Prozessbaum aufwärts nach einem vertrauten Namen zu suchen, schafft einen vom Angreifer kontrollierten Suchpfad.

Bereinigung gehört zum Sicherheitsmodell

Sperren Sie den gesamten Aktionsweg
Bei gesperrtem Tresor lehnt Sallyport jeden Aktionsversuch durch den Broker ab.

Die stdio-Bereinigung betrifft Deskriptoren und Kindprozesse. Der Normalfall ist einfach: Der Client schließt stdin, der Server sieht EOF, beendet oder storniert aktive Arbeit und endet. Die Störfälle sind wichtiger. Der Client kann abstürzen, während ein Nachkomme die Pipe hält. Der Server kann hängen, während der Client ihn für beendet hält. Eine privilegierte Aktion kann nach dem Widerruf fertig werden, wenn der Abbruch den ausführenden Worker nicht erreicht.

Geben Sie jeder Anfrage eine vom Broker vergebene Vorgangskennung und einen Zustand wie queued, executing, completed, denied oder indeterminate. Beim Schließen des Kanals widerrufen Sie künftige Anfragen sofort. Behaupten Sie bei einer bereits an eine externe API gesendeten Aktion keine Stornierung, wenn die Gegenseite sie nicht unterstützt. Erfassen Sie indeterminate, falls der lokale Prozess vor Bekanntwerden des Ergebnisses stirbt. Dieser Eintrag verhindert eine unbemerkte doppelte Ausführung durch Wiederholungen.

Die Socket-Bereinigung hat zwei Objekte: angenommene Verbindungen und den lauschenden Pfad. Schließen Sie eine Clientverbindung bei Protokollfehler, fehlgeschlagener Autorisierung, Leerlaufablauf oder Dienstende. Entfernen Sie den Pfad nur, wenn der Dienst noch dasselbe Dateisystemobjekt besitzt. EADDRINUSE beim Neustart ist ein Untersuchungsgrund, keine Erlaubnis zum unlink des Vorhandenen.

Diese Shell-Prüfung hilft bei der Entwicklung, weil sie Pfadtyp, Eigentümer, Modus und lauschenden Prozess ohne Änderung zeigt:

sock="$TMPDIR/com.example.broker.sock"
stat -f 'type=%HT owner=%Su mode=%Sp inode=%i' "$sock"
lsof -n -U "$sock"

Ein normales macOS-Ergebnis hat diese Form:

type=Socket owner=alice mode=srw------- inode=123456
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF   NODE NAME
Broker  48102 alice   9u  unix 0x0123456789abcdef      0t0        /.../com.example.broker.sock

Parsen Sie die Beispielwerte nicht. Prüfen Sie den Typ Socket, den erwarteten Eigentümer, verweigerten Zugriff für Gruppe und andere sowie die installierte Brokerinstanz als Prozess. Wiederholen Sie die Kontrolle nach erzwungenem Absturz, Anwendungsupdate, Abmeldung und zweitem Start. Ein Entwurf, der nur nach normalem Beenden bereinigt, ist nicht getestet.

Wenn launchd den Dienst startet, sollte es durchgehend dafür zuständig sein. Eine Mischung aus anwendungsgesteuertem Start und launch agent kann zwei Instanzen erzeugen, die um denselben Pfad konkurrieren. Eine Komponente besitzt Erstellung, Bereitschaft und Entfernung. Clients brauchen einen ausdrücklichen Zustand unavailable, statt wiederholt weitere Broker zu starten.

Der Bereitstellungsaufwand verlagert sich

Stdio ist bei der Installation günstiger und wird teurer, wenn viele Clients residenten Zustand teilen. Jeder MCP-Client braucht einen Befehlseintrag. Der Shim muss die signierte Anwendung oder ihren privaten Endpoint finden, eine kompatible Protokollversion aushandeln und einen klaren Fehler liefern, wenn die Anwendung fehlt oder gesperrt ist. Das Paket muss Ausführungsrechte und Codesignaturen erhalten. Shell-Startdateien sollten nicht nötig sein; GUI-Anwendungen starten oft ohne die vom Terminal erwartete Umgebung.

Ein Unix-Socket erfordert Dienstinstallation, Zuständigkeit für den Start, Endpoint-Erkennung, Verzeichnisrechte, Wiederherstellung und Kompatibilität unabhängiger Client- und Serverupdates. Dafür verwenden alle Clients einen stabilen Endpoint, und der Dienst hält Tresorzustand und Audit-Reihenfolge in einem Prozess. Das ist attraktiv, wenn die Desktop-Anwendung ohnehin ständig läuft.

Die Endpoint-Erkennung braucht einen Vertrag. Unter macOS gilt $TMPDIR je Benutzer, doch die geerbte Umgebung kann sich zwischen Terminal, Editor und GUI-Starter unterscheiden. Ein fester Pfad in einem geschützten Supportverzeichnis ist leichter zu beurteilen, auch wenn Sandbox und Installation ihn einschränken können. Erhalten Clients den Pfad von einem Bootstrap-Befehl, authentifizieren Sie dessen Ergebnis, statt einen beliebigen Pfad aus der Projektkonfiguration anzunehmen.

Versionsunterschiede treten in beiden Modellen auf. Bei stdio wählt der Client das zu startende Shim-Programm. Bei einem residenten Socket kann während gestaffelter Updates ein alter Client einen neuen Dienst erreichen oder umgekehrt. Führen Sie im ersten Austausch eine kleine Versionsaushandlung durch. Lehnen Sie nicht unterstützte Kombinationen vor der Genehmigung ab, denn ein Benutzer kann keine Anfrage sinnvoll genehmigen, die Client und Broker unterschiedlich verstehen.

Betriebsteams bevorzugen manchmal Sockets, weil bekannte Werkzeuge sie auflisten. Entwickler bevorzugen manchmal stdio, weil sich ein Befehl im Terminal ausführen lässt. Keine Bequemlichkeit darf zum Debug-Zugang werden. Ein Diagnoseclient mit privilegierten Anfragen folgt demselben Zuordnungs- und Genehmigungsweg wie ein Agent. Ein Debug-Schalter ohne Autorisierung wird irgendwann eine Entwicklungsmaschine verlassen.

Der Vergleich ändert sich, wenn der Broker nicht resident ist. Eine vollständige GUI-Anwendung bei jeder stdio-Verbindung zu starten, verursacht Verzögerungen und unpassende Dialoge. Einen Socket-Dienst nur zur Vermeidung eines kleinen Shims am Leben zu halten, erzeugt Update- und Bereinigungsarbeit. Entscheiden Sie zuerst die Anwendungslaufzeit und passen Sie dann den externen Transport an.

Ordnen Sie den Entwurf konkreten Bedrohungen zu

Trennen Sie Aufrufe und Sitzungen
Activity erfasst Aktionen, Sessions verfolgt die auslösenden Agentenprozesse.

Das Plattformteam sollte erfassen, welche Entwurfseigenschaft auf welche Bedrohung antwortet. Die Tabelle ist eine Entscheidungsakte, keine Punktwertung. Ein Transport gewinnt eine Zeile nur, wenn die umgebende Implementierung die genannte Kontrolle bereitstellt.

Bedrohung oder AnforderungStdio-EntwurfUnix-Socket-Entwurf
Ein anderer Benutzer versucht ZugriffPrivate Prozessdeskriptoren und korrekte VererbungGeschütztes Elternverzeichnis und Modus 0600
Ein anderer Prozess desselben Benutzers verbindet sichSchwieriger, wenn nur der Starter die Pipe besitzt, aber geerbte Deskriptoren bleiben ein RisikoStandardmäßig möglich, daher sind Peer-Zugangsdaten und Anwendungsidentität nötig
Genehmigung endet mit einem AgentenlaufEOF und beobachtetes Prozessende liefern natürliche WiderrufssignaleServer erstellt Sitzung und bindet sie an Verbindung und Prozesslaufzeit
Mehrere Agenten teilen einen TresorJeder Shim braucht einen privaten authentifizierten Sprung zum TresorprozessResidente Dienst nimmt getrennte authentifizierte Verbindungen an
Broker stürzt ab und startet neuClient sieht EOF und startet neu oder meldet einen FehlerDienst behandelt alten Pfad und erzwingt neue Verbindung und Autorisierung
Clientprogramm ändert sich im LaufErfasste Identität bleibt an die Sitzung gebundenErfasste Identität bleibt an die Verbindung gebunden; Neuverbindung löst neue Prüfung aus
Einfache ErstinstallationBefehl und signiertes Programm, ohne Endpoint-EinrichtungStartregistrierung, geschützter Pfad, Erkennung und Bereinigung nötig
Zentrale Audit-ReihenfolgeGemeinsamer Tresorkern ordnet Ereignisse der ShimsIn einem residenten Dienst natürlich, dauerhaftes Logging braucht trotzdem einen Entwurf

Zwei Schlüsse bleiben meist bestehen. Ein Angreifer unter demselben Benutzer nimmt den Dateimodus-Bits fast ihre gesamte beruhigende Wirkung. Die Dauer einer Genehmigung zählt genauso wie der Endpoint-Zugriff. Ein vollständig privater Socket mit ganztägiger Genehmigung kann mehr Befugnis gewähren als ein sorgfältig begrenzter stdio-Kanal.

Vergeben Sie keine numerischen Gewichte, wenn das Team sie nicht begründen kann. Bei sensiblen Zugangsdaten kann eine einzige fehlende Identitätsprüfung alle Bereitstellungsvorteile überwiegen. Schreiben Sie für jede Zeile einen Abnahmetest. Starten Sie etwa einen nicht genehmigten Prozess unter demselben Benutzer und weisen Sie die Ablehnung nach; genehmigen Sie einen Agenten, beenden Sie ihn, lassen Sie einen Nachkommen weiterlaufen und weisen Sie nach, dass die alte Autorisierung nicht wiederverwendbar ist.

Die Wahl kann auch geschichtet werden. MCP verwendet stdio zwischen Agent und kleinem Shim, während der Shim über einen privaten Unix-Socket oder einen anderen Betriebssystem-IPC mit dem residenten Broker spricht. Das ist oft eine passende Desktop-Form, erzeugt aber zwei Grenzen. Authentifizieren Sie beide. Der Shim muss beweisen, welchen Agentenlauf er vertritt, und die Anwendung muss beweisen, dass er den vorgesehenen Broker erreicht hat, nicht einen durch Projektdateien ausgetauschten Endpoint.

Legen Sie Identität in eine geprüfte Sitzungshülle

Genehmigen Sie jede Verwendung
Markieren Sie einen sensiblen Schlüssel für Klick oder Touch ID bei jedem Aufruf.

Eine kleine Protokollhülle macht die Sicherheitsentscheidung prüfbar. Sie ersetzt die Betriebssystemidentität nicht. Sie bindet bereits geprüfte Tatsachen an die Anfrage, die der Broker ausführen soll.

Nach der Prüfung des lebenden Aufrufers erzeugt der Broker Sitzungskennung und Nonce selbst und gibt sie über den authentifizierten Kanal zurück. Jede weitere Anfrage trägt diese Kennung, eine steigende Sequenznummer, die angeforderte Fähigkeit und Aktionsparameter. Der Broker weist eine unbekannte Sitzung, eine wiederholte oder bei strenger Ordnung übersprungene Nummer, eine nicht genehmigte Fähigkeit oder eine Anfrage auf einem anderen Kanal ab.

{"session_id":"s_7M4K","sequence":12,"capability":"http:billing.read","action":{"method":"GET","path":"/v1/invoices"}}

Die Antwort wiederholt Vorgangsidentität und Zustand, nicht Secrets oder eingefügte Autorisierungsheader:

{"operation_id":"op_01J8","sequence":12,"state":"completed","result":{"status":200,"body_ref":"activity:8841"}}

Das sind Protokollformen, keine universellen Feldnamen. Entscheidend ist, dass der Server Identität zuweist, Reihenfolge durchsetzt und eine dauerhafte Referenz auf die aufgezeichnete Aktion liefert. Signieren Sie die Hülle nicht mit einem Schlüssel, den der Agent erhält; dadurch würde der Agent Zugangsdaten halten. Binden Sie sie an den authentifizierten lokalen Kanal und behalten Sie geheimes Material im Broker.

Bei stdio kann die Kanalbindung einen Zufallswert enthalten, der nur durch die neue Pipe übermittelt wurde, sowie die erfasste Starteridentität. Bei einem Unix-Socket kann sie die angenommene Verbindung und das Peer-Audit-Token enthalten. Dürfen Anfragen zwischen Verbindungen wechseln, definieren Sie eine bewusste Wiederaufnahme mit kurzer Dauer und einmaligen Token. Eine aus einem Protokoll kopierte Sitzungskennung darf keine Befugnis wiederherstellen.

Trennen Sie Genehmigungs- von Anzeigedaten. Repository-Pfad, vom Agenten geliefertes Label, Werkzeugname und Begründung helfen einer Person bei der Entscheidung, können aber vom Angreifer gewählt werden. Der Brokerdatensatz unterscheidet geprüfte Prozessfakten, Benutzeraussagen, genehmigte Fähigkeiten und Anfrageinhalt. Bei einem Vorfall sieht ein gut formuliertes Label dann nicht wie ein Beleg aus.

Ein Desktop-Broker kann beide klar kombinieren

Für eine signierte, ständig laufende macOS-Anwendung ist stdio an der MCP-Grenze mit einem getrennt authentifizierten lokalen Sprung in die Anwendung oft der klarste Entwurf. Der Agent erhält das erwartete Startmodell und eine an den Prozess gebundene Laufzeit. Die Anwendung hält einen Tresor, eine Genehmigungsoberfläche und eine geordnete Audit-Historie. Der Entwurf funktioniert nur, wenn der interne Sprung die äußere Aufruferidentität bewahrt, statt alle Shims zu einem vertrauenswürdigen Client zusammenzufassen.

Sallyport verwendet diese Form: MCP-fähige Agenten starten den mitgelieferten stdio-Shim sp mcp, während die Anwendung HTTP- und SSH-Aktionen ausführt, sodass Secrets den Agenten nicht erreichen. Die Sitzungsgenehmigung beginnt mit der Codesignaturstelle des Prozesses und behandelt damit den blinden Fleck reiner Socket-Rechte.

Diese Wahl macht Unix-Sockets nicht allgemein falsch und stdio allein nicht ausreichend. Ein Plattformteam mit mehreren nativen Clients kann einen geschützten Socket als primäre API bereitstellen. Es ist dann für Peer-Prüfung, Sitzungserstellung, Wiederherstellung alter Endpoints und Updatekompatibilität verantwortlich. Kann es jeden Punkt nicht erklären, ist der Socket noch nicht für Zugangsdaten bereit.

Wählen Sie den Entwurf, dessen Fehlerzustand sich am leichtesten ablehnen lässt. Scheitert die Zuordnung, lehnen Sie die Aktion ab. Kann der Broker nicht beweisen, dass ein Endpoint zur aktuellen Instanz gehört, verbinden und löschen Sie ihn nicht. Verbindet ein Client nach einem Prozessneustart neu, erstellen Sie eine neue Sitzung. Diese Regeln kosten etwas Komfort und entfernen die stille Kontinuität, die lokale Broker gefährlich macht.

Die abschließende Architekturprüfung sollte auf eine Seite passen: Autorisierungseinheit, geprüfter Aufruferbeleg, Sitzungsbeginn und -ende, Endpoint-Eigentum, Absturzverhalten, Updateverhalten und Audit-Datensatz. Beruht eine Antwort auf «demselben Benutzer», sollte die Prüfung sagen, ob Schadsoftware dieses Benutzers außerhalb des Modells liegt. Dieser eine Satz zeigt, ob stdio und Unix-Sockets als Transporte verglichen oder als Ersatz für eine Sicherheitsentscheidung verwendet werden.

FAQ

Ist MCP stdio sicherer als ein Unix Domain Socket?

Nicht von selbst. Stdio begrenzt einen Kanal natürlich auf einen gestarteten Prozess, während ein Unix-Socket einen residenten Dienst begünstigt. Die Sicherheit hängt davon ab, ob diese Laufzeit zur Autorisierungseinheit passt.

Authentifiziert Socket-Modus 0600 die aufrufende Anwendung?

Nein. Er beschränkt den Zugriff meist auf den Eigentümer, doch jeder Prozess dieses Benutzers kann eine Verbindung versuchen. Prüfen Sie den lebenden Peer und treffen Sie eine getrennte Autorisierungsentscheidung.

Kann ein Desktop-Broker mehrere Agenten über stdio bedienen?

Ja. Starten Sie einen Shim je Agent und geben Sie jedem einen privaten authentifizierten Sprung zum gemeinsamen Tresorkern. Trennen Sie Sitzungsidentitäten, damit kein Shim die Genehmigung eines anderen beansprucht.

Was soll nach dem Absturz eines stdio-Clients passieren?

Der Broker widerruft künftige Aufrufe bei EOF oder Prozessende und erfasst das Ergebnis laufender Arbeit. Könnte eine externe Aktion abgeschlossen sein, markieren Sie sie als indeterminate, statt sie blind zu wiederholen.

Wie sollte ein alter Unix-Socket entfernt werden?

Prüfen Sie das Objekt ohne Linkverfolgung sowie Typ, Eigentümer und Beziehung zu einer beendeten Instanz. Führen Sie nie allein wegen EADDRINUSE von bind ein unlink des vorhersehbaren Pfads aus.

Sind Unix-Sockets schnell genug für MCP?

Ja, für normale Anfragen. Lokaler Transport fällt neben HTTP oder SSH meist kaum ins Gewicht, daher sollten Identität und Lebenszyklus vor Durchsatz entscheiden.

Sollte Autorisierung einen Broker-Neustart überleben?

Normalerweise nicht. Der Neustart trennt den geprüften Kanal und die Prozessbelege; verlangen Sie Neuverbindung und neue Sitzung, sofern das Produkt keine geschützte dauerhafte Autorisierung zusagt.

Darf der Client seinen Prozessnamen zur Zuordnung senden?

Er darf ein Anzeigelabel senden, aber der Broker darf ihm nicht vertrauen. Leiten Sie Identität vom lebenden Prozess, Audit-Token, der Signatur oder der systemseitigen Startbeziehung ab.

Wo sollte eine macOS-App den Unix-Socket ablegen?

Nutzen Sie ein vom Benutzer oder der Anwendung kontrolliertes Elternverzeichnis und verweigern Sie Gruppe und anderen den Zugriff. Definieren Sie die Erkennung ohne Vertrauen in Projektkonfiguration.

Wann ist eine Kombination aus stdio und Socket sinnvoll?

Sie passt zu einem residenten Desktop-Tresor für getrennt gestartete MCP-Agenten. Der stdio-Rand liefert prozessgebundene Sitzungen; der interne Socket braucht weiterhin Authentifizierung und geprüften Kontext.

Sallyport

Sallyport führt API-Aufrufe und SSH-Befehle für Ihren KI-Agenten aus. Die Schlüssel bleiben in einem lokalen Tresor auf Ihrem Mac; Sie geben jeden Lauf frei, und jede Aktion landet in einem versiegelten Journal.

© 2026 Sallyport · Open Source unter Apache-2.0 · Oleg Sotnikov