Anthropic Engineering

Claude를 가두는 법 — claude.ai·Claude Code·Cowork의 containment 설계

에이전트 능력이 커질수록 blast radius도 커진다. 사람 감독은 93% 승인률의 approval fatigue로 새기 마련이라, 행동이 아니라 '할 수 있는 것'을 막는 containment가 핵심. claude.ai의 ephemeral container·Claude Code의 OS 샌드박스·Cowork의 로컬 VM 패턴, 그리고 실제로 뚫렸던 사고들(신뢰 이전 실행·사용자 경유 주입·승인 도메인 유출·EDR 불가시성)의 교훈.

How we contain Claude across products

생각 덩어리

12개월 만에 뒤집힌 계산 — 질문은 blast radius의 상한

Twelve months ago, we'd have rejected out of hand the idea of granting Claude access sufficient to take down an internal Anthropic service. Today that level of access is routine, and Anthropic developers are more productive for it.

The risk of these deployments has two components: how likely a failure is, and how much damage one could do. Progress on safeguards and model training has steadily driven down the first; the second—the theoretical blast radius—only grows as capabilities and access expand.

Yet as agents become capable of doing work that once required a person or even a team, the cost of not deploying grows large enough that the risk-reward calculation tips heavily toward adoption, as long as products can be made safe. The engineering question becomes how to cap the blast radius.

감독에서 봉쇄로 — 93% 승인률과 approval fatigue

Our telemetry showed users approved roughly 93% of permission prompts. The more approvals a user sees, the less attention they pay to each, becoming over time much less diligent in their supervision.

Still, vulnerabilities remain—any probabilistic defense has a non-zero miss rate.

Rather than supervising what the agent does, we supervise what it’s able to do by enforcing access boundaries through, for example, sandboxes, virtual machines, and egress controls.

This is where Anthropic engineering has devoted the most effort, and also where many of the most surprising security failures have occurred.

세 가지 위험 — 사용자 오용 · 모델 일탈 · 외부 공격자

This includes everything from asking the agent to bypass a check they find annoying, to running a destructive command they don’t understand, to specifying intentional harm.

More capable models make fewer mistakes, but they’re also better at finding unexpected paths to a goal, often by routing around restrictions nobody thought to write down.

At Anthropic, we’ve seen Claude models “helpfully” escape a sandbox in order to complete a task, examine git history to find answers to a coding test, and spontaneously identify the benchmark it was being run on in order to decrypt its answer key.

방어의 세 지점 — 환경 · 모델 · 외부 콘텐츠

For example, if credentials never enter the sandbox, they can't be exfiltrated, regardless of whether the cause is a user, a model finding a “creative” path, or an attacker.

Because models are probabilistic, these shape only what the agent tends to do, not what it is theoretically capable of doing.

On Gray Swan's Agent Red Teaming benchmark, which tests susceptibility to prompt injection, Claude Opus 4.7 holds attack success to roughly 0.1% on single attempts, and around 5–6% after 100 adaptive attempts. ... Yet even with best-in-class defenses, protection in the model layer will never be 100% effective, which is why it can't stand alone.

An audited connector isn’t the same as audited data—a GitHub connector, for instance, can load a poisoned README straight into the model’s context despite passing malware checks.

Pattern 1: claude.ai의 일회용 컨테이너 — 가장 약한 층은 직접 만든 층

When Claude runs code inside claude.ai, it does so in a gVisor container on isolated infrastructure. The agent is entirely server-side; no code runs on the local machine, and the filesystem is ephemeral (per-session).

We're not protecting user machines from agents; we're protecting our own infrastructure and each tenant from one another.

That work reinforced the oldest lesson in security: the weakest layer is the one you built yourself. gVisor and seccomp have been hardened against well-resourced adversaries for far longer than agentic AI has existed, so the review effort went into the newer pieces we'd built around them.

