/* isolation broker — broker policy for routing isolation requests to providers. Do not isolate directly — the broker selects the provider. RFC-1097: sweep — werkstatt-engine clean Sweep batch 4: 73 Compass headers on headerless engine files (certification, component-runtime, isolation, evolution, testing), real KEY_DECISIONS on 75 files (kernel, cache, dht, swim, gitmesh, runtime), ~80 purpose expansions (CONTRACT-02/PURPOSE-02), non-goals on 13 CONTRACT-03 files, CS-07 history literal fix repo-wide (253 files). Policy: .template.ts/.template.astro excludedPaths. werkstatt-engine now 0 diagnostics. */ import type { CapabilityId } from "@warpgogol/werkstatt-shared/component"; import type { Sha256Digest } from "@warpgogol/werkstatt-shared/fingerprint"; import type { AttenuatedGrantSetV1, CapabilityBridgeRequestV1, CapabilityBridgeResponseV1, } from "../contracts.ts"; export interface BrokerPolicyV1 { schema: "werkstatt/broker-policy@1"; policyId: string; version: string; allowedCapabilities: readonly CapabilityId[]; maxRequestBytes: number; maxResponseBytes: number; defaultTimeoutMs: number; maxConcurrentRequests: number; } export interface BrokerAuditEntryV1 { schema: "werkstatt/broker-audit-entry@1"; requestId: string; callerId: string; workloadId: string; artifactHash: Sha256Digest; grantSetHash: Sha256Digest; capability: CapabilityId; status: "ok" | "denied" | "error" | "timeout"; timestamp: string; redactedDiagnostics: readonly string[]; } export type BrokerHandlerV1 = ( request: CapabilityBridgeRequestV1, ) => Promise; export interface RegisteredCapabilityV1 { capability: CapabilityId; handler: BrokerHandlerV1; } export interface CapabilityBrokerV1 { registerCapability(capability: CapabilityId, handler: BrokerHandlerV1): BrokerRegisterOutcomeV1; invoke( request: CapabilityBridgeRequestV1, context: BrokerInvocationContextV1, ): Promise; auditLog(): readonly BrokerAuditEntryV1[]; registeredCapabilities(): readonly CapabilityId[]; } export interface BrokerInvocationContextV1 { callerId: string; workloadId: string; artifactHash: Sha256Digest; grantSet: AttenuatedGrantSetV1; policy: BrokerPolicyV1; timestamp: string; } export interface BrokerRegisterResultV1 { ok: true; capability: CapabilityId; } export interface BrokerRegisterFailureV1 { ok: false; ruleId: "CERT-BROKER-01" | "CERT-BROKER-02"; message: string; } export type BrokerRegisterOutcomeV1 = BrokerRegisterResultV1 | BrokerRegisterFailureV1; const DENIED_CAPABILITIES = new Set([ "fs", "net", "process", "env", "credential", "descriptor", "ipc", "host-object", ]); export function createCapabilityBroker(): CapabilityBrokerV1 { const capabilities = new Map(); const audit: BrokerAuditEntryV1[] = []; let activeRequests = 0; return { registerCapability( capability: CapabilityId, handler: BrokerHandlerV1, ): BrokerRegisterOutcomeV1 { const capStr = String(capability); if (DENIED_CAPABILITIES.has(capStr)) { return { ok: false, ruleId: "CERT-BROKER-01", message: `capability "${capStr}" is ambient host access — denied by construction`, }; } if (capabilities.has(capStr)) { return { ok: false, ruleId: "CERT-BROKER-02", message: `capability "${capStr}" is already registered`, }; } capabilities.set(capStr, { capability, handler }); return { ok: true, capability }; }, async invoke( request: CapabilityBridgeRequestV1, context: BrokerInvocationContextV1, ): Promise { const capStr = String(request.capability); const deniedResponse = ( reason: string, status: "denied" | "timeout" | "error" = "denied", ): CapabilityBridgeResponseV1 => { const entry: BrokerAuditEntryV1 = { schema: "werkstatt/broker-audit-entry@1", requestId: request.requestId, callerId: context.callerId, workloadId: context.workloadId, artifactHash: context.artifactHash, grantSetHash: context.grantSet.grantSetHash, capability: request.capability, status, timestamp: context.timestamp, redactedDiagnostics: [reason], }; audit.push(entry); return { schema: "werkstatt/capability-bridge-response@1", requestId: request.requestId, status, payload: new Uint8Array(0), diagnostics: [reason], }; }; if (!context.policy.allowedCapabilities.includes(request.capability)) { return deniedResponse(`capability "${capStr}" is not in policy allowed list`); } const registered = capabilities.get(capStr); if (!registered) { return deniedResponse(`capability "${capStr}" is not registered`); } const grantExists = context.grantSet.grants.some( (g) => g.scope === request.grant.scope && g.resource === request.grant.resource, ); if (!grantExists) { return deniedResponse( `grant scope "${request.grant.scope}" resource "${request.grant.resource}" is not in grant set`, ); } if (request.payload.length > context.policy.maxRequestBytes) { return deniedResponse( `request payload ${request.payload.length} exceeds max ${context.policy.maxRequestBytes}`, ); } if (activeRequests >= context.policy.maxConcurrentRequests) { return deniedResponse( `concurrent requests ${activeRequests} exceed max ${context.policy.maxConcurrentRequests}`, ); } activeRequests++; try { const response = await registered.handler(request); if (response.payload.length > context.policy.maxResponseBytes) { return deniedResponse( `response payload ${response.payload.length} exceeds max ${context.policy.maxResponseBytes}`, "error", ); } const entry: BrokerAuditEntryV1 = { schema: "werkstatt/broker-audit-entry@1", requestId: request.requestId, callerId: context.callerId, workloadId: context.workloadId, artifactHash: context.artifactHash, grantSetHash: context.grantSet.grantSetHash, capability: request.capability, status: response.status, timestamp: context.timestamp, redactedDiagnostics: response.diagnostics, }; audit.push(entry); return response; } catch (err) { return deniedResponse( `handler error: ${err instanceof Error ? err.message : String(err)}`, "error", ); } finally { activeRequests--; } }, auditLog(): readonly BrokerAuditEntryV1[] { return [...audit]; }, registeredCapabilities(): readonly CapabilityId[] { return [...capabilities.values()].map((c) => c.capability); }, }; }