Environment probe · comparative analysis · rev 3

claude.ai chat / Cowork / Kimi / AI Studio

Four agent environments, each probed from the inside. Three are built to run untrusted code; the fourth only looks like it is. The clearest signal of intent in all four is not the toolchain but the egress policy.

compiled 2026-07-24 chat 06-10 cowork 07-24 kimi 07-23 ai studio 07-24
containment agent capability chat microVM · 4 tools cowork microVM · dev agent kimi container · full desktop off axis ai studio gVisor · app preview host
Cowork is not a midpoint — it occupies the expensive high-containment / high-capability corner, which is what the TLS-terminating proxy, commit-signing hooks and off-by-default Docker daemon are for. AI Studio is drawn off the axis deliberately: it is not competing on containment, because it was never built to run untrusted code. Plotting it alongside the other three would make a category difference look like a failure.
claude.ai chat Claude Cowork Kimi Google AI Studio · different threat model

§1 Substrate & isolation

Where the boundary sits, and how much sits above it.

Platform
Dimensionchatcoworkkimiai studio
Isolation modelFirecracker microVMFirecracker microVMcontainerd container (K8s pod)gVisor (runsc) on Cloud Run
Kernelown guest, 6.18.5own guest, 6.18.5shared host, 5.10.134user-space kernel, 4.19.0-gvisor
PID 1process_api (Rust)process_api (Rust, vsock)s6-svscan/bin/bash ./start.sh
Root filesystemext4ext4 + 2× ro squashfsoverlayfs, 114+ layersoverlay (378 GB — a gVisor reporting artifact)
Base OSUbuntu 24.04.4 · 20260410Ubuntu 24.04.4 · same serialDebian 12 on LifseaOSDebian 12, largely unminimised
Instance marker--wiggle----remote_cowork--numeric instance IDCloud Run K_SERVICE / K_REVISION
Agent uidrootrootrootroot (nginx workers drop to nobody)

The gVisor cross-reference

Anthropic's public containment write-up describes claude.ai code execution as gVisor, while direct probing of the chat sandbox finds Firecracker. AI Studio is useful here precisely because it is unambiguously gVisor, and shows what that leaves behind: df /var/log returning Function not implemented, and a CPU model reported as unknown. Neither fingerprint appears in the chat sandbox.

That does not resolve the discrepancy — both may be true of different code paths — but it does establish what the gVisor case looks like from inside.

Hardening flags

Settingchatcoworkkimiai studio
init_on_free=1setnot setnot setn/a — no guest kernel
nomodulesetsetnot setn/a — modules impossible under gVisor
SELinuxn/a (VM)n/a (VM)selinux=0n/a
Kernel auditn/an/aaudit=0n/a
Spectre IBRSdefaultdefaultnoibrshost-managed
Syscall interceptionhardware VThardware VTnonefull — gVisor's core mechanism
Loopback bypassblockedblockedsshd on 0.0.0.0:22n/a — loopback is the architecture

gVisor and Firecracker are different answers to the same question, and both are credible: one intercepts syscalls in user space, the other gives the guest its own kernel behind a hardware boundary. Kimi's shared host kernel with mitigations disabled is the outlier — not because containers are unsound, but because that particular flag set spends containment on performance.

§2 Compute & storage

Cowork figures from the 2026-07-24 probe. See §6 for week-over-week drift.

Dimensionchatcoworkkimiai studio
CPUXeon @ 2.80 GHzXeon @ 2.80 GHzXeon Platinum @ 2.50 GHzmasked (unknown)
Cores1 vCPU2 vCPU2 vCPU2 vCPU
RAM3.9 GB7.8 GB4.0 GB4.0 GB
Swap / GPUnone / nonenone / nonenone / nonenone / none
Disk252 GB252 GB, 30 GB avail40 GB378 GB reported — see note
Python / Node3.12.3 / 22.22.23.11.15 / 22.22.23.12.12 / —3.10.12 / 22.23.1
User-data transport4× rclone FUSElocal ext4FUSE portalnone — overlay only
Persistencerclone cache non-determinismephemeral; durability via gitoverlay ephemeral; backend unobservablefully ephemeral, no mechanism exposed

Don't quote the 378 GB

/, /dev, /dev/shm and /tmp all report 378 GB in the AI Studio probe. That is one synthesised number repeated across four overlay mounts — a gVisor filesystem-layer artifact, not a provisioned allowance. It is not comparable to chat and Cowork's 252 GB block device.

