Skip to content

About

AWS Lambda MicroVM lab for securely running isolated Claude Managed Agent workloads with Terraform, API Gateway, IAM, Secrets Manager, CloudWatch, and CloudTrail.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Lambda MicroVM + Claude Managed Agents Lab

Terraform AWS Python JavaScript API Gateway CloudWatch CloudTrail Security Project


πŸ“Œ Current Lab Status

This repository is a student lab / proof-of-concept that demonstrates a secure AWS pattern for launching Claude Managed Agent work inside isolated Lambda MicroVM sessions. It is not claiming to be a fully production-ready enterprise platform.

Current verified deployment values:

Item Current value
AWS Region us-east-1
AWS Account <ACCOUNT_ID>
Terraform backend bucket class-7-state-files
Terraform backend key lambda-labs/microvm.tfstate
API Gateway webhook URL https://fkj0engflg.execute-api.us-east-1.amazonaws.com/prod/claude/webhook
Artifact bucket microvm-artifacts-bucket
Artifact S3 URI s3://microvm-artifacts-bucket/microvm-artifacts/app.zip
Claude environment key secret ARN arn:aws:secretsmanager:us-east-1:<ACCOUNT_ID>:secret:lambda-microvm-lab-dev/claude/environment-key-HbbDkY
Claude webhook signing secret ARN arn:aws:secretsmanager:us-east-1:<ACCOUNT_ID>:secret:lambda-microvm-lab-dev/claude/webhook-signing-secret-r9XywX
MicroVM image name class7-microvm-image
MicroVM image ARN arn:aws:lambda:us-east-1:<ACCOUNT_ID>:microvm-image:class7-microvm-image
MicroVM image state CREATED
Latest active image version 1.0
Launcher Lambda log group /aws/lambda/lambda-microvm-lab-dev-microvm-launcher
API Gateway log group /aws/apigateway/lambda-microvm-lab-dev-claude-webhook
MicroVM log group /aws/lambda/microvms/class7-microvm-image
CloudTrail bucket lambda-microvm-lab-dev-cloudtrail-d06df742
CloudTrail trail ARN arn:aws:cloudtrail:us-east-1:<ACCOUNT_ID>:trail/lambda-microvm-lab-dev-microvm-trail

Latest validation evidence:

  • Terraform initialized and validated successfully.
  • Terraform apply completed with 46 added, 0 changed, 0 destroyed.
  • Lambda MicroVM image state is CREATED.
  • Latest active MicroVM image version is 1.0.
  • Manual unsigned webhook test returned 401 Invalid webhook signature.
  • Manual MicroVM runtime smoke test reached RUNNING.
  • Direct MicroVM /health endpoint returned HTTP/1.1 200 OK.

🎯 What Is This Project?

This project builds a Terraform-managed AWS lab environment that connects Claude Managed Agents to isolated AWS Lambda MicroVM runtime sessions.

In everyday terms, this project creates a secure β€œAI workroom” in AWS. When Claude needs to run a task, a webhook request goes to API Gateway, a Python Lambda launcher verifies the request, and the workload runs inside a short-lived Lambda MicroVM instead of a shared server.

This helps answer a real-world security question

How can a company let AI agents safely perform useful technical work without giving them uncontrolled access to internal systems?


🧠 Recruiter-Friendly Summary

Built a Terraform-managed AWS student lab that securely connects Claude Managed Agents to isolated Lambda MicroVM runtime environments. The project uses API Gateway, Lambda, IAM, Secrets Manager, S3, CloudWatch, and CloudTrail to package, launch, monitor, and audit AI workload sessions in AWS.

Real-world example

A company may want an AI assistant to review support tickets, inspect logs, or troubleshoot cloud alerts. Instead of allowing the AI to run directly on a long-lived shared server, this project launches a temporary isolated MicroVM session with controlled IAM permissions, secrets access, logging, and audit trails.


πŸ—οΈ Architecture Stages

1️⃣ Build Pipeline

Terraform apply
β†’ Package app/Dockerfile + app/app.js
β†’ Create app.zip
β†’ Upload app.zip to S3
β†’ CloudFormation creates AWS::Lambda::MicrovmImage
β†’ Lambda MicroVM image becomes versioned and launchable

2️⃣ Runtime Request Flow

