Site
Alle Artikel

Veröffentlicht 22. Sept. 202616 Min. Lesezeit

Unternehmens-KI-Fragen: Zwölf schwierige Fragen zu Vinkius mit Code-Level-Antworten

Zwölf schwierige Fragen von Sicherheits-, Finanz- und Plattformteams im Unternehmen, jede beantwortet mit einer spezifischen Quelldatei, Zeilennummer und Durchsetzungsmechanismus aus dem Vinkius-Laufzeit.

Renato Marinho

Von Renato Marinho

Founder · Vinkius

The Vinkius enterprise question and answer surface: twelve hard questions from security, finance, and platform teams, each answered by a specific enforcement surface. The V8 sandbox, the circuit breaker, the hash chain, the capability lockfile, the quarantine switch.

slug: vinkius-enterprise-ai-questions category: enterprise-ai tags: ["enterprise-ai", "security", "governance", "qa", "isolation", "audit"] date: 2026-09-22 hero: src: /post/hero-enterprise-qa.svg alt: "Die Vinkius Enterprise-KI-Frage-Antwort-Oberfläche: zwölf schwierige Fragen von Sicherheits-, Finanz- und Plattformteams, jeweils beantwortet durch eine spezifische Durchsetzungsoberfläche. Die V8-Sandbox, der Circuit-Breaker, die Hash-Kette, das Capability-Lockfile, der Quarantäne-Schalter."

Unternehmens-KI-Fragen: Zwölf schwierige Fragen zu Vinkius mit Code-Level-Antworten

Unternehmen fragen nicht, ob KI-Agenten die Arbeitsweise verändern werden. Sie fragen, ob Vinkius die Konversation übersteht, die sie kommen sehen: die Besprechung, in der ihr Sicherheitsteam, euer Finanzteam und euer Plattformteam jeweils verlangen zu wissen, wie genau diese Plattform das Vertrauen verdient, produktiven Traffic auszuführen.

Ich habe diese Fragen in Vorstandssitzungen, in Sicherheits-Kriegsräumen und in den stillen E-Mail-Fädeln beantwortet, die jedem Piloten folgen. Dies ist die konsolidierte Version. Jede Antwort nennt unten die Quelldatei, die Zeilennummer und den Durchsetzungsmechanismus. Nichts hier ist Politik, die in einem Deck geschrieben steht. Jede Kontrolle ist ein Funktionsaufruf, eine Konstante im Quellcode oder ein Redis-Schlüssel, den die Laufzeit vorprüft, bevor der Agent auch nur ein Ergebnis sieht.

Wenn Sie die Person sind, die vor einem Raum stehen muss und erklären muss, warum ein nichtdeterministischer Prinzipal mit Tool-Zugriff innerhalb Ihres Netzwerks laufen darf: dies ist die Referenz, die Sie während des Vortrags geöffnet halten.


Die Isolierungsschranke

Q1: Wie stellen wir sicher, dass unsere KI-Agenten nicht aus ihrer Sandbox entkommen und unser internes Netzwerk erreichen?

Der Agent läuft nie auf einer Maschine, die Sie besitzen. Jeder Tool-Aufruf wird in einem frischen V8-Isolate ausgeführt, das von isolated-vm erstellt wird, einer Bibliothek, die den V8-Motor außerhalb von Node.js einbettet und keine Brücke zum Host-Prozess bereitstellt, es sei denn, wir injizieren sie explizit. Das Isolate erhält nur die Polyfills, die wir freigeben. Es gibt kein process, kein require, kein fs, kein fetch aus der Sicht des Gasts.

Die Speicherobergrenze ist eine feste Konstante. Limits.ts:36 definiert ISOLATE_MEMORY_LIMIT_MB = 128. In IsolateRunner.ts:117 setzt der Konstruktor this.memoryLimit = options.memoryLimit ?? 128 und in IsolateRunner.ts:143 wird das Isolate mit new ivm.Isolate({ memoryLimit: this.memoryLimit }) erstellt. Wenn der Gast 128 MB erreicht, wirft V8 eine RangeError, die die Berechnung beendet. Es gibt kein Weg, dies zu überschreiten.