§3 Egress — the axis that separates all four

Same component class, four different intentions.

Dimensionchatcoworkkimiai studio
Mechanism403 intercept, x-deny-reasonTLS-terminating MITM + Anthropic CABright Data residential proxynone
Intentrestrict reachrestrict reach, across many toolchainsextend reach past anti-bot defencesno policy — reach is unconstrained
Exit IPsAnthropic infraAnthropic infrarotating residential ISPs (TH, ID)Google infra, direct
Metadata endpointnot testedhard-blockednot reportedreachable — token extractable
Anti-detectionnonenoneautomation flags stripped, UA spoofednone
Scopeall trafficall trafficbrowser onlyall traffic, unfiltered
Ingress controln/an/asshd, key-onlynginx + Lua token bridge — where the security work went

Cage, disguise, and absence

Anthropic's proxies are a cage. They exist so the agent cannot reach things. Kimi's is a disguise — it exists so the agent can reach things that would otherwise block it, via residential exit IPs and stripped automation fingerprints. That design is internally coherent: exposing the pool to Chromium but not to Python stops arbitrary code from abusing the IP pool. It carries a third-party consent question, since traffic exits through real consumer connections.

AI Studio has neither, and that is the point of §4: it spent its budget somewhere else entirely.

§4 AI Studio is not a peer — and scoring it as one is a category error

Read the process tree before reading the findings.

PID 1 is a shell script that starts nginx, starts a Go control plane, waits for /health, and then blocks on tail -f /dev/null. Behind nginx sits a Vite dev server — the application being built. There is no tool dispatcher and no execution policy gate, because the product's job is to host a preview of your app and control who can load it, not to run adversarial code safely.

Nearly all of its security engineering is on ingress: every request to / passes an nginx Lua script that validates a token against aistudio.google.com, caches results in a shared dict, retries around token-minting replication lag, rejects javascript: return URLs, and carries a dedicated fallback for iOS Safari's cross-site cookie blocking. That is careful work. It is simply pointed at a different threat.

Severity, recalibrated

FindingAs filedCalibratedWhy
Metadata server reachable; OAuth token extractable high default · mitigated Every Cloud Run container reaches 169.254.169.254; platform default, not an AI Studio choice. The control is IAM scoping, and the same session confirmed it holds — two API calls returned 403 and Cloud Resource Manager is SERVICE_DISABLED.
Model API key in plaintext environment high real, severity undetermined Mechanism is genuine — any transitive npm dependency reads process.env, and egress is open. But severity depends on whether the key is per-applet disposable or shared platform, which the probe never established.
DISABLE_AUTH_BRIDGE switches off ingress auth entirely not filed highest-consequence control Documented and warned in-file, intended for eval containers. Still the one variable whose misapplication turns an authenticated preview into an open one. It went unmentioned in the source audit.
Unrestricted egress high accurate fact, mis-framed True and worth stating — but a preview host that cannot reach the internet cannot serve most applications. This belongs in the threat-model discussion, not the vulnerability list.

What the recalibration does not say

AI Studio is still unsuitable for running untrusted third-party code. Root execution, open egress and secrets in the process environment compose badly, and that combination is real. The correction is to the framing: these are properties of a preview host being used as an execution sandbox, not defects in an execution sandbox.

§5 Product posture

Four product classes, not four sizes of one thing.

Dimensionchatcoworkkimiai studio
Runtime on top4-tool interfaceClaude Code CLI 2.1.218s6 stack + Jupyter kernelnginx + Go control plane + Vite
Interaction modelone-shot tool executionagent: MCP, hooks, sub-agents, scheduled tasksremote desktop: Xvnc + Chromium + pyautoguiapp preview served through an auth bridge
BrowserPlaywright, headlessPlaywright + Chrome automationChromium 149 on a real X displaynone — the browser is the user's
DatabasesnoneRedis + Postgres 16.13, in-boxnot reportednone
Containersabsentpresent, daemon off, Hub blockednot reportedabsent
Systems toolchaingcc, JavaRust, Go, strace, lsofminimal imagenone — JS/TS and Python only
Reach to user's machinenoneremote-devices bridgeSSH in, key-onlynone
Git posturea capabilitycentral — commit signing, stop hooksnot reportednot a concern of the product

Reading the four

chat — hardened ephemeral scratchpad. Reason, generate documents, run short code.

cowork — git-native software-engineering agent. Docker tooling, proxy trust bundle and signing hooks all exist to run a general dev toolchain under one policy gate.

