P1: Enforce cross-VM host isolation, extract the sandboxed proxy, add capsem proxy, and document the architecture
- Dominant language
- Rust
- Stars
- 72
- Forks
- 13
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 5
Description
## Status and scheduling
**P1 — queued; product implementation is blocked on SDK and OCI/network integration completion.**
- [ ] PR #199 lands and its SDK integration issues are resolved. It is still OPEN at this update.
- [x] PR #200 landed (2026-09-15).
- [ ] Confirm the replacement switch and OCI/network lifecycle verification are complete, including relevant authenticated OCI control integration in #207.
- [ ] Re-audit the landed code before changing product files.
- [ ] Coordinate architecture documentation with the new documentation site rebuild following SDK completion.
Do not interrupt the active SDK/network work or fold this refactor into it. This issue is the comprehensive follow-up, expanding the previous #206 scope. #201 supplies the original MITM privilege finding; its proposed owner-side evaluator is superseded by the proxy ownership specified here. #207 retains ownership of the active OCI HTTP-control migration; do not duplicate it here.
On pickup, create dedicated Sprinty implementation items for platform confinement, proxy extraction, proxy exposure, verification, and documentation. The backlog specification/dependency check is tracked separately from the existing release sprint.
## Goal
Complete Capsem's host-side isolation so a compromised VM, or a host worker processing its traffic, cannot access another VM's files, credentials, control sockets, or unrelated networks.
Extract the existing MITM, security enforcement, logging, and telemetry pipeline into sandboxed proxy workers. Reuse that engine for both VM interception and a new `capsem proxy` command exposing an OpenAI-compatible API endpoint.
Deliver a clean architecture page for the rebuilt documentation site, describing the implemented system rather than the historical design. MCP becomes a client on top of the SDK, outside the core runtime architecture.
## Problem and security contract
The source audit found explicit OS confinement around `capsem-router` switches and published-port relays, but incomplete host boundaries elsewhere:
- HTTP gateway: authenticated separate process, without application-installed OS confinement.
- VM owners: cleared inherited environments, but still the launching user's filesystem/socket authority.
- MITM and DNS: inside the process holding VM control and hypervisor resources.
- Documentation: 0700 directories and 0600 sockets incorrectly described as preventing sibling same-UID access.
Library separation, parent watching, authentication, and environment clearing are useful controls, not substitutes for an OS sandbox.
Assume malicious guest traffic and potential code execution inside a guest-facing host worker. Its resulting authority must be limited to its assigned VM, proxy session, or network. The coordinator and host kernel remain trusted. Intentional communication between members of the same network follows that network's contract. Standalone proxy clients are not themselves sandboxed.
A compromised worker must also be unable to trick the coordinator into acting for another session: broker IPC authorization is part of the containment boundary, not merely input validation.
## Required implementation
### 1. Enforce process authority
Define and implement each process's permitted files, descriptors, listeners, upstream connections, IPC operations, credentials, and lifetime owner.
| Process | Required authority |
|---|---|
| `capsem-service` | Trusted lifecycle coordinator and capability broker |
| HTTP gateway | API listener, necessary control/terminal channels, narrow runtime/log access |
| VM owner | One VM's virtualization resources, session, read-only assets, required IPC |
| Proxy worker | One VM or standalone proxy session's traffic, policy, credentials, telemetry |
| Network switch | One network's attachments and forwarding control |
| Published-port relay | Explicitly granted connections for its owning VM |
- [ ] Apply appropriate confinement on macOS and Linux, preserving required VZ/KVM operations without unrelated session access.
- [ ] Clear worker environments and close unrelated inherited descriptors.
- [ ] Prefer scoped descriptor grants and narrow broker operations over access to entire runtime directories.
- [ ] Install confinement before untrusted input or readiness; fail startup, terminate, and reap on confinement failure.
- [ ] Bind capabilities to trusted session identity and generation. Never authorize from a worker-supplied VM ID, path, or network ID alone.
- [ ] Make cancellation close resources and join/reap owned tasks and children.
- [ ] Retain and verify existing confined switches/relays rather than replace them unnecessarily.
Gateway confinement needs its own policy: it must accept connections and use authorized service/terminal channels. Do not copy the descriptor-only router policy blindly. Preserve SDK gateway authentication; the coordinator must also enforce the authority of its control connection.
### 2. Extract one reusable proxy implementation
- [ ] Move MITM/TLS/HTTP processing, traffic rules/plugins, provider routing, credential integration, logging, and telemetry out of the VM owner.
- [ ] Run one confined proxy worker per VM; each standalone invocation gets an independent session/worker. Share implementation, not unrestricted authority across sessions.
- [ ] Keep the coordinator on configuration, scoped grants, and lifecycle. Do not relay every HTTP body, packet, or audit record through a central coordinator.
- [ ] Keep database execution/storage in `capsem-logger`; give workers only their logging capability or permitted session storage. No separate logging daemon is required. No route-owned SQLite access or projection caches.
- [ ] Relocate guest-facing DNS into the confined networking/proxy responsibility, preserving private-name resolution and upstream DNS semantics.
- [ ] Preserve rules/plugins, credential handling/redaction, streaming/cancellation/backpressure/timeouts, upstream errors, usage and session attribution, audit visibility/flushing, and VM boot/restart/stop/recovery.
- [ ] Remove superseded in-process handlers and all unconfined fallbacks.
Provision only the keys/certificates and credential capabilities required by that worker. The threat model must state that a compromised proxy holds its own session's granted authority, never another session's authority. Scoped upstream connection capability must not become arbitrary dialing.
### 3. Add `capsem proxy`
Expose the shared processing engine as an **OpenAI-compatible API endpoint**: configure an existing OpenAI SDK client's `base_url` to point at it.
- [ ] Use the existing profile/provider model to select upstream and security configuration.
- [ ] Configurable bind address and port; default loopback, OS-assigned port. Report usable base URL and proxy-session identity.
- [ ] Start without booting a VM.
- [ ] Preserve supported OpenAI-compatible surfaces, including Chat Completions and Responses where supported by the landed engine, streaming, and cancellation.
- [ ] Route only to configured provider authority; client headers/payloads cannot create an arbitrary-destination relay or forge trusted VM identities.
- [ ] Use existing scoped credentials and redaction.
- [ ] Keep the data listener separate from the authenticated SDK/control gateway.
- [ ] Stopping the command stops its listener/worker, cancels active requests, and completes bounded audit shutdown.
- [ ] Register the new command in the public-surface contract; update help, examples, and relevant schemas without unrelated API changes.
**The proxy listener is unauthenticated by design. Remote binding is supported; deployment/network controls own access restriction. Do not introduce proxy authentication.** SDK gateway authentication remains independent and mandatory.
**No standalone forward-proxy mode, CONNECT, transparent host interception, or client CA installation.** Transparent interception belongs inside Capsem VMs. This supersedes the previous forward-proxy/client-trust wording of #206.
Standalone mode controls and audits only model traffic sent through its endpoint. It cannot prevent an unrestricted agent from bypassing it or observe all host files, tool execution, or other network connections. State that limit accurately.
### 4. New documentation architecture page
- [ ] Write a canonical page for the rebuilt site based on the landed implementation, not the historical manual.
- [ ] Show actual processes separately from libraries/threads, and distinguish control, private-network, and proxied-traffic paths.
- [ ] Explain per-VM/per-network/global ownership and each sandbox's permitted and denied capabilities.
- [ ] Cover gateway, coordinator, VM owner, switch, relay, proxy, and MCP above the SDK.
- [ ] Show VM interception and standalone API access as adapters to the same processing engine.
- [ ] Explain policy, credentials, logging/telemetry, revocation, failure/recovery, OS differences, and verified limitations.
- [ ] Include a working SDK `base_url` example.
- [ ] Correct misleading same-UID isolation claims in developer references and replace/redirect contradictory pages through the new site's publication workflow.
Do not restore the old documentation site merely to publish this page. If the rebuild is not ready, retain reviewed content/diagrams as an explicitly pending deliverable and do not claim publication complete.
## Verification and acceptance
### Effective confinement and cross-VM denial
Use test-owned fixtures to demonstrate behavior, not merely inspect configuration:
- [ ] Worker A cannot read/write B's session, obtain B's credentials, open B's control endpoints, or forge access by changing identifiers.
- [ ] A switch cannot access another network's attachments or VM control.
- [ ] Gateway/proxy workers cannot execute arbitrary processes, signal unrelated processes, open arbitrary host files, or establish ungranted outbound connections.
- [ ] Necessary operations still work under confinement on macOS and Linux.
- [ ] Deliberately failed confinement prevents readiness and traffic acceptance.
- [ ] Compromised-worker/broker requests cannot expand authority beyond trusted session/generation grants.
### Functional integration
- [ ] Real VM/OCI workloads retain interception, policy, credentials, private networking, and telemetry behavior.
- [ ] Python and TypeScript OpenAI SDK clients work with hermetic upstreams through the standalone base URL.
- [ ] Verify supported streaming/non-streaming APIs, cancellation, tool-call payloads, usage, and upstream failures.
- [ ] Denied requests reach no upstream; exact audit facts identify session/provider/decision/outcome. Preserve existing fail-closed enforcement/audit-admission semantics.
- [ ] Standalone mode starts no VM and implements no CONNECT/forward-proxy route.
- [ ] Remote binding is unauthenticated as specified; SDK gateway authentication remains effective.
- [ ] Exercise the new CLI and documentation examples through real entrypoints.
### Chaos and lifecycle
Use Greyjoy-style fault injection and retain earlier review regressions:
- [ ] Kill a proxy while its VM and another VM are active; effects remain scoped.
- [ ] Restart workers without reusing stale credentials/grants/session identity.
- [ ] Exercise disconnect/reconnect races and network retirement.
- [ ] Stall clients/upstreams, interrupt streams, and exhaust bounded queues.
- [ ] Repeat creation/destruction without accumulating processes, descriptors, tasks, or buffers.
- [ ] Verify bounded audit shutdown and failure handling without bypassing policy.
### Completion gates
- [ ] Required focused tests and platform gates pass on the final candidate.
- [ ] No security behavior regression, unconfined fallback, or duplicate proxy implementation.
- [ ] Architecture diagram/capability table match the actual implementation.
- [ ] Documentation/examples verified against the final SDK; publication status explicit.
- [ ] User-visible changes have a changelog entry.
- [ ] Remaining trust assumptions and standalone proxy limitations are explicit.
**This issue is complete only when boundaries are enforced and tested—not when code is merely moved into subprocesses.**
## Related work and historical requirements
- #199: SDK dependency.
- #200: merged OCI/private-network origin; verify final switch/lifecycle evidence at pickup.
- #201: original MITM privilege finding, covered by this implementation scope; do not build its earlier alternative owner-side evaluator.
- #207: authenticated OCI/exposure control migration, owned by the active integration work.
- #203: ledger decision correctness, relevant to preserving exact audit behavior.
- The earlier #206 requested exposure/preview enforcement consistency. Preserve the behavior landed by #207 and its separate preview origin; do not duplicate preview orchestration or create a second evaluator in this issue.
Previous #206 description — historical; superseded where it conflicts with the accepted plan above
## Problem
Capsem's MITM proxy, private networking, published ports, authenticated previews, and requested standalone proxy all need the same policy, plugin, credential, attribution, and audit behavior. Today the MITM assembly assumes a VM/vsock owner while private connections and port exposure have separate orchestration. Extending those paths independently risks inconsistent enforcement and ledger evidence.
## Desired architecture
- Introduce a security session that is independent of VM lifecycle.
- Keep transport adapters responsible only for establishing trusted caller, source, destination, and workload facts.
- Reuse the existing `SecurityEvent` rule/plugin rail, credential broker, ledger materialization, and logger-owned database boundary.
- Preserve the confined router/descriptor-handoff data plane. Service and VM owners must not become workload-byte proxies.
- Support VM egress, private networking, port exposure, browser previews, and standalone forward-proxy traffic through the shared runtime.
- Retrofit the exposure HTTP API and scoped MCP exposure tool from PR #199 onto the shared runtime.
## Security requirements
- Standalone clients cannot claim trusted VM, process, network-member, or exposure identities.
- An enforcement error or failure to admit the primary audit event refuses the action.
- Runtime materialization may contain required credentials; ledger materialization contains only redacted/brokered values.
- Preview content remains isolated from the administrative gateway origin.
- A standalone proxy enforces only traffic routed through it; bypass prevention requires separate client confinement and must be described accurately.
- Low-privilege workers receive only scoped descriptors and configuration: no gateway administrator token, registry credentials, unrestricted filesystem access, CA private key, or virtualization entitlement.
## Acceptance criteria
- Allowed, denied, failed, closed, restored, and revoked operations have correlated operation, VM/security-session, exposure, connection, caller, and trace identifiers.
- Denied traffic never reaches its destination.
- Revocation terminates active HTTP streams, WebSockets, and raw TCP flows.
- Audit tests use the logger flush barrier and prove exact route/ledger output without opening SQLite from routes or helpers.
- Tests prove credential and token redaction and reject identity spoofing.
- Standalone HTTP/HTTPS proxy use works without booting a VM and uses explicitly provisioned client trust.
## Related work
- PR #199: typed gateway SDKs and interaction contracts.
- PR #200: private VM networks and OCI workloads.
Contributor guide
Research direction
Start by resolving the stated dependencies on PR #199, PR #200, and issue #207, then audit the existing VM, proxy, gateway, and confinement implementation before creating the separate Sprinty work items. Use the capsem proxy entry point, Python and TypeScript OpenAI SDK clients, and Greyjoy-style fault injection as verification paths. Done means scoped confinement, reusable proxy behavior, lifecycle tests, and architecture documentation all match the acceptance checks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust, typescript
- Domain
- api, backend, cli, documentation, networking, security, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100