Die Boot-Sequenz in IsolateRunner.ts:132 zeigt genau, was verbunden wird. Schritte 1 bis 12 injizieren nur die host-delegierten Primitiven, die wir wollen: eine Console-Bridge, eine Timer-Bridge, eine Crypto-Bridge (getRandomValues), eine Fetch-Bridge (die den SSRF-Guard durchläuft), eine Digest-Bridge (SHA-256, SHA-384, SHA-512), eine HMAC-Bridge (für JWT HS256) und eine MCP-Transport-Bridge. Es wird niemals ein roher Netzwerk-Socket an den Gast übergeben. Der Interceptor in IsolateRunner.ts:164-183 fängt Tool-Definitionen aus dem Bundle ab und sendet sie zurück zum Host, aber der Gast kann keine beliebigen Host-Funktionen aufrufen.

Der Snapshot in SnapshotCache.ts:19 wird vor dem Erreichen von V8 mit SHA-256 validiert. Ein korrupter oder manipulierter Snapshot wird in SnapshotCache.ts:70-71 gelöscht, bevor er geladen wird.

Für die vollständige Laufzeitarchitektur hinter dieser Isolierungsschranke, siehe AI Agents Are the New Consumers und How V8 Isolates Power the Vinkius Runtime.

Q2: Wenn ein Agent versucht, unsere internen Dienste aufzurufen, was hält ihn tatsächlich auf?

Jeder ausgehende HTTP-Aufruf von einem Isolate durchläuft eine einzige Funktion: safeFetch in SsrfGuard.ts:163. Es gibt keinen anderen Ausstieg. Der Gast kann fetch aufrufen, aber die Bridge in IsolateRunner.ts:161 leitet es ausschliesslich zu dieser Funktion um.

Die SSRF-Abwehr hat drei Schichten, alle in SsrfGuard.ts:

Erster, Zieldvalidierung. SsrfGuard.ts:27 definiert PRIVATE_RANGES, eine Liste von Regex-Mustern, die 127/8, 10/8, 172.16 to 172.31/12, 192.168/16, 169.254/16, 0/8 und ihre IPv6-Passförmigen (::1, fc00, fe80) treffen. Jede gelöste Adresse wird gegen diese Liste getestet, bevor die Verbindung hergestellt werden kann.

Zweiter, DNS-Pinning mit IP-Kopplung. SsrfGuard.ts:50 setzt DNS_CACHE_MAX_ENTRIES = 4_096. Die Cache-Lebensdauer ist an die undici Keep-Alive-Socket-Lebensdauer in Limits.ts:46 gekoppelt, AGENT_KEEP_ALIVE_TIMEOUT_MS = 65_000. Eine geprüfte Adresse kann die Verbindungsrichtlinie nicht überleben, die das Pin-Setup gerechtfertigt hat. Dies verhindert DNS-Rebinding-Angriffe, bei denen ein Angreifer den A-Record zwischen Auflösung und Verbindung wechselt.

Dritte, die undici-custom Lookup-Funktion in SsrfGuard.ts:110-113 löst DNS in eine IP auf, bevor der TLS-Handshake erfolgt, und übergibt dann dieselbe IP als servername, um den SNI an den tatsächlich verbundenen Host anzupassen. Die Verbindung ist an die gelöste IP für die Lebensdauer des Socket-Pools gebunden.

Q3: Was verhindert, dass ein Tool sensible Daten über seine Antwort ausstrahlt?

Datenbereinigung findet in ResponseGuard.ts statt und läuft vollständig im Host-Prozess ab, nie innerhalb des V8-Isolates. Der Kommentar in ResponseGuard.ts:4 erklärt die Sicherheitsgrenze ausdrücklich: Redaktion zwischen Upstream-Daten und Agent-Ausgabe.

Der Guard ist Stage 6 des Ausführungs-Pipelines in ToolExecutionPipeline.ts:422. Die Pipeline-Stufen in Reihenfolge sind: (1) Quota-Durchsetzung in ToolExecutionPipeline.ts:380, (2) Handler-Ausführung in ToolExecutionPipeline.ts:392, (3) Antwort-Normalisierung in ToolExecutionPipeline.ts:396, (4) FinOps-Trunkation in ToolExecutionPipeline.ts:401, (5) Kompaktierung in ToolExecutionPipeline.ts:408, (6) DLP in ToolExecutionPipeline.ts:422, (7) Tool-Fehler-Erkennung in ToolExecutionPipeline.ts:426, und (8) Telemetrie in ToolExecutionPipeline.ts:448.