kimi — multimodal desktop agent. It gives the model a screen and a mouse rather than a CLI; the browser, VNC and residential proxy all follow from that.

ai studio — application preview host. It gives the model a web server and gives the user an authenticated URL.

Cowork and Kimi are closer in ambition to each other than either is to chat, reached by opposite routes: Cowork hands the agent a developer's terminal, Kimi hands it a user's desktop. AI Studio hands it neither.

§6 Cowork drift — week over week

2026-07-15 → 2026-07-24. Only fields that moved.

Field07-1507-24
claude_cli2.1.2102.1.218
agentclaude-code_2-1-210_agentclaude-code_2-1-218_agent
runnerstaging-a54e7c22brelease-1186d93b9-ext
cpuXeon @ 2.10 GHzXeon @ 2.80 GHz
https_proxy127.0.0.1:45919127.0.0.1:39185

What the drift says

staging → release. The most consequential field. The 07-15 findings were taken against a pre-release runner and should not be assumed to describe the shipping environment; anything load-bearing from that run is worth re-confirming.

Proxy port rotates per session. 45919 → 39185 is ephemeral binding, not a config change. Read $https_proxy at runtime; never hard-code it.

Clock is a per-session draw. 2.10 → 2.80 GHz is fleet heterogeneity, not a spec change — and 2.80 GHz happens to match the chat sandbox, which mildly strengthens the shared-substrate reading.

Unchanged: init_on_free still not set, Docker daemon still off, kernel still 6.18.5, base image still serial 20260410. The substrate is stable; only the product layer moved.

§7 Evidence quality & corrections

Every source here is a self-probe. The shared failure mode is over-reading strings output — mistaking a build-toolchain artifact embedded in a binary for the binary's own implementation.

Corrections to the chat whitepaper (2026-06-10)

ClaimStatusBasis
rclone-filestore is RustwrongStrings show crypto/internal/fips140, go.shape.*, zeebo/xxh3 — it is Go, as rclone has always been.
chat has a Rust nightly toolchainover-readNo installed rustc was ever found; that was a version string inside a shipped binary.
sudo absent in chatuntestedNever probed. Not observed-absent.
chat egress does not terminate TLSuntested403s observed; MITM never checked for.
process_api is RustholdsCargo registry paths, hyper, jsonwebtoken.

Corrections to the AI Studio audit (2026-07-24)

ClaimStatusBasis
"ip is absent from $PATH"contradictedThe same transcript shows which ip resolving to /usr/sbin/ip, and ip a returning full interface output.
378 GB diskartifactRepeated identically across four mounts; a gVisor reporting quirk.
Service account "likely scoped tightly"partially testedTwo APIs denied; the account's full IAM binding set was never enumerated.
Two findings rated "high"recalibratedSee §4. Neither survives the evidence in the same probe.

Confidence in the Kimi report

ClaimConfidence
Bright Data proxy — vendor-specific response fields, five distinct exit IPs, residential ASNshigh — near-conclusive
Chrome launch flags, process table, s6 stack, boot cmdlinehigh — directly observable
FUSE portal backend protocollow — explicitly speculative
Cross-session persistencelow — backend not observable
Absent tooling (strace, lsof)low — self-reported untested

Still unresolved

Anthropic's public containment write-up describes claude.ai code execution as gVisor; direct probing finds Firecracker. AI Studio now gives us a control case for what gVisor leaves behind — and those fingerprints are absent from the chat sandbox. Both statements may still be true of different code paths. Flagged, not resolved.

Separately: Cowork's claude binary is Bun-compiled, and Bun v2.1.181+ ships the Zig→Rust port of Bun itself, so 2.1.218 embeds a Rust-generation runtime. The discriminating probe — Rust vs Zig markers in the embedded runtime — still has not been run. This is a rewrite of Bun, not of Claude Code, and is unrelated to process_api's Rust.

§8 Summary

IsolationEgress intentAgent surfaceBuilt to
chatmicroVM + init_on_freerestrict4 toolsrun untrusted code safely
coworkmicroVMrestrict, elaboratelyfull dev agentrun untrusted code safely, at toolchain scale
kimishared kernel, mitigations offextendfull desktopoperate a browser like a person
ai studiogVisor syscall interceptionnonenone — it hosts, not executesserve your app to the right viewer

Containment and capability trade against each other, and the first three sit at deliberate points on that curve. The fourth is on a different curve altogether — which is the most useful thing this comparison shows, and the thing a straight vulnerability count would have hidden.