Split View: AWS Lambda MicroVMs — 에이전트가 짠 코드를 VM 격리로 실행한다는 것, 그리고 스냅샷이 만드는 새 문제
AWS Lambda MicroVMs — 에이전트가 짠 코드를 VM 격리로 실행한다는 것, 그리고 스냅샷이 만드는 새 문제
- 들어가며 — 에이전트가 짠 코드를 어디서 실행할 것인가
- Lambda MicroVMs가 실제로 무엇인가
- 빠른 시작의 정체 — 부팅하지 않고 스냅샷에서 되살아난다
- 스냅샷의 대가 — 유일해야 할 것이 유일하지 않다
- VMGenID가 고치는 것과 고치지 못하는 것
- VM 경계가 막지 않는 것
- 숫자에 관한 정직한 이야기
- 대안 — gVisor 쪽은 어떻게 하고 있나
- 언제 쓰지 말아야 하나
- 마치며
- 참고 자료
들어가며 — 에이전트가 짠 코드를 어디서 실행할 것인가
LLM에게 코드를 짜게 하는 것까지는 이제 쉬운 축에 듭니다. 어려운 건 그 코드를 실행하는 쪽입니다. 모델이 방금 만들어 낸 코드는 정의상 리뷰를 거치지 않았고, 프롬프트 인젝션 한 방이면 사용자가 의도한 적 없는 코드가 됩니다. 이걸 어디서 돌릴 것인가는 취향 문제가 아니라 격리 경계를 어디에 그을 것인가의 문제입니다.
컨테이너는 이 자리에 잘 맞지 않습니다. 이유는 하나뿐입니다 — 커널을 공유하니까요. namespace와 cgroup, seccomp를 아무리 조여도 테넌트 A의 코드와 테넌트 B의 코드는 같은 커널의 시스템 콜 인터페이스를 두드립니다. 그 인터페이스에서 하나만 터지면 경계가 통째로 무너집니다. 그래서 이 문제를 진지하게 다루는 곳들은 결국 더 아래로 내려갔습니다 — 하드웨어 가상화, 또는 사용자 공간 커널로.
AWS가 2026년 6월 22일 Lambda MicroVMs를 내놓은 게 그 맥락입니다. 새로운 격리 기술은 아닙니다 — Firecracker는 2018년부터 있었고 Lambda 자체가 그 위에서 돕니다. 새로운 건 파는 방식입니다. Firecracker의 격리·스냅샷·수명주기를 직접 다루는 원시 요소로 꺼내 주되, 하이퍼바이저는 여전히 AWS가 운영합니다.
이 글은 제품 소개가 아니라 경계에 관한 글입니다. 이 경계가 정확히 무엇을 막고, 무엇을 막지 않으며, 스냅샷이라는 구현 선택이 어떤 새 문제를 데려오는지를 봅니다.
Lambda MicroVMs가 실제로 무엇인가
AWS 컴퓨트 블로그(2026년 7월 10일, Kulkarni·Agarwal·Madan)가 설명하는 모델은 이렇습니다.
- MicroVM 이미지 — Dockerfile과 코드를 zip으로 묶어 S3에 올리면, Lambda가 그 Dockerfile을 실행하고, 애플리케이션을 띄우고, 완전히 초기화된 상태의 Firecracker 스냅샷을 뜹니다. 버전이 붙는 아티팩트입니다.
- MicroVM — 그 이미지에서 온디맨드로 띄우는 개별 인스턴스. 세션당, 사용자당, 잡당 하나씩 줍니다.
API는 create-microvm-image, run-microvm, suspend-microvm, resume-microvm, terminate-microvm, delete-microvm-image로 단출합니다.
aws lambda-microvms run-microvm \
--image-identifier arn:aws:lambda:us-east-1:123456789012:microvm-image:analytics-notebook \
--idle-policy '{"maxIdleDurationSeconds":300,"suspendedDurationSeconds":28800,"autoResumeEnabled":true}' \
--maximum-duration-in-seconds 28800 \
--region us-east-1
검증되는 스펙만 추리면 이렇습니다. 개발자 가이드의 사이징 표가 출처입니다.
베이스라인 → 피크(자동 4배 수직 확장) 최대 디스크
0.5 GB / 0.25 vCPU → 2 GB / 1 vCPU 8 GB
1 GB / 0.5 vCPU → 4 GB / 2 vCPU 8 GB
2 GB / 1 vCPU (기본) → 8 GB / 4 vCPU 8 GB
4 GB / 2 vCPU → 16 GB / 8 vCPU 16 GB
8 GB / 4 vCPU → 32 GB / 16 vCPU 32 GB
여기서 흔한 오해를 하나 정리해 둡니다. 여기저기서 인용되는 "32GB / 16vCPU"는 베이스라인이 아니라 가장 큰 베이스라인의 피크입니다. 메모리만 설정하면 vCPU는 2GB당 1개 비율로 따라오고, 피크는 베이스라인의 4배까지 자동으로 올라갑니다. AWS 뉴스 블로그의 표현은 "up to 16 vCPUs, 32 GB of memory, and 32 GB of disk per MicroVM"이고, 이게 그 뜻입니다.
나머지 경계 조건들:
- ARM64 전용. x86 없습니다.
- 5개 리전 — 버지니아 북부, 오하이오, 오리건, 아일랜드, 도쿄.
- 최대 8시간(28,800초). 세션 수명이자 유휴 서스펜드 보존 한도입니다.
- 각 MicroVM은 전용 HTTPS 엔드포인트를 받고, HTTP/1.1·HTTP/2·WebSocket·gRPC·SSE를 지원합니다. 인증은
create-microvm-auth-token으로 발급하는 JWE 토큰을X-aws-proxy-auth헤더에 실어 보냅니다. 토큰에는 허용 포트와 만료가 박힙니다.
VM 경계이기 때문에 가능한 게 하나 있는데, 이건 진짜 장점입니다. additionalOsCapabilities를 ["ALL"]로 주면 파일시스템 마운트, 네트워크 네임스페이스 생성, eBPF 실행 같은 것들이 열립니다. 문서의 문장이 정확합니다 — "Capabilities are applied within the VM isolation boundary and do not affect the host or other MicroVMs." 샌드박스 안에 사실상 루트를 줘도 호스트가 안전한 건, 그 아래에 하이퍼바이저가 있기 때문입니다. 컨테이너로는 이 거래를 할 수 없습니다.
빠른 시작의 정체 — 부팅하지 않고 스냅샷에서 되살아난다
"near-instant startup"의 실체는 부팅을 안 하는 것입니다. Lambda SnapStart에서 쓰던 기법 그대로입니다 — Firecracker 스냅샷에서 재개합니다.
이미지 빌드 시점에 Lambda가 하는 일은 순서대로 이렇습니다. 베이스 이미지에서 새 MicroVM을 띄우고, Dockerfile을 실행하고, ENTRYPOINT/CMD로 앱을 띄우고, 초기화 완료를 라이프사이클 훅으로 확인한 뒤, 디스크와 메모리 상태의 스냅샷을 뜹니다. 훅은 두 개입니다.
/ready → /aws/lambda-microvms/runtime/v1/ready
앱이 스냅샷 찍혀도 되는 상태인지. 503이면 재시도, 200이면 스냅샷.
/validate → /aws/lambda-microvms/runtime/v1/validate
빌드 후, 그 이미지로 띄운 새 MicroVM에서 재개 정상 동작 확인.
/validate 훅에는 문서에 적힌 숨은 용도가 있습니다 — 여기서 목 페이로드를 돌리면 Lambda가 스냅샷의 어느 영역이 실제로 접근되는지 추적해서 시작 시 그 영역의 인출을 최적화합니다. 스냅샷 복원은 결국 메모리 페이지를 게으르게 끌어오는 일이고, 어느 페이지가 뜨거운지 미리 알려 주면 빨라진다는 이야기입니다.
스냅샷이 담는 것은 문서가 명시합니다 — 실행 중인 모든 프로세스의 메모리 상태(백그라운드 데몬, cron, 자식 프로세스 포함), 디스크 상태, 그리고 초기화된 네트워크 연결과 파일 디스크립터.
마지막 항목을 다시 읽어 보십시오. 여기서부터가 이 글의 본론입니다.
스냅샷의 대가 — 유일해야 할 것이 유일하지 않다
Lambda MicroVMs의 모델은 "하나의 이미지 → N개의 MicroVM"입니다. 즉 하나의 스냅샷에서 수백 개의 VM이 반복해서 재개됩니다. 이게 빠른 이유이자, 문제인 이유입니다.
Firecracker 자신의 문서가 이 패턴을 뭐라고 부르는지 그대로 옮깁니다.
When snapshots are used in a such a manner that a given guest's state is resumed from more than once, guest information assumed to be unique may in fact not be; this information can include identifiers, random numbers and random number seeds, the guest OS entropy pool, as well as cryptographic tokens. Without a strong mechanism that enables users to guarantee that unique things stay unique across snapshot restores, we consider resuming execution from the same state more than once insecure.
같은 상태에서 두 번 이상 재개하는 것을 "insecure"라고 못박습니다. 그리고 Firecracker 문서가 예시로 든 "잠재적으로 안전하지 않은 사용"의 형태가 — 하나의 스냅샷 S에서 microVM B, C를 각각 재개하는 것 — Lambda MicroVMs의 정상 동작 그 자체입니다.
AWS도 이걸 숨기지 않습니다. 스냅샷 문서의 문장입니다.
If your code generates unique content during image version build phase (unique IDs, secrets, or entropy for pseudorandomness), that content is shared across all MicroVMs run from the same image version.
구체적으로 어디서 터지는지 보겠습니다.
환경 변수. 문서에 따르면 환경 변수는 이미지 빌드 시점에 설정되고(최대 50개) 스냅샷 빌드 과정에서 컨테이너에 주입됩니다. 즉 환경 변수에 넣은 비밀은 그 이미지에서 뜨는 모든 테넌트의 MicroVM이 공유합니다. 컨테이너 습관대로 API 키를 env에 꽂으면, 멀티테넌트 샌드박스 전체가 같은 키를 보게 됩니다. 런타임에 주입하려면 run-microvm의 동적 페이로드를 써야 합니다.
난수와 암호 토큰. 빌드 시점에 만든 세션 ID, 시드, 토큰은 전부 복제됩니다. AWS의 처방은 "빌드가 아니라 MicroVM 시작 후에 생성하라"이고, 재설정용으로 /run 라이프사이클 훅을 제공합니다.
OpenSSL. 이게 가장 구체적인 함정입니다. 문서는 AWS 제공 베이스 컨테이너 이미지 public.ecr.aws/lambda/microvms:al2023-minimal을 쓰라고 합니다. 이유는 그 안에 "AWS-patched version of OpenSSL that is compatible with snapshotting"이 들어 있기 때문입니다. 자체 베이스 이미지를 쓴다면 Amazon Linux 2023의 openssl-snapsafe-libs 패키지를 직접 넣어야 합니다.
왜 OpenSSL만 특별 취급을 받을까요? 다음 절이 답입니다.
VMGenID가 고치는 것과 고치지 못하는 것
커널 쪽에는 해법이 있습니다. VMGenID는 게스트가 "나 방금 스냅샷에서 되살아났다"를 감지하게 해 주는 가상 장치입니다. 16바이트 난수 식별자를 게스트에 노출하고, 스냅샷 재개 때마다 하이퍼바이저가 그 값을 바꿉니다. Firecracker는 이 장치를 항상 활성화하고, 재개 시 새 16바이트 값을 쓴 뒤 vCPU를 재개하기 전에 게스트에 인터럽트를 넣습니다. Linux는 5.18부터(ACPI 기준, DeviceTree는 6.10부터) 이 값의 변화를 감지해 커널 내부 CSPRNG를 재시드합니다.
그래서 AWS가 안내하는 언어별 CSPRNG — Java 11+의 SecureRandom, Node.js의 crypto.randomBytes, Python 3.12+의 Secrets.SystemRandom, .NET 8+의 Cryptography.RandomNumberGenerator — 는 안전합니다. 공통점은 전부 /dev/random 또는 /dev/urandom을 통해 커널에서 엔트로피를 받는다는 것입니다. 커널이 재시드되니 이들도 갈라집니다.
문제는 커널을 거치지 않는 것들입니다. Firecracker 문서의 문장을 그대로 옮깁니다.
State other than the guest kernel entropy pool, such as unique identifiers, cached random numbers, cryptographic tokens, etc will still be replicated across multiple microVMs resumed from the same snapshot. Users need to implement mechanisms for ensuring de-duplication of such state, where needed.
will에 강조가 붙어 있는 건 원문 그대로입니다. VMGenID는 커널 엔트로피 풀만 고칩니다. 사용자 공간이 자기 엔트로피 풀을 따로 들고 있으면 — OpenSSL이 정확히 그렇습니다 — 그건 복제된 채로 남습니다. 그래서 openssl-snapsafe-libs라는 별도 패키지가 존재하는 것이고, 그래서 AWS가 베이스 이미지를 쓰라고 권하는 것입니다.
Firecracker의 엔트로피 문서는 이 한계를 더 솔직하게 인정합니다 — 사용자 공간 라이브러리들이 각자 엔트로피 풀을 유지하는 문제에 대해 "현재 프로그래밍 모델에서 일반적인 해법은 없으며, 우리가 할 수 있는 건 스냅샷 이전 로직에서 그것들을 쓰지 말라고 권고하는 것뿐"이라고 적혀 있습니다.
사용자 공간까지 알리는 표준화 작업은 진행 중입니다. VMClock 장치의 vm_generation_counter를 사용자 공간이 mmap()으로 감시하거나 poll()로 알림을 받을 수 있고, 이 지원은 Amazon 엔지니어(itazur@amazon.com)가 2026년 1월 30일 보낸 패치로 Linux 커널 v7.0에 머지됐습니다. Amazon Linux의 microvm 커널 5.10과 6.1 계열에는 백포트돼 있습니다. 다만 이건 "라이브러리가 이 장치를 감시하도록 고쳐져 있어야" 값을 합니다. 지금 당장 당신이 쓰는 라이브러리가 그렇게 돼 있을 가능성은 낮습니다.
정리하면 스냅샷 재개 시 유일성의 책임 분담은 이렇습니다.
커널 엔트로피 풀 → VMGenID가 자동 재시드 (Linux 5.18+) [해결됨]
/dev/urandom 쓰는 CSPRNG → 커널을 타므로 자동으로 안전 [해결됨]
OpenSSL 등 자체 엔트로피 풀 → 패치된 빌드 필요 (openssl-snapsafe-libs) [부분 해결]
앱이 만든 ID·토큰·시드 → 아무도 안 고쳐 줌. /run 훅에서 직접 재생성 [당신 책임]
빌드 시점 환경 변수 → 스냅샷에 그대로 박힘. 런타임 주입으로 회피 [당신 책임]
마지막 두 줄이 이 글에서 가장 중요한 부분입니다. VM 격리 경계는 이 문제에 대해 아무것도 해 주지 않습니다. 테넌트 간 커널 탈출을 막는 것과, 테넌트들이 같은 시드를 보는 것은 전혀 다른 층위의 문제입니다.
VM 경계가 막지 않는 것
스냅샷 문제를 다 해결했다고 칩시다. 그래도 VM 경계가 막지 않는 게 남아 있고, 실무에서는 이쪽이 더 자주 사고를 냅니다.
기본값이 열린 인터넷입니다. 네트워킹 문서의 문장 그대로 — "By default, Lambda MicroVMs have public internet access on the egress path." 프롬프트 인젝션당한 에이전트가 샌드박스 안에서 자격증명이나 사용자 데이터를 읽어 curl로 외부에 쏘는 시나리오를 생각해 보십시오. VM 경계는 이걸 하나도 막지 않습니다. 하이퍼바이저 입장에서 그건 게스트가 정상적으로 하는 네트워크 I/O일 뿐입니다. 이그레스를 통제하려면 Lambda Network Connector로 트래픽을 자기 VPC로 돌려 보안 그룹과 NACL을 태워야 합니다. 즉 진짜 방어선은 하이퍼바이저가 아니라 당신이 짜는 네트워크 정책입니다.
이건 AWS만의 이야기가 아닙니다. Anthropic의 자체 호스팅 샌드박스 보안 문서는 같은 경계를 더 노골적으로 적어 뒀습니다 — "Without egress restrictions, a compromised tool execution can reach arbitrary external hosts." 그리고 "Anthropic이 대신 해 줄 수 없는 것" 목록에 이런 항목이 있습니다: "Isolate tools inside your sandbox. Anthropic's security boundary stops at the sandbox." 참고로 AWS 컴퓨트 블로그는 Lambda MicroVMs를 Claude Managed Agents의 자체 호스팅 샌드박스 공급자로 쓰는 패턴을 명시적으로 소개합니다 — 에이전트 루프는 Anthropic 쪽에, 도구 실행은 당신의 MicroVM에 두는 구성입니다.
IAM은 여전히 당신 몫입니다. 컴퓨트 블로그가 짚는 좋은 디테일이 하나 있는데, 빌드 타임 IAM 역할과 실행 타임 IAM 역할을 분리할 수 있다는 점입니다. 테넌트별 권한을 세밀하게 주려면 이걸 써야 합니다. VM 격리는 실행 역할이 과대 권한이면 아무 소용이 없습니다.
프롬프트 인젝션은 격리 문제가 아닙니다. 모델이 속아서 "허용된 일"을 하는 것을 하이퍼바이저가 알아챌 방법은 없습니다. VM 경계는 블래스트 반경을 줄이는 도구지, 에이전트가 판단을 그르치는 걸 막는 도구가 아닙니다.
숫자에 관한 정직한 이야기
시작 지연 숫자는 AWS가 주지 않습니다. 컴퓨트 블로그, 뉴스 블로그, 개발자 가이드를 다 훑어도 "near-instant startup", "resume within seconds", "starts within seconds" 같은 표현만 나옵니다. 밀리초 수치는 어디에도 없습니다. 그러니 여기서 숫자를 지어내지 않겠습니다 — 당신의 이미지 크기와 워킹셋으로 직접 재야 하는 값입니다. 스냅샷 복원이 페이지 인출에 비례한다는 걸 생각하면, 멀티 기가 워킹셋과 200MB짜리 이미지의 재개 시간이 같을 리 없습니다.
Firecracker 규모 숫자는 벤더 자체 주장입니다. "15 trillion+ monthly invocations"(개발자 가이드), "tens of trillions of requests each month for over 1.5 million customers"(컴퓨트 블로그) 모두 AWS가 자기 서비스에 대해 말하는 수치이고, 측정 조건은 공개돼 있지 않습니다. Firecracker가 대규모로 검증됐다는 정성적 근거로는 충분하지만, 그 이상으로 읽을 자료는 아닙니다.
비용은 계산할 수 있습니다. Lambda 요금 페이지의 us-east-1 ARM 기준 공개 요율은 이렇습니다.
vCPU $0.0000276944 / vCPU-second
메모리 $0.0000036667 / GB-second
스냅샷 쓰기 $0.0038 / GB (서스펜드)
스냅샷 읽기 $0.00155 / GB (시작·재개)
스냅샷 보관 $0.08 / GB-month
기본 베이스라인(2GB / 1vCPU)을 계속 켜 두면 초당 0.0000350278달러입니다. 시간당 약 $0.126, 하루면 약 $3.03, 30일이면 약 $91. 이건 베이스라인만 계산한 바닥값이고, 베이스라인 초과 사용분과 스냅샷·데이터 전송은 별도입니다. 참고로 InfoQ의 보도에 인용된 실무자 추정치도 하루 $3.03으로 같은 값이 나왔습니다 — 공개 요율에서 독립적으로 유도한 값이 일치하니 이 수치는 믿어도 됩니다. 같은 기사는 이게 Fargate 스팟의 9배가 넘는다는 지적도 인용합니다.
여기서 설계 함의가 나옵니다. 이 요금 모델에서 유휴 MicroVM을 켜 둔 채 방치하면 그냥 돈입니다. 서스펜드가 선택이 아니라 필수인 이유고, idle-policy가 API의 1급 시민인 이유입니다. 서스펜드하면 컴퓨트 과금이 멈추고 스토리지 요율만 남습니다. 반대로 강화학습 환경처럼 짧은 VM을 대량으로 돌리는 워크로드라면 시작마다 스냅샷 읽기 요금이 붙는다는 점을 모델에 넣어야 합니다.
운영 부담도 숫자로 옵니다. 베이스 이미지에는 폐기 주기가 있습니다 — DEPRECATED(60일) → EXPIRING(30일, 신규 이미지 생성 불가) → EXPIRED(빌드도 실행도 불가). 즉 이미지를 만들어 놓고 잊으면 언젠가 안 뜹니다. 재빌드는 정기 작업입니다.
대안 — gVisor 쪽은 어떻게 하고 있나
같은 문제를 다른 경계로 푸는 쪽도 봐야 공평합니다. Google은 2026년 5월 21일 GKE Agent Sandbox를 내놨습니다. 하드웨어 가상화 대신 gVisor — 시스템 콜을 사용자 공간에서 가로채는 커널 — 를 쓰고, 기본 거부 Kubernetes 네트워크 정책을 함께 겁니다. Kata Containers 같은 다른 샌드박스를 꽂을 수 있는 인터페이스도 있고, Kubernetes SIG 산하 오픈소스 프로젝트입니다.
Google이 주장하는 수치는 "클러스터당 초당 300개 샌드박스 할당, 서브초 지연, 할당의 90%가 200밀리초 내 완료"입니다. 벤더 자체 측정이고, 클러스터 구성 같은 조건은 블로그에 명시돼 있지 않습니다. "Axion에서 다른 하이퍼스케일러 대비 최대 30% 나은 가격 대비 성능"도 마찬가지로 Google 자체 비교입니다.
경계의 성격 차이는 분명히 해 둘 값이 있습니다. gVisor는 시스템 콜을 사용자 공간에서 재구현해 호스트 커널에 닿는 표면을 줄입니다. 얇고 빠르지만, 결국 소프트웨어가 커널 인터페이스를 흉내 내는 것이므로 그 소프트웨어 자체가 공격 표면입니다. Firecracker는 KVM 위의 진짜 VM이라 게스트가 자기 커널을 갖지만, 그만큼 무겁고 — 그리고 이 글의 절반을 차지한 스냅샷 문제를 데려옵니다. 어느 쪽이 "더 안전하다"는 문장은 조건 없이는 쓸 수 없습니다. 확실한 건 기본 거부 이그레스는 두 진영 다 별도로 챙겨야 한다는 것뿐입니다.
언제 쓰지 말아야 하나
쓰지 마십시오, 만약
- 실행하는 코드가 당신 코드라면. 신뢰 경계가 없는데 테넌트별 VM 값을 낼 이유가 없습니다. 하루
$3바닥값과 8시간 상한을 받아들일 근거가 안 됩니다. - 워크로드가 상태가 없고 짧다면. 스냅샷 수명주기·유일성 처리·서스펜드 정책이 전부 상태 보존을 위한 복잡도인데, 그걸 안 쓸 거면 그냥 Lambda 함수가 맞습니다.
- x86이 필요하다면. ARM64 전용입니다.
- 5개 리전 밖이 필요하다면.
- 세션이 8시간을 넘어야 한다면. 이건 상한이고 우회로가 없습니다.
- 이그레스를 못 잠글 거라면. 열린 인터넷 기본값 위에서 신뢰할 수 없는 코드를 돌리는 건, VM 격리를 샀지만 정작 중요한 문을 열어 둔 것입니다. 이건 "그냥 쓰지 마라"가 아니라 "이걸 안 할 거면 VM 격리에 돈 낼 이유가 없다"에 가깝습니다.
값을 하는 경우는 반대로 뚜렷합니다 — 사용자나 에이전트가 만든 코드를 테넌트별로 격리해 실행해야 하고, 세션이 길고 상태가 있고 유휴 구간이 있고, 샌드박스 안에 높은 OS 권한을 줘야 하며(스캐너처럼), 그러면서 Firecracker 인프라를 직접 운영할 생각은 없는 경우. 이 조합이 정확히 AWS가 겨냥한 자리이고, 실제로 그 자리에는 잘 맞습니다.
마치며
Lambda MicroVMs는 좋은 물건입니다. 다만 파는 것과 사는 것을 헷갈리면 안 됩니다. 파는 것은 하이퍼바이저 운영의 외주화입니다 — Firecracker의 격리와 스냅샷을 직접 굴리지 않고 API로 쓰는 것. 사는 것은 강한 테넌트 간 커널 경계이고, 그 경계는 실재하며 컨테이너로는 못 삽니다.
사지 못하는 것도 분명합니다. 스냅샷에서 되살아난 VM들이 같은 비밀과 같은 시드를 보지 않게 만드는 일은 여전히 당신 몫입니다. VMGenID는 커널 엔트로피 풀까지만 고쳐 주고, 그 위층은 Firecracker 문서가 직접 "복제된다"고 적어 뒀습니다. 이그레스도 당신 몫입니다 — 기본값이 열린 인터넷이니까요. IAM도, 프롬프트 인젝션도 마찬가지입니다.
그래서 이 제품의 진짜 교훈은 격리 기술 자체보다는 그 아래 있습니다. 빠르게 만든 구현 선택이 새로운 신뢰 가정을 만든다는 것. 부팅을 건너뛰려고 스냅샷을 쓴 순간, "모든 프로세스는 고유한 상태로 시작한다"는 40년 묵은 가정이 조용히 깨집니다. 하이퍼바이저는 그 사실을 모릅니다. 그걸 아는 건 문서를 끝까지 읽은 당신뿐입니다.
참고 자료
- AWS Lambda MicroVMs 출시 공지 (2026-06-22)
- Run isolated sandboxes with full lifecycle control: AWS Lambda introduces MicroVMs — AWS 뉴스 블로그
- Announcing Lambda MicroVMs — AWS 컴퓨트 블로그 (2026-07-10)
- Lambda MicroVMs 개발자 가이드 — 개요
- MicroVM 이미지 — 사이징 표·빌드 훅·베이스 이미지 수명주기
- Working with snapshots — 유일성·CSPRNG·OpenSSL 주의사항
- Networking — 기본 이그레스와 JWE 인증
- AWS Lambda 요금
- Firecracker — Snapshot support (스냅샷 보안과 유일성, VMGenID, VMClock)
- Firecracker — Entropy for Clones
- AWS Launches Lambda MicroVMs for Isolated Agent and User Code Execution — InfoQ
- Bringing you Agent Sandbox on GKE and Agent Substrate — Google Cloud 블로그 (2026-05-21)
- Claude Managed Agents — 자체 호스팅 샌드박스 보안 모델
AWS Lambda MicroVMs — Running Agent-Written Code Under VM Isolation, and the New Problem Snapshots Create
- Introduction — Where Should You Run the Code an Agent Writes
- What Lambda MicroVMs Actually Are
- The Truth Behind the Fast Start — Resuming from a Snapshot Instead of Booting
- The Price of Snapshots — When the Thing That Should Be Unique Isn't
- What VMGenID Fixes, and What It Doesn't
- What the VM Boundary Doesn't Block
- An Honest Look at the Numbers
- The Alternative — How the gVisor Side Handles This
- When Not to Use It
- Closing
- References
Introduction — Where Should You Run the Code an Agent Writes
Getting an LLM to write code is the easy part now. The hard part is running it. Code a model just generated hasn't been reviewed by definition, and one successful prompt injection turns it into code the user never intended. Where you run that code isn't a matter of taste — it's a question of where you draw the isolation boundary.
Containers don't fit well here, for one reason: they share a kernel. However tightly you lock down namespaces, cgroups, and seccomp, tenant A's code and tenant B's code still knock on the same kernel's system-call interface. One break in that interface and the whole boundary collapses. So anyone who takes this problem seriously has ended up going further down — to hardware virtualization, or to a userspace kernel.
That's the context for AWS shipping Lambda MicroVMs on June 22, 2026. It isn't a new isolation technology — Firecracker has existed since 2018, and Lambda itself already runs on top of it. What's new is how it's sold. AWS pulls Firecracker's isolation, snapshotting, and lifecycle out as raw primitives you handle directly, while AWS still operates the hypervisor.
This post isn't a product pitch — it's about the boundary. It looks at exactly what this boundary blocks, what it doesn't, and what new problem the implementation choice of snapshotting brings along.
What Lambda MicroVMs Actually Are
The model described by the AWS Compute Blog (July 10, 2026, Kulkarni, Agarwal, Madan) is this:
- MicroVM image — you zip up a Dockerfile and code, upload it to S3, and Lambda runs that Dockerfile, boots the application, and takes a Firecracker snapshot of the fully initialized state. It's a versioned artifact.
- MicroVM — an individual instance launched on demand from that image. You get one per session, per user, per job.
The API is small: create-microvm-image, run-microvm, suspend-microvm, resume-microvm, terminate-microvm, delete-microvm-image.
aws lambda-microvms run-microvm \
--image-identifier arn:aws:lambda:us-east-1:123456789012:microvm-image:analytics-notebook \
--idle-policy '{"maxIdleDurationSeconds":300,"suspendedDurationSeconds":28800,"autoResumeEnabled":true}' \
--maximum-duration-in-seconds 28800 \
--region us-east-1
Here's just the verifiable spec, sourced from the sizing table in the developer guide.
Baseline → Peak (auto vertical scale, up to 4x) Max disk
0.5 GB / 0.25 vCPU → 2 GB / 1 vCPU 8 GB
1 GB / 0.5 vCPU → 4 GB / 2 vCPU 8 GB
2 GB / 1 vCPU (default) → 8 GB / 4 vCPU 8 GB
4 GB / 2 vCPU → 16 GB / 8 vCPU 16 GB
8 GB / 4 vCPU → 32 GB / 16 vCPU 32 GB
One common misreading worth clearing up here. The "32GB / 16vCPU" figure quoted around the web isn't a baseline — it's the peak of the largest baseline. Set only the memory, and vCPU follows at a ratio of 1 per 2GB, with the peak auto-scaling up to 4x the baseline. The AWS news blog phrases it as "up to 16 vCPUs, 32 GB of memory, and 32 GB of disk per MicroVM," and that's what it means.
The rest of the boundary conditions:
- ARM64 only. No x86.
- 5 regions — Northern Virginia, Ohio, Oregon, Ireland, Tokyo.
- Up to 8 hours (28,800 seconds). That's both the session lifetime and the idle-suspend retention limit.
- Each MicroVM gets a dedicated HTTPS endpoint, supporting HTTP/1.1, HTTP/2, WebSocket, gRPC, and SSE. Auth uses a JWE token issued via
create-microvm-auth-token, carried in theX-aws-proxy-authheader. The token embeds allowed ports and an expiration.
There's one thing the VM boundary makes possible that's a genuine advantage. Set additionalOsCapabilities to ["ALL"] and things like filesystem mounts, network namespace creation, and running eBPF open up. The documentation's own words are precise here — "Capabilities are applied within the VM isolation boundary and do not affect the host or other MicroVMs." You can hand out something close to root inside the sandbox and still keep the host safe, because there's a hypervisor underneath. Containers can't make this trade.
The Truth Behind the Fast Start — Resuming from a Snapshot Instead of Booting
The substance of "near-instant startup" is: it doesn't boot. It's the same technique Lambda SnapStart used — resuming from a Firecracker snapshot.
At image-build time, here's what Lambda does, in order: it launches a new MicroVM from the base image, runs the Dockerfile, starts the app via ENTRYPOINT/CMD, confirms initialization is complete through lifecycle hooks, and then takes a snapshot of the disk and memory state. There are two hooks.
/ready → /aws/lambda-microvms/runtime/v1/ready
Whether the app is in a state safe to snapshot. 503 = retry, 200 = snapshot.
/validate → /aws/lambda-microvms/runtime/v1/validate
After the build, confirms a new MicroVM launched from that image resumes correctly.
The /validate hook has a hidden use documented by AWS — run a mock payload through it here, and Lambda traces which regions of the snapshot are actually touched, then optimizes fetching those regions at startup. Snapshot restore ultimately comes down to lazily pulling in memory pages, and knowing ahead of time which pages are hot speeds that up.
The documentation spells out what the snapshot contains — the memory state of every running process (including background daemons, cron jobs, and child processes), the disk state, and initialized network connections and file descriptors.
Read that last item again. This is where the real argument of this post begins.
The Price of Snapshots — When the Thing That Should Be Unique Isn't
The Lambda MicroVMs model is "one image → N MicroVMs." That means hundreds of VMs repeatedly resume from a single snapshot. That's the reason it's fast, and the reason it's a problem.
Here's what Firecracker's own documentation calls this pattern, verbatim.
When snapshots are used in a such a manner that a given guest's state is resumed from more than once, guest information assumed to be unique may in fact not be; this information can include identifiers, random numbers and random number seeds, the guest OS entropy pool, as well as cryptographic tokens. Without a strong mechanism that enables users to guarantee that unique things stay unique across snapshot restores, we consider resuming execution from the same state more than once insecure.
It states flatly that resuming from the same state more than once is "insecure." And the exact shape of "potentially insecure use" the Firecracker docs give as an example — resuming microVMs B and C separately from a single snapshot S — is the normal operating behavior of Lambda MicroVMs itself.
AWS doesn't hide this either. From the snapshot documentation:
If your code generates unique content during image version build phase (unique IDs, secrets, or entropy for pseudorandomness), that content is shared across all MicroVMs run from the same image version.
Let's look at exactly where this bites.
Environment variables. Per the documentation, environment variables are set at image-build time (up to 50) and get injected into the container during snapshot construction. That means any secret you put in an environment variable is shared by every tenant's MicroVM booted from that image. Plug an API key into env the way you would in a container, and the entire multi-tenant sandbox sees the same key. To inject at runtime, you have to use the dynamic payload of run-microvm.
Random numbers and cryptographic tokens. Session IDs, seeds, and tokens created at build time get cloned across the board. AWS's prescription is "generate after the MicroVM starts, not during the build," and it provides a /run lifecycle hook for resetting these.
OpenSSL. This is the most concrete trap. The documentation says to use AWS's provided base container image, public.ecr.aws/lambda/microvms:al2023-minimal. The reason: it contains an "AWS-patched version of OpenSSL that is compatible with snapshotting." If you use your own base image, you have to add the openssl-snapsafe-libs package from Amazon Linux 2023 yourself.
Why does OpenSSL get singled out? The next section answers that.
What VMGenID Fixes, and What It Doesn't
There's a kernel-side fix. VMGenID is a virtual device that lets a guest detect "I was just resumed from a snapshot." It exposes a 16-byte random identifier to the guest, and the hypervisor changes that value on every snapshot resume. Firecracker always enables this device, and on resume it writes a new 16-byte value and injects an interrupt into the guest before resuming its vCPU. Linux, starting at 5.18 (via ACPI; 6.10 for DeviceTree), detects the change in this value and reseeds its internal kernel CSPRNG.
That's why the per-language CSPRNGs AWS points you to — Java 11+'s SecureRandom, Node.js's crypto.randomBytes, Python 3.12+'s Secrets.SystemRandom, .NET 8+'s Cryptography.RandomNumberGenerator — are safe. What they have in common is that all of them draw entropy from the kernel through /dev/random or /dev/urandom. Since the kernel gets reseeded, so do they.
The problem is anything that bypasses the kernel. Here's Firecracker's documentation, verbatim:
State other than the guest kernel entropy pool, such as unique identifiers, cached random numbers, cryptographic tokens, etc will still be replicated across multiple microVMs resumed from the same snapshot. Users need to implement mechanisms for ensuring de-duplication of such state, where needed.
The emphasis on will is in the original. VMGenID fixes only the kernel entropy pool. If userspace keeps its own separate entropy pool — which is exactly what OpenSSL does — that stays cloned. That's why the separate openssl-snapsafe-libs package exists, and why AWS recommends using its base image.
Firecracker's entropy documentation is more candid about this limit — on the problem of userspace libraries each keeping their own entropy pool, it states there is "no generic solution in the current programming model, and all we can do is recommend against using them in logic that precedes a snapshot."
There's ongoing standardization work to notify userspace too. Userspace can watch the vm_generation_counter of the VMClock device via mmap() or get notified via poll(), and this support merged into Linux kernel v7.0 via a patch an Amazon engineer (itazur@amazon.com) sent on January 30, 2026. It's backported into Amazon Linux's microvm kernel 5.10 and 6.1 series. But this only pays off if "the library has been modified to watch this device" — and right now, the odds that whatever library you're using has been modified that way are low.
To summarize, here's how the responsibility for uniqueness on snapshot resume breaks down.
Kernel entropy pool → auto-reseeded by VMGenID (Linux 5.18+) [solved]
CSPRNGs using /dev/urandom → go through the kernel, so safe automatically [solved]
Self-entropy pools (e.g. OpenSSL) → need a patched build (openssl-snapsafe-libs) [partially solved]
App-generated IDs, tokens, seeds → nobody fixes this for you. Regenerate in the /run hook [your responsibility]
Build-time environment variables → baked into the snapshot as-is. Avoid via runtime injection [your responsibility]
The last two lines are the most important part of this post. The VM isolation boundary does nothing for this problem. Blocking a kernel escape between tenants and tenants seeing the same seed are entirely different layers of the problem.
What the VM Boundary Doesn't Block
Say you've solved the snapshot problem entirely. There's still what the VM boundary doesn't block, and in practice this is where the more frequent incidents happen.
The default is open internet. Straight from the networking documentation — "By default, Lambda MicroVMs have public internet access on the egress path." Picture an agent that's been prompt-injected reading credentials or user data inside the sandbox and shipping them out with curl. The VM boundary blocks none of that. From the hypervisor's point of view, that's just the guest doing normal network I/O. To control egress, you have to route traffic through your own VPC with a Lambda Network Connector and put it through security groups and NACLs. The real line of defense isn't the hypervisor — it's the network policy you write.
This isn't unique to AWS. Anthropic's self-hosted sandbox security documentation states the same boundary more bluntly — "Without egress restrictions, a compromised tool execution can reach arbitrary external hosts." And on the list of "what Anthropic can't do for you," there's this: "Isolate tools inside your sandbox. Anthropic's security boundary stops at the sandbox." For what it's worth, the AWS Compute Blog explicitly describes the pattern of using Lambda MicroVMs as a self-hosted sandbox provider for Claude Managed Agents — the agent loop lives on Anthropic's side, tool execution in your MicroVM.
IAM is still on you. One good detail the Compute Blog points out: you can separate the build-time IAM role from the runtime IAM role. You need this if you want fine-grained per-tenant permissions. VM isolation is worthless if the execution role is over-privileged.
Prompt injection isn't an isolation problem. There's no way for the hypervisor to notice that the model was tricked into doing something "permitted." The VM boundary is a tool for shrinking blast radius, not a tool for stopping an agent from making a bad call.
An Honest Look at the Numbers
AWS does not give a startup-latency number. Go through the Compute Blog, the news blog, and the developer guide, and all you get is phrasing like "near-instant startup," "resume within seconds," "starts within seconds." No millisecond figure appears anywhere. So I won't invent one here — it's a number you have to measure yourself, against your own image size and working set. Given that snapshot restore scales with page fetches, there's no reason a multi-gigabyte working set and a 200MB image would resume in the same time.
Firecracker's scale numbers are vendor claims. "15 trillion+ monthly invocations" (developer guide), "tens of trillions of requests each month for over 1.5 million customers" (Compute Blog) — both are figures AWS states about its own service, and the measurement conditions aren't published. They're sufficient as qualitative evidence that Firecracker has been proven at scale, but not more than that.
Cost you can actually compute. The published us-east-1 ARM rates from the Lambda pricing page are:
vCPU $0.0000276944 / vCPU-second
Memory $0.0000036667 / GB-second
Snapshot write $0.0038 / GB (suspend)
Snapshot read $0.00155 / GB (start / resume)
Snapshot storage $0.08 / GB-month
Keep the default baseline (2GB / 1vCPU) running continuously and that's $0.0000350278 a second. Roughly $0.126 an hour, about $3.03 a day, about $91 over 30 days. That's just the baseline floor — usage above baseline and snapshot/data-transfer costs are separate. For what it's worth, the practitioner estimate cited in InfoQ's coverage also comes out to $3.03 a day — the same number independently derived from the public rates, so this figure holds up. The same article also cites the observation that this is more than 9x Fargate Spot.
That has a design implication. Under this pricing model, leaving an idle MicroVM running is just money. That's why suspend isn't optional — it's mandatory — and why idle-policy is a first-class citizen of the API. Suspend it and the compute charge stops, leaving only the storage rate. On the flip side, for a workload that runs a large volume of short-lived VMs — like an RL environment — you need to factor in that every start incurs a snapshot-read charge.
Operational overhead comes with numbers attached too. Base images have a deprecation cycle — DEPRECATED (60 days) → EXPIRING (30 days, can no longer create new images) → EXPIRED (can neither build nor run). Make an image and forget about it, and eventually it stops launching. Rebuilding is a recurring chore.
The Alternative — How the gVisor Side Handles This
It's only fair to look at whoever's solving the same problem with a different boundary. Google shipped GKE Agent Sandbox on May 21, 2026. Instead of hardware virtualization, it uses gVisor — a kernel that intercepts system calls in userspace — paired with default-deny Kubernetes network policies. There's an interface for plugging in other sandboxes like Kata Containers too, and it's an open-source project under Kubernetes SIG.
The numbers Google claims are "300 sandbox allocations per second per cluster, sub-second latency, 90% of allocations completing within 200 milliseconds." That's a vendor-measured figure, and conditions like cluster configuration aren't specified in the blog post. "Up to 30% better price-performance than other hyperscalers on Axion" is likewise Google's own comparison.
The difference in the nature of the boundaries is worth stating clearly. gVisor reimplements system calls in userspace to shrink the surface touching the host kernel — thin and fast, but since it's ultimately software impersonating a kernel interface, that software itself becomes the attack surface. Firecracker is a real VM on top of KVM, so the guest gets its own kernel — heavier for it, and it brings along the snapshot problem that's taken up half of this post. Neither side gets to claim "more secure" without conditions attached. The one certain thing is that default-deny egress is something both camps have to handle separately.
When Not to Use It
Don't use it if:
- The code you're running is your own code. With no trust boundary, there's no reason to pay per-tenant VM prices. A
$3-a-day floor and an 8-hour cap aren't justified. - The workload is stateless and short-lived. Snapshot lifecycle, uniqueness handling, and suspend policy are all complexity that exists to preserve state — if you're not going to use that, a plain Lambda function is the right call.
- You need x86. It's ARM64 only.
- You need somewhere outside the 5 regions.
- Sessions need to run longer than 8 hours. That's a hard cap with no workaround.
- You can't lock down egress. Running untrusted code on top of an open-internet default means you bought VM isolation and left the door that actually matters open. This isn't so much "just don't use it" as "if you're not going to do this, there's no reason to pay for VM isolation at all."
When it earns its cost is, by contrast, clear — you need to run user- or agent-generated code isolated per tenant, sessions are long, stateful, and have idle periods, you need to grant high OS privileges inside the sandbox (like a scanner would), and you don't want to operate Firecracker infrastructure yourself. That combination is exactly the spot AWS is aiming at, and it fits that spot well.
Closing
Lambda MicroVMs is a good product. Just don't confuse what's being sold with what you're buying. What's sold is outsourcing hypervisor operations — using Firecracker's isolation and snapshotting through an API instead of running it yourself. What you're buying is a strong inter-tenant kernel boundary, and that boundary is real, and containers can't sell it to you.
What you're not buying is just as clear. Making sure VMs resumed from a snapshot don't see the same secrets and the same seeds is still on you. VMGenID only fixes the kernel entropy pool, and Firecracker's own documentation states plainly that everything above that layer "gets replicated." Egress is on you too — the default is open internet. So is IAM. So is prompt injection.
So the real lesson of this product sits below the isolation technology itself. An implementation choice made for speed creates a new trust assumption. The moment you use a snapshot to skip booting, the 40-year-old assumption that "every process starts in a unique state" quietly breaks. The hypervisor doesn't know that. The only one who does is you, and only if you read the documentation to the end.
References
- AWS Lambda MicroVMs launch announcement (2026-06-22)
- Run isolated sandboxes with full lifecycle control: AWS Lambda introduces MicroVMs — AWS News Blog
- Announcing Lambda MicroVMs — AWS Compute Blog (2026-07-10)
- Lambda MicroVMs Developer Guide — Overview
- MicroVM images — sizing table, build hooks, base image lifecycle
- Working with snapshots — uniqueness, CSPRNG, and OpenSSL caveats
- Networking — default egress and JWE auth
- AWS Lambda Pricing
- Firecracker — Snapshot support (snapshot security and uniqueness, VMGenID, VMClock)
- Firecracker — Entropy for Clones
- AWS Launches Lambda MicroVMs for Isolated Agent and User Code Execution — InfoQ
- Bringing you Agent Sandbox on GKE and Agent Substrate — Google Cloud Blog (2026-05-21)
- Claude Managed Agents — Self-hosted sandbox security model