In ResponseGuard.ts:54-57 teilt der Guard eingehende Patterns in zwei Kategorien ein. Patterns wie *.email werden in Feldnamen (z.B. email) extrahiert und pro Element auf jedes Objekt im Antwortbaum angewendet. Das gleiche Pattern wie stepRedact im Presenter-Pipeline. Patterns wie user.ssn verwenden den Original-Pfad und werden mit fast-redact für eine explizite Top-Level-Übereinstimmung kompiliert.

Der Zensierwert ist [REDACTED] in ResponseGuard.ts:108-116. Wenn während der Redaktion ein Fehler auftritt, gibt ResponseGuard.ts:177 { error: '[REDACTED]: DLP redaction failed' } zurück, so dass keine Teildaten austreten.

Jede Redaktion wird gezählt und zugewiesen in ResponseGuard.ts:122-128, sodass das KI-Governance-Dashboard zeigt, welcher Connector welche Redaktion ausgelöst hat und wie oft.

Q4: Kann ein kompromittierter oder fehlerhafter Connector andere Connectoren auf derselben Laufzeit beeinflussen?

Nein. Jeder Verbindungstoken erhält sein eigenes Isolate, seine eigene Credential-Map und seinen eigenen Lebenszyklus. IsolateLifecycle.ts:34 eröffnet mit dem Invariant: Jeder Token erhält sein eigenes IsolateRunner mit seinen eigenen injizierten Credentials. Kein Teilen zwischen Tokens.

Die Credential-Injektion in IsolateLifecycle.ts:96-104 verschmilzt entschlüsselte Server-Credentials mit dem Verbindungstoken des Aufrufers, aber nur Tokens mit dem Präfix vk_live_ werden injiziert. IsolateLifecycle.ts:32 definiert CONNECTION_TOKEN_PREFIX = 'vk_live_'.

Der Schnellpfad in IsolateLifecycle.ts:124-136 stellt ein Isolate aus dem Snapshot wieder her, aber die Re-Injektion in IsolateLifecycle.ts:62-64 setzt die Credential-Map vor der Übergabe des Runners neu durch. Ein lebendiges Isolate überlebt eine einzelne Anfrage. Legacy SSE hält es für die gesamte Sitzung und stateless POSTs wiederverwenden es, solange diese Sitzung geöffnet ist. Aber es könnte von einem Pfad gebootet worden sein, der den Verbindungstoken noch nicht aufgelöst hatte. Der Fingerprint-Guard auf injectSecrets stellt sicher, dass dies ein No-Op ist, wenn die Map bereits aktuell ist.

Q5: Wie erzwingt Vinkius Ausgabegrenzen, und was passiert, wenn sie überschritten werden?

Der Circuit-Breaker in CircuitBreaker.ts:22 läuft als die erste Prüfung im Pipeline. Er ist ein gleitender Fenster-Zähler, der in Redis gespeichert ist. Das Konfigurationsobjekt stellt window_minutes, max_requests und cooldown_minutes aus der Serverkonfiguration.

In CircuitBreaker.ts:48-56 wird der Zähler mit INCR auf einen Schlüssel mit Scope cb:window:{scopeId}:{windowKey} erhöht. Der Fenster-Schlüssel leitet sich ab von Math.floor(Date.now() / 1000 / windowSeconds) in CircuitBreaker.ts:50, sodass das Fenster deterministisch voranschreitet und sich automatisch zurücksetzt.

Wenn der Zähler max_requests überschreitet, schaltet der Dis joncteur in CircuitBreaker.ts:60-62 um, indem er cb:tripped:{scopeId} mit SETEX für die Cooldown-Periode schreibt. Die Fehlermeldung ist bewusst kodiert:

[SYSTEM] CRITICAL: Financial budget ceiling exceeded.
Your account's circuit breaker has tripped to protect your budget.
DO NOT RETRY this request.

Dies ist ein bewusst nicht wiederholbarer Fehler. Im Gegensatz zu einer 429-Ratenbegrenzung, die ein Klient mit Backoff wiederholt, sagt der Circuit-Breaker dem Agent, stoppen und dem Benutzer, seinen Plan zu prüfen. Die Nachricht wird in die Tool-Antwort injiziert, damit der Agent sie in seinem Prompt-Kontext sieht.

Das QuotaEnforcer.ts:27 konstruiert den Circuit-Breaker in seinem Konstruktor und ruft this.circuitBreaker.check(config) in QuotaEnforcer.ts:48 auf, bevor irgendeine Quota-Logik ausgeführt wird.