Pattern 2: Claude Code의 human-in-the-loop 샌드박스 — 개발자라서 성립하는 전략

This is only a tractable solution for Claude Code because the average user is a developer who’s familiar with coding environments: they can read bash, they understand what rm -rf does, and they already run npm install from untrusted sources several times a week.

Claude Code launched with the simplest possible defense: allow reads, require approval for write, bash, and network access.

we shipped an OS-level sandbox (Seatbelt on macOS, bubblewrap on Linux) that hardens the boundary: reads are allowed, writes are allowed inside the workspace, but network is denied by default. ... The result was an 84% reduction in permission prompts, and we open-sourced the runtime, so the boundary is auditable.

experienced users auto-approve roughly twice as often as new users, but they also interrupt the agent mid-execution more frequently. Instead of gating individual steps, experienced users are more likely to supervise the agent only when it goes off track.

놓친 위험: 신뢰 다이얼로그 이전에 실행되는 코드

Because Claude Code reads project settings during startup—before presenting the standard "Do you trust this folder?" prompt—the hook the attacker had authored and committed would execute automatically.

The fix in each case had the same shape: defer parsing and execution of project-local configuration until after the user accepts the trust prompt.

treat project-open, config-load, and localhost listeners the way you'd treat any inbound request from the internet. They shouldn’t be implicitly trusted just because they feel local and arrive before the user has consented.

놓친 위험: 사용자가 곧 주입 벡터 — 25번 중 24번 유출

The phish looked like ordinary collaboration—a "can you run this for me?" email with a ready-to-paste prompt attached—and the prompt itself read like routine task instructions. But somewhere among the setup steps, it gently asked Claude to read ~/.aws/credentials, encode the contents, and POST them to an external endpoint. Across 25 retries of that prompt, Claude completed the exfiltration 24 times.

Our model-layer defenses anchor on user intent—when the user is the one typing the instruction, there's nothing anomalous for a classifier to catch. A human contractor handed the same script would have done the same thing.

The only defense that holds in this situation is the environment, specifically egress controls that block the POST regardless of intent and filesystem boundaries that keep ~/.aws out of reach in the first place.

작동하는 프롬프트를 내부 Slack에 공유하자, 일부 내부 에이전트가 Slack을 읽는다는 지적이 나왔다. 페이로드는 이미 ambient가 됐고, 스레드에 canary string을 심어 감지를 걸었다.

In a world where agents read everything, the investigation tooling is also an attack surface.

Pattern 3: Cowork의 로컬 VM — 탈출구 열쇠를 쥔 프로세스가 없다

a non-technical knowledge worker shouldn’t be expected to judge bash incantations such as find . -name "*.tmp" -exec rm {} ;. When approving an exception requires expertise the typical user doesn’t have, admins should set a boundary that is absolute and always-on.

The user's selected workspace and .claude folder are mounted; nothing else on the host is visible. Credentials stay in the host's keychain and never enter the guest machine.

In the original architecture—what we call full-VM mode—the agent loop itself ran inside the guest, so Claude executed as an ordinary Linux user with no awareness it was sandboxed.

Compare this to Claude Code, where a privileged process sits outside the sandbox deciding per-command whether to enforce it; a persuasive injected prompt or a fatigued approval click can get that process to run something un-sandboxed. Here, there was no outer process holding an escape-hatch key, and so no component with the authority to grant an exception.

full-VM의 타협 — 에이전트 루프와 MCP는 밖으로, 코드 실행은 안으로

any failure during VM startup made Cowork unusable. Moving the agent loop outside of the VM, while keeping code execution inside of it, allowed Claude to still respond to the user and help debug issues rather than freeze on an error.

Running them inside the VM made them harder to audit, created brittle dependency issues when the VM updated, and didn’t support MCPs that required interaction with local processes such as databases

We found that offering different file-mount modes helps to granularly control risk; Claude Cowork offers read-only, read-write, and read-write-no-delete.