Claude Managed Agent
β†’ Sends session.status_run_started webhook
β†’ API Gateway REST API receives POST /claude/webhook
β†’ Python launcher Lambda verifies webhook signature
β†’ Launcher Lambda calls RunMicroVM
β†’ Lambda MicroVM starts one isolated session
β†’ MicroVM worker runs the student lab Node.js service
β†’ Results/status flow back over HTTPS

3️⃣ Supporting AWS Services

S3              Stores the packaged MicroVM app artifact.
Secrets Manager Stores Claude environment key and webhook signing secret.
IAM             Provides least-privilege roles and policies.
CloudWatch      Stores logs, metrics, and alarms.
CloudTrail      Audits management events and Lambda MicroVM data events.
API Gateway     Exposes the Claude webhook route.
Lambda          Runs the Python launcher.

πŸ–ΌοΈ Network Architecture Diagram

Lambda MicroVM Architecture Infographic

Alternate infographic version:

Lambda MicroVM Lab Architecture

The diagrams show the lab in three stages:

  1. Build Pipeline β€” Terraform packages the app (app.zip) to the S3 artifact bucket, then CloudFormation (AWS::Lambda::MicrovmImage) produces the Lambda MicroVM image.
  2. Runtime Request Flow β€” Claude webhook traffic enters through API Gateway to the Python launcher Lambda, which verifies the signature and calls RunMicroVM to start the isolated MicroVM worker on port 8080 (ALL_INGRESS / INTERNET_EGRESS network connectors). Results return to Claude over HTTPS.
  3. Supporting AWS Services β€” IAM, Secrets Manager, CloudWatch, and CloudTrail provide security, logging, and audit.

βœ… What This Lab Builds

  • S3 artifact bucket for the MicroVM application package.
  • S3 object for microvm-artifacts/app.zip.
  • Lambda MicroVM image using CloudFormation AWS::Lambda::MicrovmImage.
  • Python launcher Lambda for Claude webhook events.
  • API Gateway REST API endpoint at /prod/claude/webhook.
  • Secrets Manager secret containers for the Claude environment key and webhook signing secret.
  • Least-privilege IAM roles for MicroVM build, MicroVM runtime, launcher Lambda, and API Gateway CloudWatch logging.
  • CloudWatch log groups, metric filters, and alarms.
  • CloudTrail trail with management events and Lambda MicroVM data events.
  • JavaScript MicroVM worker stub for student-lab validation.

🧰 Required Tools

Tool Requirement Purpose
Terraform 1.14+ Required Deploy AWS infrastructure.
AWS CLI v2 Required Run validation, logs, MicroVM commands, and secrets updates.
Python 3.14 Required for this lab Package the launcher Lambda dependencies.
Git Bash Recommended on Windows Run the lab commands consistently.
jq Recommended Parse JSON outputs from AWS CLI.
Claude Console Required for full Claude integration Create Managed Agent, self-hosted environment, and webhook.
AWS Console Optional Capture screenshots and visually inspect resources.
VS Code Required Edit Terraform, Python, JavaScript, and Markdown files.
.venv-lambda-build Recommended Python virtual environment for packaging the launcher Lambda.

πŸ“ Project Structure