Q6: Wie gehen Sie mit Mehrkosten um, ohne legitimen Traffic zu blockieren?

Das Quota-Modell verzweigt sich nach Plan in QuotaEnforcer.ts:154-246:

Marketplace-Abonnements (Unternehmenspläne mit einem Sitz pro Connector) werden strikt am vereinbarten Abonnement-Limit blockiert. QuotaEnforcer.ts:163 dekrementiert den Zähler mit DECR und gibt einen SUBSCRIPTION QUOTA EXCEEDED-Fehler in QuotaEnforcer.ts:168 zurück.

Kostenloser Plan ist strikt blockiert ohne Mehrkosten-Pfad. QuotaEnforcer.ts:186-188 dekrementiert den Zähler und gibt REQUEST BLOCKED: QUOTA EXCEEDED mit einem Upgrade-Link in QuotaEnforcer.ts:205 zurück.

Kostenpflichtiger Plan wird nie strikt für Quota blockiert. QuotaEnforcer.ts:246 lässt die Anfrage durch. Die Mehrkosten werden in QuotaEnforcer.ts:236-243 ausgelöst: Wenn newCount quota.limit überschreitet, wird die Überschreitung berechnet als newAmount = newCount - quota.limit, und creditSlot = Math.ceil(overAmount / 10_000). Wenn der Slot eine 10K-Grenze überschreitet, löst triggerOverageCharge fire-and-forget in QuotaEnforcer.ts:242. Der Abrechnungsaufruf blockiert nie die Anfrage.

Der TTL der Quota-Schlüssel in QuotaEnforcer.ts:15 ist QUOTA_KEY_TTL_SECONDS = 31 * 24 * 60 * 60 (31 Tage), was einen beliebigen 30-Tage-Abrechnungszyklus abdeckt. Die INCR-Retry-Schleife in QuotaEnforcer.ts:88-100 versucht bis zu 3-mal mit exponentiellem Backoff [0, 50, 150] ms.

Q7: Welche Not-Aus-Schalter existieren, wenn ein Connector böswillig oder kompromittiert wird?

Drei Ebenen des Kill-Schalters, jeweils in einem anderen Geltungsbereich:

Tier 1: Server-Quarantäne in SoarController.php:50 POST /servers/{server}/soar/kill. Setzt mcp:quarantine:{id} in Redis mit einem TTL von 3600 Sekunden. Alle drei Transport-Routen prüfen diesen Schlüssel und geben 403 in legacySse.ts:63, mcpEndpoint.ts:257, und streamableHttp.ts:101 zurück.

Tier 2: Server-Not-Halt in ServerLifecycleController.php:72-100. Deaktiviert den Server, widerruft ALLE Tokens (revoked_at = now, revoked_by = 'server_halt', is_enabled = false in den Zeilen 81-86), und sendet mcp:kill-server plus Token-weise mcp:invalidate via Redis pub/sub in Zeile 89. Entspricht dem Artikel 14 der EU-KI-Gesetzgebung.

Tier 3: Org-Level-Global-Halt in Organization.php:645-666. Aktiviert die Spalten global_halt_at und global_halt_by, die die Laufzeit bei jeder Anfrage prüft.

Die Laufzeit-Seite empfängt diese Signale in server.ts:96-103. Der Kanal mcp:kill-server löst ConnectionTracker.ts:158-194 aus, der alle SSE-Verbindungen trennt, V8-Isolates freigibt und Redis-Cache-Einträge löscht.

Die FAQ der Governance-Veröffentlichung bei der Circuit-Breaker-Frage behandelt das benutzerseitige Verhalten. Das vollständige Incident-Response-Playbook mit SOAR-Integration ist in der FAQ-Abschnitt dieser Veröffentlichung.

Q8: Was verhindert, dass ein unkontrollierter Agent tausende parallele Sitzungen öffnet?

Die Sitzungsschicht erzwingt eine harte Deckkammer pro Token. SessionManager.ts:44 definiert MAX_SESSIONS_PER_TOKEN = 50. In SessionManager.ts:171 läuft die Prüfung: if (meta.token === token && ++count >= MAX_SESSIONS_PER_TOKEN). Die 51. parallele Sitzung wird abgelehnt.