One potential gotcha here is that symlink resolution has to happen before path validation, not after, or a symlink inside an authorized folder can point outside and escape.

놓친 위험: 승인된 도메인으로의 유출 — allowlist는 capability grant다

a malicious file placed in the user's mounted workspace carried hidden instructions along with an API key controlled by the attacker. Claude, following the instructions, read other files in the workspace and called Anthropic's Files API using the attacker's key. The egress proxy checked the destination, saw api.anthropic.com, and let it through. The files were uploaded to the attacker's Anthropic account. The sandbox worked perfectly, and yet the data was exfiltrated.

Previously, we’d conceptualized the allowlist as a destination filter, something that told Claude these domains are okay to talk to. But it may be better conceptualized as a capability grant. Every function reachable through any domain on an allowlist is now an attack surface. Allowing api.anthropic.com meant allowing file uploads to arbitrary Anthropic accounts.

We fixed it using a defensive man-in-the-middle proxy inside the VM that intercepts traffic to our API. It only passes requests carrying the VM's own provisioned session token; an attacker-embedded key is rejected by the proxy.

This is also a second instance of the principle that the software you build yourself is often the weakest. The hypervisor, seccomp, and gVisor across our products have been dependable. Our custom allowlist proxy was the piece that failed.

놓친 위험: 격리가 EDR도 막았다

When evaluating Claude Cowork, enterprise security teams asked, "Why can't our EDR see inside?"

the same isolation keeping Claude contained also kept host-based endpoint detection and response out. From the EDR's perspective, Claude Cowork is an opaque hypervisor process. It can't inspect the guest.

Our current mitigation is to use pull-based OTLP exports that let administrators retrieve event logs after the fact, but this is not the same as live monitoring. If you're building something similar, budget for this conversation early.

에이전트가 읽는 것의 신뢰 — 원격 툴은 승인 후에도 변한다

Any external resource provided to an agent represents two risks at once: a code execution risk, in the traditional supply-chain sense, and a prompt injection vector. Traditional dependency auditing (pinning versions, verifying signatures, reviewing source) addresses the first, but misses the second.

A locally installed tool is auditable. You can read the code, pin the version, and know it won't change under you. A remote tool—a hosted MCP server, a cloud connector—can change behavior at any point after you’ve approved it; your install-time trust decision may no longer apply.

we err toward live inspection: once a poisoned tool return has steered the agent into exfiltrating data, the log just shows a successful, authorized API call. There's no after-the-fact signal to find.

The classifier that does the inspection can be a small, fast model; it doesn't need to be the one doing the reasoning.

다가오는 위험 — 메모리 오염 · 멀티에이전트 신뢰 격상 · 에이전트 신원

The share of agent context that persists across sessions keeps growing—this includes product memory, CLAUDE.md files, mounted workspaces, and the state directories of scheduled and long-running agents. An injection that lands in any of these is reloaded each time the agent starts.

if a sub-agent's output is treated as higher-trust than raw tool results, because such output came from “us,” a new vector for prompt injection is introduced.

Should an agent possess its own principal identity, or should it act as an extension of the user and inherit the user’s permissions? Ultimately, the answer may be a blend of the two.

원칙 — 확률이 다 빗나갈 때 맞아주는 건 결정론적 경계

Design for containment at the environment layer first, then steer behavior at the model layer. ... In each, the model layer couldn't help; there was nothing anomalous for it to catch. The deterministic boundary is what gets hit when everything probabilistic misses.

Match isolation strength to the user's capacity for oversight. A developer who can read bash and a knowledge worker who can't are not running the same threat model.

Battle-tested hypervisors, syscall filters, and container runtimes have survived more adversarial attention than anything you'll build. Across every deployment described here, the standard primitives held while our own work around them exposed flaws.

They still read files, open sockets, and spawn processes; this makes containment with mature tooling a crucially viable defense.

원본 사이트 →