microvm/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ app.js
β”‚   └── Dockerfile
β”œβ”€β”€ deliverables/
β”‚   β”œβ”€β”€ microvm-run.json
β”‚   └── microvm-token.json
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ architecture/
β”‚   β”‚   β”œβ”€β”€ lambda_microvm_architecture_infographic.png
β”‚   β”‚   └── microvm-lab-flowchart.svg
β”‚   └── runbooks/
β”‚       └── CLI_COMMANDS.md
β”œβ”€β”€ images/
β”‚   β”œβ”€β”€ aws-verifications.jpg
β”‚   β”œβ”€β”€ base-image-versions.jpg
β”‚   β”œβ”€β”€ claude-console-agent-environment.jpg
β”‚   β”œβ”€β”€ claude-console-environment.jpg
β”‚   β”œβ”€β”€ claude-console-webhook-subscribe.jpg
β”‚   β”œβ”€β”€ claude-console-webhook.jpg
β”‚   β”œβ”€β”€ claude-secrets-describe-pt1.jpg
β”‚   β”œβ”€β”€ claude-secrets-describe-pt2.jpg
β”‚   β”œβ”€β”€ claude-secrets.jpg
β”‚   β”œβ”€β”€ cloudtrail-selectors.jpg
β”‚   β”œβ”€β”€ cloudwatch-alarms-pt1.jpg
β”‚   β”œβ”€β”€ cloudwatch-alarms-pt2.jpg
β”‚   β”œβ”€β”€ launcher-lambda-logs.jpg
β”‚   β”œβ”€β”€ manual-microvm-health.jpg
β”‚   β”œβ”€β”€ manual-microvm-id.jpg
β”‚   β”œβ”€β”€ manual-microvm-launch.jpg
β”‚   β”œβ”€β”€ manual-microvm-outputs.jpg
β”‚   β”œβ”€β”€ manual-microvm-running.jpg
β”‚   β”œβ”€β”€ s3-bucket-verification.jpg
β”‚   β”œβ”€β”€ terraform-apply.jpg
β”‚   β”œβ”€β”€ terraform-destroy.jpg
β”‚   β”œβ”€β”€ terraform-init-fmt-validate.jpg
β”‚   β”œβ”€β”€ terraform-outputs.jpg
β”‚   β”œβ”€β”€ terraform-plan.jpg
β”‚   └── webhook-smoke-test.jpg
β”œβ”€β”€ launcher/
β”‚   β”œβ”€β”€ lambda_function.py
β”‚   └── requirements.txt
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ build_launcher_package.py
β”‚   └── prepare_build_dirs.py
β”œβ”€β”€ terraform/
β”‚   β”œβ”€β”€ 1-authentication.tf
β”‚   β”œβ”€β”€ 2-provider.tf
β”‚   β”œβ”€β”€ 3-variables.tf
β”‚   β”œβ”€β”€ 4-locals.tf
β”‚   β”œβ”€β”€ 5-random.tf
β”‚   β”œβ”€β”€ 6-s3.tf
β”‚   β”œβ”€β”€ 7-cloudwatch.tf
β”‚   β”œβ”€β”€ 8-iam.tf
β”‚   β”œβ”€β”€ 9-microvm-image.tf
β”‚   β”œβ”€β”€ 10-secrets.tf
β”‚   β”œβ”€β”€ 11-api-gateway.tf
β”‚   β”œβ”€β”€ 12-lambda.tf
β”‚   β”œβ”€β”€ 13-cloudtrail.tf
β”‚   β”œβ”€β”€ 14-outputs.tf
β”‚   β”œβ”€β”€ terraform.tfvars
β”‚   └── terraform.tfvars.example
β”œβ”€β”€ .gitignore
β”œβ”€β”€ README.md
└── RUNBOOK.md

⚠️ Git Hygiene

Do not commit generated or local-only files:

build/
terraform/.terraform/
*.tfstate
*.tfstate.*
*.tfplan
terraform.tfvars
lambda-response.json
microvm-run.json
microvm-token.json
*.zip

Commit terraform/terraform.tfvars.example, but do not commit real Claude secrets.


πŸš€ Deployment Steps

For more detailed instructions, see RUNBOOK.

1️⃣ Set shell environment

export AWS_REGION="us-east-1"
export AWS_PROFILE="default"

2️⃣ Validate AWS identity

aws sts get-caller-identity --region "$AWS_REGION"

3️⃣ Confirm backend bucket

aws s3api head-bucket \
  --bucket class-7-state-files \
  --region "$AWS_REGION"

4️⃣ Check MicroVM base image versions

aws lambda-microvms list-managed-microvm-image-versions \
  --image-identifier arn:aws:lambda:us-east-1:aws:microvm-image:al2023-1 \
  --region "$AWS_REGION" \
  --output table

This lab currently uses:

microvm_base_image_version = "1"

5️⃣ Initialize, format, validate, plan and deploy

cd terraform
terraform init -upgrade
terraform fmt -recursive
terraform validate
terraform plan
terraform apply

Expected latest successful result:

Apply complete! Resources: 46 added, 0 changed, 0 destroyed.

πŸ”‘ Configure Claude Secrets

Do not place real Claude secret values directly inside terraform.tfvars.

Current secret containers:

Claude environment key secret:
arn:aws:secretsmanager:us-east-1:<ACCOUNT_ID>:secret:lambda-microvm-lab-dev/claude/environment-key-HbbDkY

Claude webhook signing secret:
arn:aws:secretsmanager:us-east-1:<ACCOUNT_ID>:secret:lambda-microvm-lab-dev/claude/webhook-signing-secret-r9XywX