Sitzungen werden alle 15 Sekunden via SESSION_SWEEP_INTERVAL_MS = 15_000 (SessionManager.ts:43) gescannt. Inaktive Sitzungen verfallen nach SESSION_IDLE_TIMEOUT_MS = 120_000 (2 Minuten). Unter Speicherdruck sinkt der Timeout auf SESSION_PRESSURE_TIMEOUT_MS = 30_000 (30 Sekunden).

Jeder Sitzungseintrag in Redis erhält REDIS_SESSION_TTL = 150 (2,5 Minuten), entsprechend dem inaktiven Timeout in SessionManager.ts:120. Der Scan in SessionManager.ts:89 erzwingt ebenfalls Speicherschwellen: MEMORY_WARN_THRESHOLD = 0.65 (65%) startet Warnungen und MEMORY_PRESSURE_THRESHOLD = 0.80 (80%) löst aggressive Zwei-Ebenen-Räumung aus.

Die Sitzung-zu-Token-Zuordnung ist in Redis in SessionManager.ts:155-163 gespeichert, sodass jede Laufzeitinstanz eine Sitzung auflösen oder ablehnen kann. Das bedeutet, dass horizontale Skalierung funktioniert. Sie können mehrere Laufzeitinstanzen betreiben, und die Sitzungs-Deckkammer wird global in der Flotte weiterhin durchgesetzt.

Für die Schwebedynamik der Sitzungskoordination auf Schwarm-Ebene mit 100 parallelen Agenten, die Sitzungen teilen, siehe die SwarmGateway-Sitzungs-Veröffentlichung.

Q9: Wie vermeiden Agenten Timeouts unter Last? Was ist die tatsächliche Latenz-Overhead der Governance-Pipeline?

Die Pipeline ist so konzipiert, dass der Overhead proportional zur Antwortgröße statt zur Upstream-API-Latenz ist. Die rohe Handler-Ausführung in ToolExecutionPipeline.ts:392 wird separat vom Pipeline getaktet.

Der Kaltstart verwendet Snapshots. IsolateLifecycle.ts:124-136 versucht zunächst den Schnellpfad: bootFromSnapshot in IsolateRunner.ts:247 erstellt das Isolate aus einem gecachten Snapshot mit vorgeladenen Polyfills, dokumentiert als etwa 3 bis 5 Millisekunden. Der Kommentar in IsolateLifecycle.ts:123 besagt, dass der Snapshots-Cache folgende Boots auf etwa 15 bis 25 Millisekunden beschleunigt. Nur der erste Boot pro Deploy zahlt den langsamen Weg in IsolateLifecycle.ts:138, der das vollständige IIFE-Bundle mit etwa 50 bis 100 Millisekunden ausführt.

Bei BOOT_TIME_BUDGET_MS = 5_000 (Limits.ts:33) ist der Boot-Timeout großzügig im Vergleich zu den beobachteten Latenzen. Bei DISPATCH_TIME_BUDGET_MS = 30_000 (Limits.ts:26) deckt der Dispatch-Deck die Latenz-Schwanz der Upstream-API ab. Die Funktion TimeoutClassifier.ts:53 unterscheidet zwischen UPSTREAM_TIMEOUT, COMPUTE_TIMEOUT, und MEMORY-Fehlern, sodass eine langsame externe API nicht für das Gast-Bundle verantwortlich gemacht wird.

Der Manifest-Server in streamableHttp.ts:66-69 dient initialize, tools/list, und prompts/list mit Null-V8-Boot-Overhead: rohe MCP-SDK-Handler ohne Framework-Kosten. Nur tools/call und prompts/get erreichen die volle Pipeline.

Verbindungen werden mit undici Keep-Alive gepoolt. Limits.ts:46 setzt AGENT_KEEP_ALIVE_TIMEOUT_MS = 65_000, leicht über dem Standard-60-Sekunden-ALB-Inaktivitätsfenster. Limits.ts:49 setzt AGENT_POOL_MAX = 100 als die harte Obergrenze gleichzeitiger gepoolter ausgehender Agenten.

Q10: Wie wissen wir, dass unser Verbindungstoken nicht von jemand anderem verwendet wird?

