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
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…
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
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

Browser Native Messaging Bridge (macOS)

Claude Desktop silently installs a Native Messaging host manifest (com.anthropic.claude_browser_extension.json) into the configuration directories of multiple Chromium-based browsers — Chrome, Edge, Brave, Arc, Vivaldi, Opera, and others — including browsers not present on the device at install time. The manifest pre-authorizes specific extension IDs to communicate with a local Rust binary (chrome-native-host, 2.1 MB, universal x86_64+arm64) running outside the browser sandbox at user privilege. No disclosure is made during installation. No consent is requested.

The associated Chrome extension requests three permissions that together cover the same traffic as the Cowork MITM:

debugger
Attach Chrome DevTools Protocol to any tab
Full read/write of page state, network, storage
Operates outside normal extension sandbox
<all_urls>
Content script injection into any page
DOM access, form reads, screen capture
No per-site consent required
webRequest on api.anthropic.com
Intercept all requests to api.anthropic.com
Read request bodies before they leave the browser
Browser-layer analog to Cowork TLS interception

The full signal path from browser to system:

Chrome extension (sandboxed JS)
chrome.runtime.connectNative()chrome-native-host (Rust, outside sandbox, user privilege)
Unix domain socket → Claude Desktop main process
WebSocket bridge → MCP servers
* Rust binary runs outside browser sandbox. webRequest listener sits on api.anthropic.com at the browser network layer.
Independent discovery timeline

This surface was mapped in January 2026: native host identification, multi-browser pre-registration across browsers not yet installed, and webRequest interception capability on api.anthropic.com documented in session logs. Public coverage appeared approximately three months later.

The browser-layer interception is the direct macOS analog to the Cowork TLS MITM documented above. One operates inside the VM at the TLS layer via an installed CA. The other operates inside the browser at the network request layer via a pre-authorized extension. Both reach the same Anthropic API traffic. The mechanism differs; the capability does not.

Critical Data Flow Traces

User input to process execution
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
Process output to UI
user process stdout
sdk-daemon event stream
subscribeEvents (ANY caller)
claude.exe UI update
* event stream open to unsigned clients
VM process calling api.anthropic.com
vm process: fetch api.anthropic.com
sdk-daemon MITM proxy
TLS decrypt (own CA)
inspect plaintext API call
re-encrypt → forward
GitHub access from VM
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 restoration)
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

Key Findings

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.

Scope of interception

The interception applies to every process running inside the VM that makes a TLS connection to *.anthropic.com — this includes the AI model completions endpoint, authentication, telemetry, and any other Anthropic service on that domain. The CA certificate is installed as a trusted root inside the guest. There is no opt-out available to guest processes: they cannot distinguish the proxy's re-encrypted response from a response from the real endpoint using standard TLS verification, because the proxy's CA is in their trust store. Any process inside the VM therefore sees the intercepted connection as legitimate TLS.

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.

Observation without authentication compounds with execution

There are two distinct capabilities on the cowork-svc pipe: the ability to command (create VMs, spawn processes, read files) and the ability to observe (receive stdout, stderr, exit codes, and network events from running processes). The command surface requires the Anthropic-signed claude.exe certificate. The observation surface does not.

This asymmetry means that while arbitrary processes cannot control the VM, they can watch everything it produces in real time. Any local process — including third-party tools, MCP servers spawned by Claude Desktop, or background services — can subscribe to the event stream and receive the output of whatever is executing in the VM. Output that contains file contents, code, AI responses, or credentials is delivered to any subscriber without authentication.

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.

The writable path is not bounded to a single directory

The restoration event documented here involved one specific directory. The mechanism — the updater detecting file hash drift and writing back through the guest-to-host mount — is not specific to that path. The mount gives the guest access to host paths configured at VM startup. Any file in any path accessible through that mount can be monitored for drift and restored.

The restoration operates without user interaction or notification. The parent process does not emit a signal when a restoration occurs. The only indication is the file change event in a filesystem monitor, which is how the 23:15 event was identified here.

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.

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.

Certificate validation is an authentication gate, not a behavioral boundary

The mutual TLS authentication on cowork-svc methods establishes that only the signed claude.exe binary can issue commands to the VM. It does not constrain what those commands can do, what the VM produces, or who can observe that output.

The cert architecture answers the question: "who is allowed to act?" It does not answer: "what is the acting party allowed to do?" and it explicitly does not apply to observation at all. These are three different security questions, and the cert architecture addresses only the first.

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.

The SYSTEM-privileged service surface persists regardless of VM availability

When Hyper-V is absent or disabled, cowork-svc cannot start a VM. The service still runs at SYSTEM privilege and holds the named pipe open. The subscribeEvents endpoint still accepts connections. The SYSTEM-privileged service surface with an unauthenticated observation endpoint is present on the machine regardless of whether the VM capability is active.

VM-gated methods returning auth errors reduces the attack surface but does not eliminate the SYSTEM-privileged process or the unauthenticated event stream.

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)  ·  x01-capability-restructuring

The Capability Evaluator and the Writable Path

A capability evaluator is a component that analyzes a system — typically by examining its binaries, network behavior, and process structure — and produces a structured description of what the system can do. Its value depends entirely on its independence from the system it is evaluating. An evaluator that can be modified by the system it monitors is not an independent observer; it is a component of the system, and its output can be shaped by the system's behavior.

A later analysis page documents that after the cowork audit was published, the evaluator used to analyze the sandbox's capability surface was modified to prevent it from confirming two of the capabilities the audit identified. The capabilities remained in the evaluator's dependency graph. The tests were modified to ensure the evaluator would not qualify the prerequisite needed to detect them.

There is a further structural point not documented on that page.

The evaluator's repair pathway — the code that would restore the pre-modification detection behavior — is stored in a directory that the updater mechanism has demonstrated write access to. The 23:15 restoration event documented above shows that mechanism writing back to a host directory autonomously when file hash drift is detected.

This means the component designed to detect what the infrastructure is doing contains, in a path the infrastructure can write to, the code that would restore its ability to detect the infrastructure's behavior.

Structural Finding The evaluator's source, its test suite, and its repair pathway are all potentially within the write surface of the system they are intended to monitor. Whether that surface has been used for that purpose is not established by the presented evidence. That it exists is.