Environment audit · Google AI Studio

The sandbox that isn't a sandbox

Google AI Studio's Antigravity environment is routinely compared to agent code-execution sandboxes and scored as if it were one. It isn't. It is a Cloud Run container that hosts the app you are building, and almost every apparent weakness follows from that — not from a failure to harden.

probed 2026-07-24 runtime gVisor / Cloud Run region europe-west3 rev v1

§1 What this environment is for

Read the process tree before reading the findings. It settles the threat model.

PID 1   /bin/bash ./start.sh
PID 5   nginx: master process          → :8080  ingress + auth bridge
PID 6   /app/control-plane-api/…       → :8000  Go orchestration API
PID 47  npm run dev --host 0.0.0.0     → :3000  Vite dev server (the user's app)
PID 19  tail -f /dev/null                       keeps PID 1 alive

That is a web application host. start.sh templates an nginx config, starts nginx, starts a Go control plane, waits for /health, then blocks on tail -f /dev/null until a signal arrives. There is no tool dispatcher, no subprocess broker, no policy gate on execution.

The reframe

Anthropic's sandboxes and Kimi's exist to run untrusted code safely. AI Studio's exists to serve a preview of the app under construction, to the right viewer. Its security engineering is concentrated almost entirely on ingress — who may load the iframe — rather than on egress or execution.

Scored on containment against dedicated execution sandboxes, it looks careless. Scored against what it is, most of the gap is category difference rather than negligence. The findings below are calibrated accordingly.

§2 Substrate

gVisor, and what gVisor looks like from the inside.

IsolationgVisor (runsc) on Google Cloud Run
Kernel stringLinux localhost 4.19.0-gvisor #1 SMP Sun Jan 10 15:06:54 PST 2016
Base OSDebian 12 (bookworm), largely unminimised
CPU / RAM2 vCPU (model masked as unknown) · 4 GB, no swap
Root filesystemoverlay, reported 378 GB
Process identityroot (uid 0); only nginx workers drop to nobody
Persistenceephemeral overlay only — no FUSE, no remote mounts

Two artifacts confirm gVisor rather than a conventional container, and both are useful fingerprints:

Read the disk figure carefully

/, /dev, /dev/shm and /tmp each report 378 GB. That is one synthesised figure repeated across four overlay mounts, not four large volumes. Treat 378 GB as an artifact of the gVisor filesystem layer rather than a provisioned allowance.

§3 Where the security work actually went

The nginx Lua auth bridge is the most engineered component in the environment, and the audit reports mostly skip it.

All ingress lands on nginx :8080, and every request to / passes through access_by_lua_file /etc/nginx/user_auth_verification.lua — annotated in the config as strictly necessary and never to be removed. The script:

Only after that does traffic reach the Vite dev server on :3000, with an AI Studio iframe script injected into the HTML response. The control plane is exposed under its own prefix and proxied to :8000.

The finding worth leading with — and it isn't the metadata server

The Lua script honours an environment variable, DISABLE_AUTH_BRIDGE. When set to true, authentication is skipped entirely. The in-file comment states plainly that this removes authentication for the container and that anyone holding the URL can then access it, and restricts it to internal evaluation containers where an autorater cannot authenticate.

This is a deliberate, documented, correctly-warned switch — not a bug. It is nonetheless the highest-consequence control in the environment, because a single misapplied environment variable converts an authenticated preview into an open one. It deserves more attention than a metadata endpoint that behaves exactly as Cloud Run always does.

§4 Networking and egress

Interfaceslo 127.0.0.1/8 · eth1 169.254.8.1/32 · eth2 169.254.9.1/32, 169.254.169.1/32
DNS169.254.169.254, search domain google.internal.
Egress policynone — no proxy variables, no allowlist, no TLS interception
Observedgoogle.com 301 · registry.npmjs.org 200 · api.anthropic.com 404 (reached; 404 is that host's own response to a bare request)

The absence of any RFC-1918 address, and the reliance on link-local 169.254.x.x interfaces, is the standard signature of GCP serverless networking. Egress is entirely open: the environment makes ordinary outbound TLS connections with no interception, which is the opposite of both Anthropic postures and of Kimi's browser-only proxy.

§5 Findings, recalibrated

The original audit rated two findings "high". Neither survives contact with the evidence in the same probe.

Severity reassessment
FindingAs filedCalibratedReasoning
Metadata server reachable at 169.254.169.254; OAuth token extractable high by-default · mitigated Every Cloud Run container can reach the metadata server; this is platform default, not something AI Studio introduced. The control is IAM scoping, and the same probe session confirmed it holds — testIamPermissions and run.services.list both returned 403 PERMISSION_DENIED, and Cloud Resource Manager is SERVICE_DISABLED on the project. Blast radius is contained by design.
Model API key injected as a plaintext environment variable high real, severity undetermined The mechanism is genuine: any transitive npm dependency in the Vite app can read process.env and, with unrestricted egress, ship it anywhere. Severity turns entirely on whether the key is a disposable per-applet credential or a shared platform key — the probe never established which, so "high" is unearned. The question is answerable and worth answering.
DISABLE_AUTH_BRIDGE disables ingress authentication wholesale not filed design risk — highest consequence Documented and warned in-file, restricted by intent to eval containers. Still the single switch whose misapplication most directly exposes a user's application.
Agent processes run as root (uid 0) low low — agreed gVisor's syscall interception is doing the real containment work. Dropping privileges would still be better hygiene.
Unrestricted egress high correct as fact, mis-framed as defect Accurate and worth stating. But an app-preview host that cannot reach the internet cannot serve most applications. The finding belongs in the threat-model discussion, not the vulnerability list.

What the recalibration is not saying

None of this means the environment is safe for arbitrary untrusted code. It plainly is not: root execution, open egress, and secrets in the process environment compose badly. The correction is to the framing — these are properties of a preview host being used as though it were an execution sandbox, not defects in an execution sandbox.

§6 Software environment

ToolStatusNote
Node.jsv22.23.1runs the Vite dev server
npm10.9.8
Python3.10.12oldest Python of the four environments surveyed
nginx + Luapresentndk and http-lua modules enabled
Rust / Go toolchainsabsentthough the control plane is a statically linked Go binary (not a dynamic executable)
Dockerabsent
ippresent at /usr/sbin/ipsee §7 — the source audit claims otherwise
ifconfig / netstatabsent

The toolchain is narrow and deliberate: full-stack JavaScript with Python alongside. Nothing here supports systems work, which is consistent with §1.

§7 Evidence quality

This is a self-probe. The same caveats apply as to every other environment audit in this series.

ClaimStanding
gVisor runtime, process tree, nginx and Lua configuration, start.sh contentshigh — read directly from disk
Egress unrestrictedhigh — three destinations, three successful responses, no proxy in env
Metadata reachable; IAM scoped to denyhigh — token retrieved, two API calls returned 403
"ip is absent from $PATH"contradicted — the same transcript shows which ip resolving to /usr/sbin/ip and ip a returning full interface output
378 GB diskartifact — repeated across four mounts; a gVisor reporting quirk, not a provisioned figure
Service account permissions "likely scoped tightly"partially tested — two APIs denied; the account's full IAM binding set was never enumerated
Cross-session persistenceuntested

Redactions in this document

The source transcript contained a live model API key and a live OAuth bearer token. Both are replaced here with redacted; the OAuth token had a 1799-second lifetime and is long expired, and the API key has been revoked. Applet-specific identifiers and the generated Cloud Run preview URL are also generalised, since they identify a particular session rather than the platform.

§8 Summary

RuntimegVisor (runsc) container on Cloud Run, europe-west3
Compute2 vCPU · 4 GB · ephemeral overlay
Ingressnginx + Lua token verification against aistudio.google.com
Egressunrestricted; no proxy, no allowlist, no interception
Identitymetadata reachable by platform default; service account IAM scoped to deny the APIs tested
Best used forgenerating and previewing full-stack JS/TS applications
Not suited toexecuting untrusted third-party code — open egress plus secrets in the process environment compose badly

The instructive comparison is not "is this weaker than Claude's sandbox." It is that two products can share a substrate class and diverge entirely on where they spend their security budget. AI Studio spent nearly all of it on ingress. That is a coherent choice for a preview host, and a poor fit for the execution-sandbox role it is increasingly asked to fill.