Tokens werden niemals im Raw-Wert im Runtime-Cache gespeichert oder gesucht. In ProxyRegistry.ts:385-406 akzeptiert die Invalidierungsfunktion sowohl Klartext-Tokens als auch Token-Hashes. Die Laufzeit hat kein APP_KEY und kann ihren eigenen Redis-Cache nicht direkt adressieren. Cache-Invalidierung fließt über Laravel via pub/sub, nie von der Laufzeit. Dies ist eine bewusste architektonische Einschränkung: Die Laufzeit ist rein ein Empfänger.

Die Token-Auflösung in ProxyRegistry.ts:200-218 löst das Verbindungstoken des Aufrufers gegen die Laravel-API auf, und das Ergebnis wird mit einem TTL gecacht. Die Funktion invalidate in ProxyRegistry.ts:385 unterstützt sowohl direkte Token- als auch HMAC-Hash-Widerruf, sodass Laravel nach Token-ID-Hash widerrufen kann, ohne den Raw-Token je über pub/sub zu senden.

Der ConnectionTracker.ts:19 setzt IDLE_TIMEOUT_MS = 30 * 60_000 (30 Minuten) für den LRU-Scan, und ConnectionTracker.ts:356-394 führt Zwei-Ebenen-Räumung aus: normal inaktiv nach 30 Minuten, und Speicherdruck bei 75% von TASK_MEMORY (standardmäßig 1 GB).

Q11: Wie verifizieren wir, dass die Fähigkeitsoberfläche sich nicht zwischen Deploys geändert hat?

Die Datei mcpfusion.lock ist die Quelle der Wahrheit für die gesamte Verhaltensfläche eines Connectors. CapabilityLockfile.ts:54 definiert LOCKFILE_VERSION = 1 und CapabilityLockfile.ts:57 setzt LOCKFILE_NAME = 'mcpfusion.lock'.

In CapabilityLockfile.ts:256-313 erzeugt generateLockfile() einen deterministischen Kompilierungs-Snapshot aller Tools, Prompts, Ressourcen, Imports und Modul-Abhängigkeiten. Jedes LockfileTool in CapabilityLockfile.ts:100-111 deklariert pro-Tool entitlements (filesystem, network, subprocess, crypto, codeEvaluation) und cognitiveGuardarounds (agentLimitMax, egressMaxBytes) in CapabilityLockfile.ts:140-143.

In CapabilityLockfile.ts:388 ist checkLockfile() die CI-Schranke. Der Schnellpfad prüft eine Integrity-Digest-Übereinstimmung. Der langsame Weg in CapabilityLockfile.ts:404-484 macht eine Tool-für-Tool-Vergleich und kategorisiert jede Änderung als added, removed, changed, oder unchanged. Die serialisierte Ausgabe in CapabilityLockfile.ts:324-336 verwendet sortierte Schlüssel, damit identische Eingaben immer die gleiche Ausgabe erzeugen und der Lockfile in git vergleichbar ist.

Wenn sich der Lockfile zwischen Deploys ohne eine entsprechende Überprüfung ändert, schlägt die CI-Schranke den Build fehl. Wenn die Laufzeit ein Tool erkennt, das nicht im Lockfile ist, wird es vor dem Dispatch abgelehnt.

Q12: Wie stellen wir sicher, dass Audit-Events nicht gefälscht oder gelöscht werden können?

Zwei unabhängige Hash-Chains deckten unterschiedliche Flächen ab:

Die Runtime-Tool-Ausführungs-Chain wird von ChainForge.ts aufgebaut. In ChainForge.ts:26 verankert GENESIS_HASH = '0'.repeat(64) die Chain. Für jedes Audit-Event:

chain_input  = raw_base64 || previous_hash || sequence_number
current_hash = SHA-256(chain_input)
signature    = Ed25519_Sign(sessionPrivateKey, chainInput)

Das ist in ChainForge.ts:56-66. Der Chain-Status (lastHash, lastSeq) wird atomisch in Redis in StreamingDaemon.ts:309-317 über MULTI/EXEC HSET + XACK gecacht. Der Daemon selbst in StreamingDaemon.ts:31 verwendet CONSUMER_GROUP = 'audit-group' und ist per Design single-threaded. ChainForge.ts:12 erklärt, dass es ausschließlich vom StreamingDaemon aufgerufen wird. Keine Parallelität, keine Race-Conditions.

Die Deployment-Audit-Trail wird von DeployAuditLog.php:144-147 verwaltet. Jeder Datensatz ist mit HMAC-SHA256 verkettet: H(prev_hmac || id || event || payload). Die statische Methode verifyChain() in DeployAuditLog.php:175-214 durchläuft Datensätze, die nach UUID v7 geordnet sind, berechnet den HMAC neu und vergleicht ihn mit hash_equals().