Store the Claude environment key:

aws secretsmanager put-secret-value \
  --secret-id "$CLAUDE_ENVIRONMENT_SECRET_ARN" \
  --secret-string "REPLACE_WITH_CLAUDE_ENVIRONMENT_KEY" \
  --region "$AWS_REGION"

Store the Claude webhook signing secret:

aws secretsmanager put-secret-value \
  --secret-id "$CLAUDE_WEBHOOK_SIGNING_SECRET_ARN" \
  --secret-string "REPLACE_WITH_CLAUDE_WEBHOOK_SIGNING_SECRET" \
  --region "$AWS_REGION"

πŸ€– Configure Claude Console

  1. Open Claude Console.

  2. Open the Claude Managed Agent.

  3. Open or create the self-hosted environment.

  4. Copy the environment ID and set anthropic_environment_id in terraform.tfvars.

  5. Register the current Terraform output webhook URL:

    https://fkj0engflg.execute-api.us-east-1.amazonaws.com/prod/claude/webhook
    
  6. Subscribe the webhook to:

    session.status_run_started
    
  7. Copy the webhook signing secret from Claude Console and store it in AWS Secrets Manager.


βœ… Validation Path 1: Webhook Security Smoke Test

WEBHOOK_URL="$(terraform output -raw claude_webhook_url | tr -d '\r')"

curl --ssl-no-revoke -i -X POST "$WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  --data-raw '{"type":"session.status_run_started","session_id":"manual-test"}'

Expected result:

HTTP/1.1 401 Unauthorized

Expected body:

{"error": "Invalid webhook signature"}

This is a passing result because manual curl requests are not signed by Claude.


βœ… Validation Path 2: Manual MicroVM Runtime Smoke Test

MICROVM_IMAGE_ARN="$(terraform output -raw microvm_image_arn | tr -d '\r')"
MICROVM_RUNTIME_ROLE_ARN="$(terraform output -raw microvm_runtime_role_arn | tr -d '\r')"

aws lambda-microvms run-microvm \
  --image-identifier "$MICROVM_IMAGE_ARN" \
  --image-version "1.0" \
  --execution-role-arn "$MICROVM_RUNTIME_ROLE_ARN" \
  --ingress-network-connectors "arn:aws:lambda:${AWS_REGION}:aws:network-connector:aws-network-connector:ALL_INGRESS" \
  --egress-network-connectors "arn:aws:lambda:${AWS_REGION}:aws:network-connector:aws-network-connector:INTERNET_EGRESS" \
  --idle-policy '{"maxIdleDurationSeconds":900,"suspendedDurationSeconds":0,"autoResumeEnabled":false}' \
  --maximum-duration-in-seconds 28800 \
  --run-hook-payload '{"source":"manual-lab-test","session_id":"manual-test"}' \
  --region "$AWS_REGION" \
  > microvm-run.json

MICROVM_ID="$(cat microvm-run.json | jq -r '.microvmId')"
MICROVM_ENDPOINT="$(cat microvm-run.json | jq -r '.endpoint')"

Wait for RUNNING:

while true; do
  STATE="$(aws lambda-microvms get-microvm \
    --microvm-identifier "$MICROVM_ID" \
    --region "$AWS_REGION" \
    --query 'state' \
    --output text)"

  echo "MicroVM state: $STATE"

  if [ "$STATE" = "RUNNING" ]; then
    break
  fi

  if [ "$STATE" = "TERMINATED" ]; then
    echo "MicroVM terminated before becoming reachable. Check MicroVM logs."
    break
  fi

  sleep 5
done

Create a token and test /health:

aws lambda-microvms create-microvm-auth-token \
  --microvm-identifier "$MICROVM_ID" \
  --expiration-in-minutes 30 \
  --allowed-ports '[{"port":8080}]' \
  --region "$AWS_REGION" \
  > microvm-token.json

$ TOKEN="$(cat microvm-token.json | jq -r '.authToken."X-aws-proxy-auth"')"

curl -i --ssl-no-revoke "https://${MICROVM_ENDPOINT}/health" \
  -H "X-aws-proxy-auth: $TOKEN" \
  -H "X-aws-proxy-port: 8080"

Expected response:

HTTP/1.1 200 OK
Content-Type: application/json
{"ok":true,"service":"lambda-microvm-claude-agent-lab","lab_mode":true,"message":"Student lab MicroVM worker is running."}

