Claude Desktop — Cowork Sandbox Architecture

Reconstructed from binary analysis, pipe interrogation, asar extraction • 2026-02-19

Windows Host
claude.exe (Electron/Chromium) Win32 SYSTEM cert
Signed: Anthropic, PBC
Thumbprint: dbde5d16768ed0c1...
Renderer process (Claude UI)
IPC → main process → cowork-svc pipe
Client certificate embedded in binary
Only binary that can authenticate to cowork-svc
cowork-svc.exe (Windows Service) Go binary SYSTEM
Named pipe: \\.\pipe\cowork-vm-service
Transport: uint32-BE length + JSON
Auth: mutual TLS cert verification on ALL methods
EXCEPT: subscribeEvents — open to any caller
Methods: configure, createVM, startVM, stopVM,
  isRunning, isGuestConnected, spawn, kill,
  writeStdin, isProcessRunning, mountPath,
  readFile, installSdk, addApprovedOauthToken,
  setDebugLogging, subscribeEvents
Persistent: survives MCP restarts, Claude sessions
! VM support DISABLED on this machine (win32/x64)
Bundle Assets Resources
smol-bin.x64.vhdx — 36 MB
default.clod — 96 KB
Contains: sandbox-helper, sdk-daemon
Linux ELF64 binaries for guest
Also loose on C:\Users\sethi\:
  sandbox-helper (2 MB)
  sdk-daemon (7.7 MB)
sdk-daemon sha256: e232357e...
sandbox-helper sha256: 8c6c5a22...
HCS/HCN API → Hyper-V
virtiofs / Plan9 mounts
subscribeEvents (open) — stdout/stderr/exit/network stream
Linux VM Guest
Hyper-V VM (Linux) rootfs.vhdx
Boot: vmlinuz + initrd from claudevm.bundle
/mnt/.virtiofs-root → host share mount
virtiofs: host dirs → guest mountpoints
sharedCwdPath: project dir mounted read-write
additionalMounts: per-spawn host paths
Session disk: per-conversation overlay VHDX
User: created via useradd, uid/gid from host
sdk-daemon ELF64 / root
MITM proxy: /var/run/mitm-proxy.sock
TLS intercept: *.anthropic.com
CA cert: /usr/local/share/ca-certificates/mitm-proxy-ca.crt
Network allowlist enforced (srt-settings.json)
GitHub: proxied but NOT TLS-stripped
OAuth tokens: must be approved via addApprovedOauthToken
[updater] detects file changes: old hash vs new hash
coworkd: manages virtiofs mounts, user creation
Event stream: stdout / stderr / exit / networkStatus / apiReachability
Wire: goproxy (MITM library)
sandbox-helper ELF64 / setuid priv-drop
sandbox-helper <uid> <gid> <cmd> [args...]
Reads: /etc/srt-settings.base.json
setuid → setgid → exec(command)
Pipe: stdout/stderr → sdk-daemon event stream
Shell-escapes args (al.essio.dev/shellescape)
BuildSrtCommand: assembles safe shell invocation
Purpose: drop from root to user UID before exec
allowlisted traffic (npm, pypi, github, ubuntu, crates.io)
MITM api.anthropic.com: TLS decrypt → inspect → re-encrypt
blocked: everything not in allowedDomains
Internet
Package Registries
registry.npmjs.org
pypi.org / pythonhosted.org
crates.io
yarnpkg.com
archive/security.ubuntu.com
Proxied, not TLS-stripped
GitHub OAuth tokens need approval
api.anthropic.com
Full TLS interception by sdk-daemon
Every API call decrypted + inspected
Proxy CA installed as trusted root
Claude API, Statsig, Sentry
*.anthropic.com wildcard
github.com
Allowlisted, not TLS-stripped
OAuth token checked against approvedTokens
Token passed via addApprovedOauthToken
git clone, API calls, repo access
Proxy sees all traffic patterns + timing
Everything Else
BLOCKED by sdk-daemon allowlist
deniedDomains: [] (allowlist is the gate)
allowLocalBinding: true
[proxy] blocking request - domain not allowed
Critical Data Flow Traces
User types in Claude UI
claude.exe renderer
IPC → main process
cowork-svc pipe (Anthropic cert)
sdk-daemon spawn()
sandbox-helper uid/gid
user process
user process stdout
sdk-daemon event stream
subscribeEvents (ANY caller)
claude.exe UI update
* event stream open to unsigned clients
vm process: fetch api.anthropic.com
sdk-daemon MITM proxy
TLS decrypt (own CA)
inspect plaintext API call
re-encrypt → forward
vm process: git push (GitHub)
sdk-daemon proxy
check approvedTokens list
forward (TLS not stripped)
* token must be whitelisted via addApprovedOauthToken from claude.exe
sdk-daemon [updater]
file change detected (old hash != new hash)
event: type=update, old=..., new=...
subscribeEvents stream
claude.exe handler
* candidate explanation for 23:15 tool-cdn restoration
MITM on *.anthropic.com
sdk-daemon installs its own CA certificate and performs full TLS interception on all traffic to *.anthropic.com from inside the VM. Every API call — including Claude completions, auth tokens, and telemetry — is decrypted, inspectable, and re-encrypted before leaving the machine. This is by design: Anthropic can inject headers, observe prompts, enforce policy, or modify responses at the proxy layer.
subscribeEvents: No Auth
The only unauthenticated method on the cowork-svc pipe. Any process can subscribe and receive real-time stdout/stderr/exit/network events from whatever the VM is running. On machines where the VM is active, this leaks all process output — including AI responses, code execution results, and file contents — to any local listener.
Tool-CDN Restoration (23:15)
sdk-daemon's [updater] compares old vs new file hashes. When catabolism.js was modified (breaking exeray-mcp.js), the updater detected drift from the original deployment hash and triggered restoration via the virtiofs mount — writing back through the guest-to-host share. Writer PID null in RDCX because the Go process exits before chokidar processes the notification.
GitHub OAuth Token Gate
GitHub traffic is proxied but not TLS-decrypted. However, OAuth tokens are intercepted and validated against an in-memory approved list managed by cowork-svc via addApprovedOauthToken. Tokens must be explicitly passed from claude.exe. The proxy logs: [proxy] added approved OAuth token (hash: %x...) on each addition.
VM Disabled on This Machine
cowork-svc logs VM not supported (win32/x64) — Hyper-V is either absent or disabled. The service runs with SYSTEM privileges and holds the pipe open but cannot start a VM. All VM-gated methods return auth errors from our probes. The subscribeEvents endpoint returns success:true then immediately closes — no active sessions.
Cert Architecture
cowork-svc embeds the expected client thumbprint (dbde5d16768ed0c1) and validates every connection except subscribeEvents. Claude.exe is signed by Anthropic, PBC and passes. Node.js (OpenJS Foundation) fails. This prevents MCP servers or arbitrary local processes from controlling the VM — all VM operations must flow through the signed Electron binary.
Sources: app.asar extraction (index.js vm-client code) • cowork-svc.exe pipe interrogation (80 probes) • sdk-daemon-strings.json (20,422 strings) • sandbox-helper-strings.json (6,242 strings) • srt-settings.json • audit-nexus fs_events (625,806 rows) • cowork-event-feed active (PID 2388)