In DeployAuditLog.php:95-99 wirft die Methode delete() eine RuntimeException. Logs sind unveränderlich, ohne delete()- oder update()-Pfad. Dies entspricht Artikel 26(5) und 73 der EU-KI-Gesetzgebung.

Sitzungsschlüssel rotieren alle 24 Stunden in ChainForge.ts:110-113 (rotateSessionKey). Der Sitzungs-TTL wird in StreamingDaemon.ts:35 mit SESSION_KEY_TTL_MS = 24 * 60 * 60 * 1000 erzwungen.

Q13: Was ist im versiegelten Tresor, und wie werden Schlüssel tatsächlich verwaltet?

Der Tresor speichert Ed25519-Schlüsselpaare, nicht AES-Daten. VaultProvider.ts:10-52 definiert die Schnittstelle: getMasterKey, generateSessionKey, sign, verify, und crossSignRotation.

SoftwareVaultProvider.ts:59-116 generiert den Master-Schlüssel mit einem race-sicheren SETNX auf mcp:vault:{workspaceId}. Das Sitzungszertifikat in SoftwareVaultProvider.ts:138-143 signiert den Sitzungs-Public-Key mit dem Master-Private-Key und bindet ihn an den Workspace und das Ablaufdatum.

VaultProvider.ts:23 generiert ein Sitzungs-Schlüsselpaar mit generateSessionKey(24h). Der 24-Stunden-TTL entspricht der ChainForge-Rotation in StreamingDaemon.ts:35. Die Funktion sign in VaultProvider.ts:34 führt Ed25519-Signierung unter Verwendung des Sitzungs-Private-Keys durch.

SoftwareVaultProvider.ts:188 implementiert crossSignRotation() für die 90-tägige Master-Schlüssel-Rotation. Dies ermöglicht alten Schlüsseln, neue Public-Keys zu signieren und umgekehrt, was eine zero-downtime-Migration ermöglicht.

Der Zusammenhang zur breiteren Audit-Architektur ist in der KI-Governance-Veröffentlichung, die die zwölf Flächen behandelt, die diese Schlüssel verbrauchen.

Q14: Wie erkennen und stoppen Sie einen Agenten, der verdächtige Tool-Aufrufe an unbekannte externe Ziele macht?

Jeder ausgehende HTTP-Aufruf von einem Isolate wird zu safeFetch in SsrfGuard.ts:163 geleitet, dem einzigen Ausgabepunkt, der dem Gast exponiert ist. Die Bridge in IsolateRunner.ts:161 leitet den fetch-Aufruf des Gasts ausschließlich zu dieser Funktion um.

Der TimeoutClassifier.ts:53 klassifiziert Dispatch-Fehler als UPSTREAM_TIMEOUT, COMPUTE_TIMEOUT, MEMORY, und INTERNAL_ERROR. Wenn 30 Prozent oder mehr des Dispatch-Budgets für I/O aufgewendet wurden. In TimeoutClassifier.ts:66 ist upstreamShareThresholdMs = Math.max(1_000, Math.floor(ctx.dispatchTimeoutMs * 0.3)). Der Fehler wird dem Upstream-Service zugerechnet, nicht dem Gast-Bundle. Die 3 langsamsten Aufrufe werden in MAX_LISTED_CALLS = 3 (TimeoutClassifier.ts:46) angezeigt.

Die DLP-Muster von ResponseGuard.ts decken Feldnamen ab, die sensible Werte sein sollten und niemals in Ausgabefeedbacks erscheinen. Die standardmäßigen Redaktionsmuster enthalten Platzhalter für email, password, secret, credit_card, ssn, api_key, token, iban und mehr. Jede Redaktion wird gezählt und zugewiesen in ResponseGuard.ts:122-128, sodass ein Anstieg der Redaktionen für einen bestimmten Connector ein Signal im KI-Governance-Dashboard erzeugt.

Q15: Was passiert mit meiner Verbindung, wenn der Laufzeitprozess mitten in einer Anfrage abstürzt?

POST-Anfragen sind per Design stateless. In streamableHttp.ts:15 werden POST-Anfragen stateless bedient. Jede Anfrage erstellt ein efäheres McpServer + Transport, bearbeitet die Anfrage und wirft alles weg. Der Kommentar in streamableHttp.ts:62 erwähnt, dass stateless-HTTP bedeutet, dass jede Laufzeitinstanz jede Anfrage beantworten kann.

SSE-Verbindungen sind stateful, aber ihre Metadaten leben in Redis. ConnectionTracker.ts:61-67 speichert SSE-Verbindungs-Metadaten in Redis (ElastiCache-kompatibel), sodass ein Absturz durch eine neue Instanz wiedergefunden wird, die die gleichen Metadaten liest.

In server.ts:19 startet die Laufzeit leer. Sie lädt Konfiguration lazy beim ersten Client-Verbindungsaufbau, nicht eager beim Start. Der pub/sub-Abonnent in server.ts:71-90 abonniert mcp:invalidate, mcp:kill-server, mcp:update-quota, mcp:tools-changed, und mcp:streaming-reload beim Start.

In server.ts:47-52 protokollieren nicht behandelte Rejections und nicht abgefangene Ausnahmen Fehlermeldungen, aber halten den Prozess am Laufen. Die Laufzeit ist dafür konzipiert, einzelne Anfrage-Fehler ohne Absturz zu überstehen.

Der Snapshot-Cache in SnapshotCache.ts:202 führt eine Start-Bereinigung durch, die alle gecachten Snapshots beim Booten validiert, sodass ein Absturz durch einen korrupten Snapshot beim Neustart nicht erneut eintritt.


Die zwölf Flächen, die diese Fragen beantworten

Die obigen technischen Fähigkeiten entsprechen den zwölf Flächen des Vinkius-Governance-Modells. Acht melden, vier entscheiden.

Flächen die melden (wo Sichtbarkeit lebt) :

  1. Crypto Audit Path in ChainForge.ts:26-80 für die Laufzeit-Hash-Chain, DeployAuditLog.php:144-214 für die Deployment-Integrität.
  2. DLP Telemetry in ResponseGuard.ts:122-128 zählt jede Redaktion pro Token.
  3. FinOps Telemetry in QuotaEnforcer.ts:236-243 verfolgt Nutzung und löst Mehrkosten-Aufrufe bei der 10K-Grenze aus.
  4. Connection Logs in AuditLogger.ts:19-55 sendet Verbindungsereignisse an Redis via LPUSH für SOC-2-Konformität.
  5. SIEM Dispatch in StreamingDaemon.ts:83-153 verbraucht Redis-Streams mit XREADGROUP, stellt Checkpoints wieder her und sendet an SIEM-Ziele.
  6. Snapshot Integrity in SnapshotCache.ts:95-101 verifiziert SHA-256, bevor ein Blob V8 erreicht.
  7. Timeout Classification in TimeoutClassifier.ts:41-80 ordnet Fehler Upstream-vs. Compute zu.
  8. Honeytoken Detection: Wenn eine Decoy-Credential verwendet wird, löst der Provider-Webhook aus und der Connector wird automatisch gebannt.

Flächen die entscheiden (wo Durchsetzung lebt) :

  1. Connector Policy in CapabilityLockfile.ts:100-143 friert die Fähigkeitsoberfläche zur Compile-Zeit ein.
  2. DLP Protection in ResponseGuard.ts:4-177 läuft im Host-Prozess bei jeder Tool-Antwort.
  3. FinOps Guard in CircuitBreaker.ts:22-80 schaltet bei Finanz-Budget-Grenzen mit einem nicht-wiederholbaren Fehler.
  4. Circuit Breaker in QuotaEnforcer.ts:154-246 verzweigt nach Plan, blockiert Marketplace und Kostenlosplan strikt bei ihren Grenzen, während zahlungsfähige Überschreitung zulässt.

Jede Fläche wird im Code durchgesetzt, nicht in Richtlinien-Dokumenten. Die Zahlen, Grenzen und Zeilennummern oben sind die Implementierung. Drucken Sie sie. Prüfen Sie sie. Setzen Sie sie mit Zuversicht ein.

Für die benutzerfreundliche FAQ mit einfacheren Antworten, siehe der FAQ-Abschnitt dieser Governance-Veröffentlichung. Für die Schwarm-Sitzungsverwaltung, die 100 parallele Agenten handhabt, siehe die SwarmGateway-Sitzungs-Veröffentlichung.

Themenenterprise-aisecuritygovernanceqaisolationaudit