βœ… Validation Path 3: Observability and Audit Checks

Launcher logs:

LAUNCHER_LOG_GROUP="$(terraform output -raw launcher_lambda_log_group_name | tr -d '\r')"

MSYS_NO_PATHCONV=1 aws logs tail "$LAUNCHER_LOG_GROUP" \
  --follow \
  --region "$AWS_REGION" \
  --format short

CloudTrail selectors:

aws cloudtrail get-event-selectors \
  --trail-name "lambda-microvm-lab-dev-microvm-trail" \
  --region "$AWS_REGION" \
  --output json

Expected selectors:

Log management events
Log Lambda MicroVM data events
AWS::Lambda::MicrovmImage

πŸ“Έ Screenshot Checklist

Screenshot What it proves Links for Screenshots
aws sts get-caller-identity Correct AWS account is active. AWS Verifications
aws s3api head-bucket Terraform backend bucket exists. S3 Bucket Verification
terraform init -upgrade Backend and providers initialized. Terraform Init
terraform plan Terraform syntax is valid. Terraform Plan
terraform apply complete Infrastructure was deployed. Terraform Apply
terraform output Current ARNs, URLs, and log groups. Terraform Outputs
API Gateway 401 curl Webhook security check works. Webhook Smoke Test
Manual MicroVM launch Runtime and handler are correct. Manual MicroVM Launch
MicroVM state RUNNING Runtime launch succeeded. MicroVM State Running
MicroVM /health 200 Worker is reachable. MicroVM Health
Launcher Lambda logs Observability is working. Launcher Lambda Logs
CloudWatch Alarms (Part I) Monitoring exists. CloudWatch Alarms (Part I)
CloudWatch Alarms (Part II) Monitoring exists. CloudWatch Alarms (Part II)
CloudTrail selectors Audit logging is configured. CloudTrail Selectors

🧹 Teardown

Terminate active MicroVMs:

aws lambda-microvms list-microvms \
  --image-identifier "$MICROVM_IMAGE_ARN" \
  --region "$AWS_REGION" \
  --output table
aws lambda-microvms terminate-microvm \
  --microvm-identifier REPLACE_WITH_MICROVM_ID \
  --region "$AWS_REGION"

Destroy Terraform resources:

terraform destroy

🧰 Troubleshooting

Invalid endpoint: https://lambda..amazonaws.com or https://logs..amazonaws.com

Cause: AWS_REGION is empty.

Fix:

export AWS_REGION="us-east-1"

Git Bash path conversion breaks /aws/lambda/... log group names

Use:

MSYS_NO_PATHCONV=1 aws logs tail "/aws/lambda/lambda-microvm-lab-dev-microvm-launcher" \
  --since 30m \
  --region "$AWS_REGION" \
  --format short

Python error: No module named 'pydantic_core._pydantic_core'

Cause: Python dependencies were built for Windows instead of Lambda Linux.

Fix:

rm -rf ../build

terraform apply \
  -replace=terraform_data.launcher_package

Manual webhook test returns 401 Invalid webhook signature

This is expected for unsigned curl tests and means the route is secure.

MICROVM_ID is empty

Fix:

cat microvm-run.json
MICROVM_ID="$(cat microvm-run.json | jq -r '.microvmId')"
MICROVM_ENDPOINT="$(cat microvm-run.json | jq -r '.endpoint')"

MicroVM endpoint returns 502

Check state:

aws lambda-microvms get-microvm \
  --microvm-identifier "$MICROVM_ID" \
  --region "$AWS_REGION" \
  --output table

If state is TERMINATED, launch a fresh MicroVM and generate a fresh token. If state is RUNNING, check the MicroVM logs.

Curl Schannel revocation error on Windows

Fix:

curl --ssl-no-revoke ...

πŸ“š References


πŸ‘₯ Author

Role Name / Group
Project Author T.I.Q.S.
Project Team The Brotherhood of jerMutants β€” Wolfpack
Team Lead John Sweeney
Course Instructor Theo WAF
Project Version v2.1
Completion Date July 2026
Project Type Student lab / proof-of-concept

About

AWS Lambda MicroVM lab for securely running isolated Claude Managed Agent workloads with Terraform, API Gateway, IAM, Secrets Manager, CloudWatch, and CloudTrail.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages