From 6a3e1f3a340808a99ddef6659636f9bc4b5ae3ad Mon Sep 17 00:00:00 2001 From: Fabio Balancin Date: Fri, 10 Jul 2026 04:08:41 -0300 Subject: [PATCH 1/3] Add egress-controlled code execution sample A multi-container security sample under 03-advanced: a trusted supervisor container (started by AgentCore Runtime) launches a broker and an untrusted agent container inside the same microVM via containerd. All agent egress is mediated by the broker, which enforces a runtime-configurable allowlist. The Phase 1 operation is ping_domain, exercising the full supervisor -> agent -> broker -> egress path. The allow-vs-deny contrast (amazon.com permitted, aws.amazon.com denied) demonstrates the security boundary end to end. Includes deploy.py / invoke.py / cleanup.py (matching the folder convention), three arm64 Dockerfiles, unit tests for the IPC framing and broker allowlist, and an architecture diagram. Also adds the row to the 03-advanced index. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../12-egress-coding-execution/.gitignore | 16 + .../12-egress-coding-execution/README.md | 294 ++++++++++++++++++ .../agent/src/__init__.py | 0 .../agent/src/agent_main.py | 106 +++++++ .../agent/src/ipc_client.py | 58 ++++ .../broker/src/__init__.py | 0 .../broker/src/config.py | 44 +++ .../broker/src/handlers/__init__.py | 0 .../broker/src/handlers/http.py | 13 + .../broker/src/handlers/ping.py | 60 ++++ .../broker/src/ipc_server.py | 109 +++++++ .../broker/src/main.py | 24 ++ .../12-egress-coding-execution/cleanup.py | 98 ++++++ .../12-egress-coding-execution/deploy.py | 223 +++++++++++++ .../images/architecture.png | Bin 0 -> 161027 bytes .../12-egress-coding-execution/invoke.py | 122 ++++++++ .../requirements-dev.txt | 2 + .../requirements.txt | 1 + .../12-egress-coding-execution/shared/ipc.py | 35 +++ .../supervisor/requirements.txt | 2 + .../supervisor/src/__init__.py | 0 .../supervisor/src/containerd.py | 94 ++++++ .../supervisor/src/ecr.py | 15 + .../supervisor/src/main.py | 204 ++++++++++++ .../supervisor/src/profiles.py | 55 ++++ .../supervisor/src/task_dispatch.py | 99 ++++++ .../tests/conftest.py | 16 + .../tests/unit/test_broker_config.py | 49 +++ .../tests/unit/test_ipc.py | 55 ++++ .../01-runtime/03-advanced/README.md | 10 +- 30 files changed, 1799 insertions(+), 5 deletions(-) create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/.gitignore create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/README.md create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/__init__.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/agent_main.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/ipc_client.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/__init__.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/config.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/__init__.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/http.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/ping.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/ipc_server.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/main.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/cleanup.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/deploy.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/images/architecture.png create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/invoke.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/requirements-dev.txt create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/requirements.txt create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/shared/ipc.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/requirements.txt create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/__init__.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/containerd.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/ecr.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/main.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/profiles.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/task_dispatch.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/conftest.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/unit/test_broker_config.py create mode 100644 01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/unit/test_ipc.py diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/.gitignore b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/.gitignore new file mode 100644 index 000000000..1299eac71 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/.gitignore @@ -0,0 +1,16 @@ +# Python +__pycache__/ +*.py[cod] +.venv/ +venv/ + +# Tooling caches +.ruff_cache/ +.pytest_cache/ +.mypy_cache/ + +# Generated at runtime by deploy.py / consumed by invoke.py + cleanup.py +runtime_config.json + +# OS +.DS_Store diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/README.md b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/README.md new file mode 100644 index 000000000..ab3348b9d --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/README.md @@ -0,0 +1,294 @@ +# Egress-Controlled Code Execution + +## Overview + +This sample demonstrates how to run **untrusted code** securely inside an Amazon Bedrock +AgentCore Runtime microVM. Three independently deployable containers collaborate so that +customer code never touches the network, credentials, or the container control plane +directly: + +- **Supervisor** — trusted orchestrator. Runs as a `BedrockAgentCoreApp`, receives + customer commands via the AgentCore Runtime API, and drives containerd (via `ctr`) to + pull and manage the broker and agent containers. +- **Broker** — trusted egress proxy. All external access from the agent flows through it, + and every request is validated against a runtime-configurable allowlist. +- **Agent** — the untrusted sandbox. No network, no credentials, no containerd socket — + it can only reach the broker over a Unix-domain IPC socket. + +The working Phase 1 operation is `ping_domain`, which exercises the full +supervisor → agent → broker → egress path with policy enforcement. The allow-vs-deny +contrast (an allowed domain pings, a blocked domain is denied by the broker) is the +security boundary this sample demonstrates. + +### Use case details + +| Information | Details | +|---------------------|-------------------------------------------------------------------------| +| Use case type | Security / sandboxed execution | +| Agent type | Multi-container (supervisor / broker / agent) | +| Use case components | AgentCore Runtime, containerd (`ctr`), Unix-socket IPC, egress allowlist | +| Use case vertical | Platform / infrastructure security | +| Example complexity | Advanced | +| SDK used | Amazon Bedrock AgentCore SDK (`bedrock-agentcore`), boto3 | + +## How this sample is different + +Unlike the other runtime samples in this folder — which ship a single agent as code +(zipped to S3 via `codeConfiguration`) — this sample is **container-based**. You build and +push **three** `linux/arm64` images to ECR, and the runtime is created from the +`supervisor` image via `containerConfiguration`. There is no `entryPoint`/zip step; each +image runs its own Dockerfile `CMD`. + +It also relies on one platform assumption that the other samples do not: **the supervisor +drives `containerd` inside the AgentCore Runtime microVM**. When the supervisor receives +`start_broker` / `start_agent`, it shells out to `ctr` (against +`/run/containerd/containerd.sock`) to pull each image from ECR and launch the broker and +agent as sibling containers *inside the same microVM*. The broker is launched with +`--net-host` (it can reach the network); the agent is launched **without** it (isolated +network namespace, loopback only) — that asymmetry is the security boundary. If the +runtime environment does not expose a usable containerd socket to the supervisor, the +`start_*` commands will fail; this is expected and central to how the sample works. + +## Key features + +- **Network-isolated agent** — the untrusted container runs with its own network + namespace (loopback only); it has no route to the internet or to IMDS. +- **Broker-mediated egress** — the agent can only act on the outside world by asking the + broker, which enforces an allowlist per operation. +- **Runtime-configurable policy** — allowlists are updated live via the `configure_broker` + command, no container restart required. +- **Length-prefixed JSON IPC** — a small shared protocol (`shared/ipc.py`) over Unix + domain sockets connects the components. + +## Architecture + +![Architecture: the supervisor launches the broker and agent inside the microVM; only the broker reaches the internet, the agent is network-isolated](images/architecture.png) + +The supervisor is the only container the runtime starts; it launches the broker and agent +itself via containerd. Only the broker reaches the internet — the agent is network-isolated +and must ask the broker over `broker.sock`. The supervisor commands, IPC protocol, and full +security model are detailed in the sections below. + +## Project Structure + +``` +12-egress-coding-execution/ +├── deploy.py # Check images in ECR, create the runtime, wait until READY +├── invoke.py # Run the demo: start broker/agent, configure, ping allow + deny +├── cleanup.py # Stop containers, delete the runtime (--delete-ecr also drops repos) +├── requirements.txt # boto3 (for the deploy/invoke/cleanup scripts) +├── requirements-dev.txt # + pytest (for running the unit tests) +├── shared/ +│ └── ipc.py # Length-prefixed JSON IPC framing (send/recv), shared by all three +├── supervisor/ # TRUSTED orchestrator image (the one the runtime starts) +│ ├── Dockerfile # python:3.12-slim + containerd client (ctr) +│ ├── requirements.txt # image deps: bedrock-agentcore, boto3 +│ └── src/ +│ ├── main.py # BedrockAgentCoreApp entrypoint + command router +│ ├── containerd.py # ctr wrappers: pull / start / stop / status +│ ├── ecr.py # fetch an ECR auth token (boto3) for image pulls +│ ├── profiles.py # build the ctr run args (broker = --net-host, agent = isolated) +│ └── task_dispatch.py # supervisor→agent IPC over supervisor.sock (TaskDispatcher) +├── broker/ # TRUSTED egress proxy image +│ ├── Dockerfile # python:3.12-slim + iputils-ping (stdlib-only otherwise) +│ └── src/ +│ ├── main.py # start the asyncio Unix-socket IPC server +│ ├── ipc_server.py # accept agent connections, route methods to handlers +│ ├── config.py # BrokerConfig: mutable allowlist state + configure handler +│ └── handlers/ +│ ├── ping.py # ping proxy, enforces ALLOWED_PING_DOMAINS +│ └── http.py # HTTP proxy (Phase 2 stub → NOT_IMPLEMENTED) +├── agent/ # UNTRUSTED sandbox image (no network, no creds, non-root) +│ ├── Dockerfile # python:3.12-slim, runs as USER sandbox (UID 1000) +│ └── src/ +│ ├── agent_main.py # task loop: wait on supervisor.sock, proxy pings via broker.sock +│ └── ipc_client.py # Unix-socket client (connect / request / wait_for_message) +├── images/ # architecture diagram (architecture.png) +└── tests/ # Unit tests for the IPC framing and the broker allowlist +``` + +## Prerequisites + +| Requirement | Description | +|-------------|-------------| +| Python 3.12+ | To run the `deploy.py` / `invoke.py` / `cleanup.py` scripts | +| Docker with buildx | To build the three `linux/arm64` container images | +| AWS account + credentials | For ECR image pulls and Bedrock AgentCore Runtime invocations | +| An Amazon ECR repository | Three repos: `egress-coding-execution/{supervisor,broker,agent}` | +| An IAM execution role | `deploy.py` creates one (ECR pull + CloudWatch Logs) if you don't set `ROLE_ARN` | + +Install the script dependencies: + +```bash +cd amazon-bedrock-agentcore-samples/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution +pip install -r requirements.txt +``` + +## Building and pushing the images + +All images are built for `linux/arm64` (AgentCore Runtime is ARM64) and pushed to ECR. +Run from the sample root, and replace `` and the region with your own. On a +non-arm64 host, enable emulation first with +`docker run --privileged --rm tonistiigi/binfmt --install arm64`. + +```bash +REGION=us-east-1 +REGISTRY=.dkr.ecr.${REGION}.amazonaws.com/egress-coding-execution + +# Create the three repositories (once) +for c in supervisor broker agent; do + aws ecr create-repository --repository-name egress-coding-execution/$c --region ${REGION} +done + +# Authenticate with ECR +aws ecr get-login-password --region ${REGION} \ + | docker login --username AWS --password-stdin .dkr.ecr.${REGION}.amazonaws.com + +# Build & push each image +docker buildx build --platform linux/arm64 -f supervisor/Dockerfile -t ${REGISTRY}/supervisor:latest --push . +docker buildx build --platform linux/arm64 -f broker/Dockerfile -t ${REGISTRY}/broker:latest --push . +docker buildx build --platform linux/arm64 -f agent/Dockerfile -t ${REGISTRY}/agent:latest --push . +``` + +## Deployment + +The three scripts share a `runtime_config.json` written by `deploy.py`. Set your AWS +region and credentials in the environment first (the scripts read the default boto3 +session). Edit the parameters at the top of `deploy.py` (`ROLE_NAME`, `ECR_REPO`, +`RUNTIME_NAME`) if you used different names. + +```bash +# 1. Create the AgentCore Runtime from the supervisor image (waits until READY) +python deploy.py + +# 2. Run the end-to-end demo (start broker + agent, configure the allowlist, +# then ping an allowed domain and a blocked one) +python invoke.py + +# 3. Tear down the runtime. Add --delete-ecr to also delete the three ECR repos, +# and --delete-role to delete the IAM role (only if deploy.py created it). +python cleanup.py +``` + +`deploy.py` verifies the three images exist in ECR, creates (or reuses) the runtime, and +waits for status `READY`. `invoke.py` drives one session through the full flow: + +``` +start_broker → start_agent → configure_broker (allowlist: amazon.com) → status + → ping_domain amazon.com (ALLOW: broker permits it, ping executes) + → ping_domain aws.amazon.com (DENY: blocked — subdomain not in the allowlist) +``` + +Both domains are Amazon's. The allowlist entry `amazon.com` is an **exact match**, so the +subdomain `aws.amazon.com` is denied — demonstrating that the policy is a strict allowlist, +not a substring/suffix match (use a glob like `*.amazon.com` to allow subdomains). + +The **ALLOW** result confirms the broker let the request through and the ping executed — +we do not assert ICMP reachability, because inside the microVM the echo replies may not +complete (a non-zero exit code there is a network-path artifact, not a policy denial). The +**DENY** result is the broker rejecting the domain against its allowlist: + +```json +{"status":"ok","result":{"exit_code":-1,"stdout":"","stderr":"Domain not in ping allowlist: aws.amazon.com","domain":"aws.amazon.com","count":3,"timeout":5}} +``` + +## Running tests + +The unit tests cover the two security-critical, pure-Python pieces without any AWS calls: +the length-prefixed IPC framing (`shared/ipc.py`) and the broker's allowlist policy +(`broker/src/config.py`, including glob matching and default-deny). + +```bash +pip install -r requirements-dev.txt +pytest +``` + +## Supervisor commands + +The supervisor is a stateless command router (`BedrockAgentCoreApp` entrypoint). Every +command is a JSON payload `{"command": ..., "params": {...}}` sent via +`invoke_agent_runtime` on one session: + +| Command | Parameters | Action | +|---------|-----------|--------| +| `start_broker` | `image_uri`, `env` | Pull the broker image from ECR and start it with the trusted profile (`--net-host`). `env` is passed as container env vars. | +| `start_agent` | `image_uri` | Pull the agent image and start it with the untrusted profile (no `--net-host`). | +| `configure_broker` | `allowed_ping_domains`, `allowed_domains` | Update the broker allowlists at runtime via IPC — no restart. | +| `ping_domain` | `domain`, `count`, `timeout` | Dispatch a ping task to the agent (proxied through the broker); returns the result synchronously. | +| `status` | — | Report the state of the broker and agent containers. | +| `list_containers` | — | Return the raw containerd view (`ctr tasks ls` / `containers ls`) for debugging. | +| `stop_agent` / `stop_broker` | — | Kill and remove the container. | + +`ping_domain` exercises the full path: the supervisor dispatches the task to the agent +over `supervisor.sock`; the agent asks the broker to `ping` over `broker.sock`; the broker +validates the domain against `ALLOWED_PING_DOMAINS` (fnmatch globs like `*.amazon.com`) and +only then runs `ping`. A denied domain never reaches `ping`. + +## IPC protocol + +The three containers talk over two Unix-domain sockets on a shared bind mount +(`/run/containerd/sandbox-ipc` on the microVM → `/tmp/ipc` in each container): + +| Socket | Listener | Connector | Purpose | +|--------|----------|-----------|---------| +| `broker.sock` | Broker | Agent | Egress proxy (ping; HTTP/secrets are Phase 2) | +| `supervisor.sock` | Supervisor | Agent | Task dispatch (`ping_domain`) | + +Framing is a 4-byte big-endian length prefix followed by a UTF-8 JSON payload +(`shared/ipc.py`). Requests carry `{id, method, params}`; responses carry +`{id, status, result}` or `{id, status:"error", error:{code, message}}`. + +## Security model + +| Component | Trust | Network | Credentials | containerd socket | +|-----------|-------|---------|-------------|-------------------| +| Supervisor | Trusted | Host (`--net-host`) | Execution role (IMDS) | Yes | +| Broker | Trusted | Host (`--net-host`) | Optional, scoped | No | +| Agent | **Untrusted** | **None (loopback only)** | **None** | **No** | + +| Attack vector | Mitigation | +|---------------|------------| +| Agent reaches the network / IMDS | Isolated network namespace (no `--net-host`) → no route to `169.254.169.254` | +| Agent drives containerd | Socket is never mounted into the agent | +| Agent reads broker/supervisor state | Separate mount and PID namespaces | +| Agent escalates privileges | Non-root (UID 1000), no added capabilities | +| Agent reaches unauthorized domains | Broker validates every request against the allowlist | + +**Phase 1 hardening relies on** omitting `--net-host` for network isolation and the +Dockerfile `USER sandbox` (UID 1000) for non-root execution. Explicit namespace flags, +capability dropping, and cgroup memory/CPU limits are **deferred to Phase 2** and should be +added before any non-experimental use. + +## Roadmap + +- **Phase 1 (this sample):** supervisor/broker/agent architecture with `ping_domain` as the + working egress-controlled operation; runtime-configurable allowlist. +- **Phase 2 (deferred):** HTTP proxy + `get_secret` broker handlers (stubs exist), broker + rate/size limits, explicit namespace/capability/cgroup hardening in the `ctr` args. + +## Cost Considerations + +- **AgentCore Runtime** — billed while the runtime exists. `python cleanup.py` deletes it; + run it when you are done. +- **ECR** — storage for the three images. `python cleanup.py --delete-ecr` also deletes the + three repositories. +- **IAM role** — no cost, but `python cleanup.py --delete-role` removes it if `deploy.py` + created it (a role you supplied via `ROLE_ARN` is left untouched). + +For development and testing, tear everything down when not in use. + +## Current status + +Only **Phase 1** is implemented: the supervisor/broker/agent architecture with +`ping_domain` as the working egress-controlled operation. HTTP proxying, secret +retrieval, rate limiting, and explicit cgroup/namespace hardening are stubbed or deferred +to Phase 2 — see the [Roadmap](#roadmap) above for the full breakdown. + +## Disclaimer + +The examples provided in this repository are for **experimental and educational purposes +only**. They demonstrate concepts and techniques but are not intended for direct use in +production environments. Before adapting this pattern, complete the Phase 2 hardening +described in the [Security model](#security-model) above, and use +[Amazon Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-injection.html) +to protect against prompt injection. diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/__init__.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/agent_main.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/agent_main.py new file mode 100644 index 000000000..802eec6d6 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/agent_main.py @@ -0,0 +1,106 @@ +import logging +import os +import sys +import time + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..")) + +from .ipc_client import IPCClient + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [agent] %(levelname)s: %(message)s", +) +logger = logging.getLogger(__name__) + +SUPERVISOR_SOCKET = os.environ.get("SUPERVISOR_SOCKET_PATH", "/tmp/ipc/supervisor.sock") +BROKER_SOCKET = os.environ.get("BROKER_SOCKET_PATH", "/tmp/ipc/broker.sock") + + +def _handle_ping_domain(params: dict) -> dict: + domain = params.get("domain") + count = params.get("count", 3) + timeout = params.get("timeout", 5) + + if not domain: + return { + "exit_code": -1, + "stdout": "", + "stderr": "Missing 'domain' parameter", + "domain": "", + "count": count, + "timeout": timeout, + } + + client = IPCClient(BROKER_SOCKET) + try: + client.connect() + response = client.request("ping", {"domain": domain, "count": count, "timeout": timeout}) + finally: + client.close() + + if response and response.get("status") == "ok": + result: dict = response.get("result", {}) + return result + else: + error = response.get("error", {}) if response else {} + return { + "exit_code": -1, + "stdout": "", + "stderr": error.get("message", "Ping request failed"), + "domain": domain, + "count": count, + "timeout": timeout, + } + + +def main(): + logger.info("Agent starting, connecting to supervisor at %s", SUPERVISOR_SOCKET) + + supervisor = IPCClient(SUPERVISOR_SOCKET) + + retries = 0 + while retries < 30: + try: + supervisor.connect() + logger.info("Connected to supervisor") + break + except (ConnectionRefusedError, FileNotFoundError): + retries += 1 + time.sleep(1) + else: + logger.error("Failed to connect to supervisor after 30 retries") + sys.exit(1) + + try: + while True: + logger.info("Waiting for task...") + msg = supervisor.wait_for_message() + if msg is None: + logger.info("Supervisor disconnected, shutting down") + break + + request_id = msg.get("id", "unknown") + method = msg.get("method", "") + params = msg.get("params", {}) + + logger.info("Received task %s: method=%s", request_id, method) + + if method == "ping_domain": + result = _handle_ping_domain(params) + supervisor.send_response(request_id, "ok", result=result) + else: + supervisor.send_response( + request_id, + "error", + error={ + "code": "UNKNOWN_METHOD", + "message": f"Unknown method: {method}", + }, + ) + finally: + supervisor.close() + + +if __name__ == "__main__": + main() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/ipc_client.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/ipc_client.py new file mode 100644 index 000000000..0648eb7e4 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/agent/src/ipc_client.py @@ -0,0 +1,58 @@ +import os +import socket +import sys +import uuid +from typing import Optional + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..")) + +from shared.ipc import recv_message, send_message + + +class IPCClient: + def __init__(self, socket_path: str): + self._socket_path = socket_path + self._sock: Optional[socket.socket] = None + + def connect(self) -> None: + self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self._sock.connect(self._socket_path) + + def close(self) -> None: + if self._sock: + self._sock.close() + self._sock = None + + def _require_sock(self) -> socket.socket: + if self._sock is None: + raise RuntimeError("IPC client is not connected") + return self._sock + + def request(self, method: str, params: dict) -> Optional[dict]: + sock = self._require_sock() + msg = { + "id": str(uuid.uuid4()), + "method": method, + "params": params, + } + send_message(sock, msg) + return recv_message(sock) + + def send_response( + self, + request_id: str, + status: str, + result: Optional[dict] = None, + error: Optional[dict] = None, + ) -> None: + sock = self._require_sock() + msg: dict = {"id": request_id, "status": status} + if result is not None: + msg["result"] = result + if error is not None: + msg["error"] = error + send_message(sock, msg) + + def wait_for_message(self) -> Optional[dict]: + sock = self._require_sock() + return recv_message(sock) diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/__init__.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/config.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/config.py new file mode 100644 index 000000000..decc883d2 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/config.py @@ -0,0 +1,44 @@ +import fnmatch +import os +from typing import Optional + + +class BrokerConfig: + def __init__(self): + self._allowed_ping_domains = self._parse_env("ALLOWED_PING_DOMAINS", "") + self._allowed_domains = self._parse_env("ALLOWED_DOMAINS", "") + + def _parse_env(self, key: str, default: str) -> list: + raw = os.environ.get(key, default) + return [p.strip() for p in raw.split(",") if p.strip()] + + @property + def allowed_ping_domains(self) -> list: + return list(self._allowed_ping_domains) + + @property + def allowed_domains(self) -> list: + return list(self._allowed_domains) + + def update( + self, + allowed_ping_domains: Optional[list] = None, + allowed_domains: Optional[list] = None, + ) -> list: + updated = [] + if allowed_ping_domains is not None: + self._allowed_ping_domains = list(allowed_ping_domains) + updated.append("allowed_ping_domains") + if allowed_domains is not None: + self._allowed_domains = list(allowed_domains) + updated.append("allowed_domains") + return updated + + def is_ping_domain_allowed(self, domain: str) -> bool: + for pattern in self.allowed_ping_domains: + if fnmatch.fnmatch(domain, pattern): + return True + return False + + +broker_config = BrokerConfig() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/__init__.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/http.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/http.py new file mode 100644 index 000000000..2f6690291 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/http.py @@ -0,0 +1,13 @@ +import logging + +logger = logging.getLogger(__name__) + + +async def handle_http_request(params: dict) -> dict: + return { + "status": "error", + "error": { + "code": "NOT_IMPLEMENTED", + "message": "HTTP proxy not implemented in Phase 1", + }, + } diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/ping.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/ping.py new file mode 100644 index 000000000..11bb1e484 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/handlers/ping.py @@ -0,0 +1,60 @@ +import asyncio +import logging + +from ..config import broker_config + +logger = logging.getLogger(__name__) + + +async def handle_ping(params: dict) -> dict: + domain = params.get("domain") + count = params.get("count", 3) + timeout = params.get("timeout", 5) + + if not domain: + return { + "status": "error", + "error": { + "code": "INVALID_PARAMS", + "message": "Missing 'domain' parameter", + }, + } + + if not broker_config.is_ping_domain_allowed(domain): + return { + "status": "error", + "error": { + "code": "POLICY_DENIED", + "message": f"Domain not in ping allowlist: {domain}", + }, + } + + cmd = ["ping", "-c", str(int(count)), "-t", str(int(timeout)), domain] + logger.info("Executing: %s", " ".join(cmd)) + + try: + proc = await asyncio.create_subprocess_exec( + *cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=int(timeout) + 10) + + return { + "status": "ok", + "result": { + "exit_code": proc.returncode, + "stdout": stdout.decode("utf-8", errors="replace"), + "stderr": stderr.decode("utf-8", errors="replace"), + "domain": domain, + "count": count, + "timeout": timeout, + }, + } + except asyncio.TimeoutError: + return { + "status": "error", + "error": {"code": "PING_TIMEOUT", "message": f"Ping to {domain} timed out"}, + } + except Exception as e: + return {"status": "error", "error": {"code": "PING_FAILED", "message": str(e)}} diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/ipc_server.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/ipc_server.py new file mode 100644 index 000000000..4fcdb70f0 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/ipc_server.py @@ -0,0 +1,109 @@ +import asyncio +import json +import logging +import os +import struct +from pathlib import Path + +from .config import broker_config +from .handlers.http import handle_http_request +from .handlers.ping import handle_ping + +logger = logging.getLogger(__name__) + +HEADER_FORMAT = ">I" +HEADER_SIZE = 4 + +# Method -> async handler. `heartbeat` and `configure` are handled inline in +# _handle_connection (they need direct access to the connection/config), so they +# are not registered here. +HANDLERS = { + "ping": handle_ping, + "http_request": handle_http_request, +} + + +async def _recv_message(reader: asyncio.StreamReader) -> dict | None: + try: + header = await reader.readexactly(HEADER_SIZE) + except asyncio.IncompleteReadError: + return None + length = struct.unpack(HEADER_FORMAT, header)[0] + payload = await reader.readexactly(length) + message: dict = json.loads(payload.decode("utf-8")) + return message + + +async def _send_message(writer: asyncio.StreamWriter, msg: dict) -> None: + payload = json.dumps(msg).encode("utf-8") + header = struct.pack(HEADER_FORMAT, len(payload)) + writer.write(header + payload) + await writer.drain() + + +async def _handle_connection(reader: asyncio.StreamReader, writer: asyncio.StreamWriter): + peer = writer.get_extra_info("peername") + logger.info("Agent connected: %s", peer) + + try: + while True: + msg = await _recv_message(reader) + if msg is None: + logger.info("Agent disconnected") + break + + request_id = msg.get("id", "unknown") + method = msg.get("method", "") + params = msg.get("params", {}) + + logger.info("Request %s: method=%s", request_id, method) + + if method == "heartbeat": + response = {"id": request_id, "status": "ok", "result": {"alive": True}} + elif method == "configure": + updated = broker_config.update( + allowed_ping_domains=params.get("allowed_ping_domains"), + allowed_domains=params.get("allowed_domains"), + ) + response = { + "id": request_id, + "status": "ok", + "result": {"updated": updated}, + } + elif method in HANDLERS: + handler = HANDLERS[method] + result = await handler(params) + response = {"id": request_id, **result} + else: + response = { + "id": request_id, + "status": "error", + "error": { + "code": "UNKNOWN_METHOD", + "message": f"Unknown method: {method}", + }, + } + + await _send_message(writer, response) + except Exception as e: + logger.exception("Error handling connection: %s", e) + finally: + writer.close() + await writer.wait_closed() + + +async def start_server(socket_path: str): + path = Path(socket_path) + if path.exists(): + path.unlink() + path.parent.mkdir(parents=True, exist_ok=True) + + server = await asyncio.start_unix_server(_handle_connection, path=socket_path) + # Intentional: the socket is created by the (root) broker, but the untrusted + # agent runs as UID 1000 and must be able to connect to it. Cross-UID access + # to this IPC socket is core to the sandbox design. + os.chmod(socket_path, 0o777) # nosec B103 + logger.info("Broker IPC server listening on %s", socket_path) + + async with server: + await server.serve_forever() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/main.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/main.py new file mode 100644 index 000000000..ec5c40773 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/broker/src/main.py @@ -0,0 +1,24 @@ +import asyncio +import logging +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..")) + +from .ipc_server import start_server + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(name)s] %(levelname)s: %(message)s", +) +logger = logging.getLogger(__name__) + + +def main(): + socket_path = os.environ.get("IPC_SOCKET_PATH", "/tmp/ipc/broker.sock") + logger.info("Starting broker, socket=%s", socket_path) + asyncio.run(start_server(socket_path)) + + +if __name__ == "__main__": + main() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/cleanup.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/cleanup.py new file mode 100644 index 000000000..1ec449d15 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/cleanup.py @@ -0,0 +1,98 @@ +""" +Tear down the Egress-Controlled Code Execution demo. + +Reads ``runtime_config.json`` (written by ``deploy.py``), stops the sandbox and +broker containers (mirroring the supervisor's own shutdown order), then deletes +the AgentCore Runtime so it stops incurring cost. + +Pass ``--delete-ecr`` to also delete the three ECR repositories that hold the +images, and ``--delete-role`` to delete the IAM execution role — but only if +``deploy.py`` created it (a role you supplied via ``ROLE_ARN`` is left alone). + +Usage: + python cleanup.py [--delete-ecr] [--delete-role] +""" + +import json +import os +import sys +import uuid + +import boto3 + +CONFIG_FILE = "runtime_config.json" +ECR_REPO = "egress-coding-execution" + + +def main(): + delete_ecr = "--delete-ecr" in sys.argv[1:] + delete_role = "--delete-role" in sys.argv[1:] + + try: + with open(CONFIG_FILE) as f: + config = json.load(f) + except FileNotFoundError: + print(f"Error: {CONFIG_FILE} not found. Nothing to clean up.") + sys.exit(1) + + region = config["region"] + runtime_id = config["runtime_id"] + runtime_arn = config["runtime_arn"] + control = boto3.client("bedrock-agentcore-control", region_name=region) + runtime = boto3.client("bedrock-agentcore", region_name=region) + + print(f"Cleaning up runtime {runtime_id} (region {region})\n") + + # Best-effort: stop the containers via the supervisor before deleting the + # runtime. A fresh session id is fine — these commands are idempotent. + session_id = f"egress-coding-exec-cleanup-{uuid.uuid4().hex}" + for command in ("stop_agent", "stop_broker"): + try: + runtime.invoke_agent_runtime( + agentRuntimeArn=runtime_arn, + contentType="application/json", + accept="application/json", + runtimeSessionId=session_id, + payload=json.dumps({"command": command, "params": {}}).encode("utf-8"), + ) + print(f" {command}: requested") + except Exception as e: # noqa: BLE001 - cleanup is best-effort + print(f" {command}: skipped ({e})") + + try: + control.delete_agent_runtime(agentRuntimeId=runtime_id) + print("✓ Runtime delete requested (transitions to DELETING)") + except Exception as e: # noqa: BLE001 + print(f" Warning: delete_agent_runtime failed: {e}") + + if delete_ecr: + ecr = boto3.client("ecr", region_name=region) + for component in ("supervisor", "broker", "agent"): + repo = f"{ECR_REPO}/{component}" + try: + ecr.delete_repository(repositoryName=repo, force=True) + print(f"✓ Deleted ECR repo {repo}") + except Exception as e: # noqa: BLE001 + print(f" Warning: could not delete {repo}: {e}") + + if delete_role: + role_name = config.get("role_name") + if not role_name: + print(" Skipping role deletion (deploy.py did not create the role)") + else: + iam = boto3.client("iam") + try: + for p in iam.list_role_policies(RoleName=role_name).get("PolicyNames", []): + iam.delete_role_policy(RoleName=role_name, PolicyName=p) + iam.delete_role(RoleName=role_name) + print(f"✓ Deleted IAM role {role_name}") + except Exception as e: # noqa: BLE001 + print(f" Warning: could not delete role {role_name}: {e}") + + if os.path.exists(CONFIG_FILE): + os.remove(CONFIG_FILE) + print("\n✓ Cleanup complete") + + +if __name__ == "__main__": + main() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/deploy.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/deploy.py new file mode 100644 index 000000000..d88e4d484 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/deploy.py @@ -0,0 +1,223 @@ +""" +Deploy the Egress-Controlled Code Execution sample to AgentCore Runtime. + +Creates (or reuses) an AgentCore Runtime from the pre-built ``supervisor`` image, +waits until it is READY, and writes ``runtime_config.json`` for ``invoke.py`` / +``cleanup.py`` to consume. + +Prerequisites (this script does NOT build images — that needs Docker + buildx + +QEMU for linux/arm64; see the README "Building and pushing the images" section): + * The three images pushed to ECR: ``supervisor``, ``broker``, ``agent``. + * An IAM execution role AgentCore can assume (trust ``bedrock-agentcore.amazonaws.com``) + with permissions to pull from ECR and write CloudWatch Logs. + +Usage: + python deploy.py +""" + +import json +import os +import sys +import time + +import boto3 +from boto3.session import Session + +# --- Parameters (edit for your own account) -------------------------------- +ROLE_NAME = "EgressCodingExecutionRole" # IAM execution role name... +ROLE_ARN = None # ...or set the full ARN here to override ROLE_NAME +ECR_REPO = "egress-coding-execution" # base ECR repo (holds supervisor/broker/agent) +IMAGE_TAG = "latest" # image tag to use for all three images +RUNTIME_NAME = "egress_coding_execution_demo" # AgentCore Runtime name (created or reused) + +CONFIG_FILE = "runtime_config.json" + +session = Session() +REGION = session.region_name or "us-east-1" +ACCOUNT_ID = session.client("sts").get_caller_identity()["Account"] # never hardcode + +ECR_BASE = f"{ACCOUNT_ID}.dkr.ecr.{REGION}.amazonaws.com/{ECR_REPO}" +SUPERVISOR_IMAGE = f"{ECR_BASE}/supervisor:{IMAGE_TAG}" +BROKER_IMAGE = f"{ECR_BASE}/broker:{IMAGE_TAG}" +AGENT_IMAGE = f"{ECR_BASE}/agent:{IMAGE_TAG}" + +control = boto3.client("bedrock-agentcore-control", region_name=REGION) + + +def check_images_exist(): + """Fail fast with a clear message if any of the three images is missing.""" + ecr = boto3.client("ecr", region_name=REGION) + for component in ("supervisor", "broker", "agent"): + repo = f"{ECR_REPO}/{component}" + try: + ecr.describe_images(repositoryName=repo, imageIds=[{"imageTag": IMAGE_TAG}]) + except Exception as e: # noqa: BLE001 - surface any ECR lookup failure clearly + print( + f"✗ Image {repo}:{IMAGE_TAG} not found in ECR ({e}).\n" + " Build and push the three images first — see the README " + '"Building and pushing the images" section.' + ) + sys.exit(1) + print("✓ All three images present in ECR") + + +def create_execution_role(): + """Create (or reuse) the AgentCore execution role, returning its ARN. + + Unlike the LLM-calling samples, this role grants no ``bedrock:InvokeModel`` — + the supervisor only needs to pull the three images from ECR and write logs. + """ + iam = boto3.client("iam") + trust = { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": {"Service": "bedrock-agentcore.amazonaws.com"}, + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": {"aws:SourceAccount": ACCOUNT_ID}, + "ArnLike": {"aws:SourceArn": f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:*"}, + }, + } + ], + } + policy = { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ECRPull", + "Effect": "Allow", + "Action": [ + "ecr:GetAuthorizationToken", + "ecr:BatchGetImage", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchCheckLayerAvailability", + ], + "Resource": "*", + }, + { + "Sid": "Logs", + "Effect": "Allow", + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents", + "logs:DescribeLogStreams", + ], + "Resource": "*", + }, + ], + } + created = False + try: + role_arn = iam.create_role( + RoleName=ROLE_NAME, + AssumeRolePolicyDocument=json.dumps(trust), + Description="Execution role for the Egress-Controlled Code Execution sample", + )["Role"]["Arn"] + created = True + print(f"✓ Created IAM role: {role_arn}") + except iam.exceptions.EntityAlreadyExistsException: + role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/{ROLE_NAME}" + print(f"✓ Reusing existing IAM role: {role_arn}") + + # Attach the policy first, THEN wait — CreateAgentRuntime validates the role's + # ECR permissions, so the policy (not just the role) must have propagated. + iam.put_role_policy( + RoleName=ROLE_NAME, + PolicyName="ece-ecr-logs", + PolicyDocument=json.dumps(policy), + ) + if created: + print(" waiting for the new role + policy to propagate ...") + time.sleep(15) + return role_arn + + +def find_runtime(name): + """Return (agentRuntimeId, agentRuntimeArn) for an existing runtime, or None.""" + kwargs = {} + while True: + resp = control.list_agent_runtimes(**kwargs) + for rt in resp.get("agentRuntimes", []): + if rt.get("agentRuntimeName") == name: + return rt["agentRuntimeId"], rt["agentRuntimeArn"] + token = resp.get("nextToken") + if not token: + return None + kwargs = {"nextToken": token} + + +def wait_until_ready(runtime_id, timeout=600, interval=15): + """Poll GetAgentRuntime until READY (or raise on a terminal/failed state).""" + deadline = time.time() + timeout + last_status = None + while time.time() < deadline: + resp = control.get_agent_runtime(agentRuntimeId=runtime_id) + status = resp["status"] + if status != last_status: + print(f" status: {status}") + last_status = status + if status == "READY": + return + if "FAILED" in status or status in ("DELETING",): + reason = resp.get("failureReason", "(no reason provided)") + raise RuntimeError(f"Runtime entered {status}: {reason}") + time.sleep(interval) + raise TimeoutError(f"Runtime not READY within {timeout}s (last: {last_status})") + + +def main(): + os.chdir(os.path.dirname(os.path.abspath(__file__))) + + print(f"Account : {ACCOUNT_ID}") + print(f"Region : {REGION}") + print(f"Supervisor: {SUPERVISOR_IMAGE}\n") + + check_images_exist() + + # Use an explicitly provided role ARN, otherwise create/reuse ours. We record + # whether we own the role so cleanup only deletes a role this script created. + role_created_by_us = ROLE_ARN is None + role_arn = ROLE_ARN or create_execution_role() + + existing = find_runtime(RUNTIME_NAME) + if existing: + runtime_id, runtime_arn = existing + print(f"✓ Reusing existing runtime '{RUNTIME_NAME}': {runtime_id}") + else: + print(f"Creating runtime '{RUNTIME_NAME}' ...") + created = control.create_agent_runtime( + agentRuntimeName=RUNTIME_NAME, + agentRuntimeArtifact={"containerConfiguration": {"containerUri": SUPERVISOR_IMAGE}}, + roleArn=role_arn, + networkConfiguration={"networkMode": "PUBLIC"}, + description="Egress-Controlled Code Execution supervisor (sandboxed untrusted code)", + ) + runtime_id = created["agentRuntimeId"] + runtime_arn = created["agentRuntimeArn"] + print(f"✓ Created runtime: {runtime_id}") + + print("\nWaiting for runtime to become READY ...") + wait_until_ready(runtime_id) + print("✓ Runtime is READY") + + with open(CONFIG_FILE, "w") as f: + json.dump( + { + "region": REGION, + "runtime_id": runtime_id, + "runtime_arn": runtime_arn, + "broker_image": BROKER_IMAGE, + "agent_image": AGENT_IMAGE, + "role_name": ROLE_NAME if role_created_by_us else None, + }, + f, + indent=2, + ) + print(f"\n✓ Deployment complete! Wrote {CONFIG_FILE}. Test with: python invoke.py") + + +if __name__ == "__main__": + main() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/images/architecture.png b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/images/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..99c54af7569d9703429881797d664193c6618627 GIT binary patch literal 161027 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%0AujU%uML?v={Ir0U3cWY^vE4&&T1gd_Tq{t>hD( z>-eYEhI%w zM;WEK>?l~^-~{v8UxbNt8BRZT1@!rRa7vVSRuUt$BGM0z6vHIu521r=1}f8#6(1Z1ZZw34F~Y8ZTJ|RMjDS>jLo#l-gAi-$q$q!J8hAWMgIRxtw#_72{lo&@!<1@7|J> zZyY3MuvCZ0BEZKKI4l4-P1@e8%Fc*{`=>P+*pO*Da0R5nSNZH=--u@-c2-p|J4WEe zKtjPw|K&+pzHmmem$huqp8a^ERAP*+9nPBk1Mq4-5e`?mIXUfYY<@gu{LU*i50u~P zosU2ixBa563O3WmOrp80?SsK=4ms07Ub&f=C=jp7zURVP5?mU1kfoMQB~(xuI9`#x ztzTUn9E`)27KkCS3Bgbc%UvlgJ2ZPi@EvkIdv@>|!ix{~WSah(dT#Fk;;o6vLpKHZVvLqMBB^=5!%q|){Ys!y-PcnTN{F?MO20)g2= z$vm=?Y0e;E!s~yytd{JF$AfzLaML1LbelW!E8fJ^l;>#SgZ}u-nHAPUMrw!Nw3if^ zIWMImXYPK`@NA`~&r-rKDh{|0g6gFbd&N zRn2cbS^4w%$5D}0)58=sQC9gunO>5vO#7jT__HH32iQ9^+ zjS{wglsO8Yd|k28!{GU}K_F3D@Z*V!iJ2}j_?0XZd(wINXmw_@TTjQrICVEp?I}Cr z0$(q~8^mrFG*X~Pv6?coTaek~35LCeTDD5Z@Gw}l9k*vkt!34)fl0kaDz29N3w^cu zE5B_Rk)-{plZEQTAz@hT1c3b{uULYu5xJrHt zDGdi2wGkV3Fj&e%H**WpfVl=W{+E7OixpYUIjGLW!YDoc*WZqac*(DiSj;4*>pg4U z_o+;OskWLrfqZ~ghbF~aTvq~%^YScbnN;oB#0?Vb09wNCYPZG{0Pfv^i!Vc2ClZFT zk}Wgxv7FyM);0uOo}I|2c}r~KTl+x0NOBHSJzt8;4aXLbXpY;y83}iz0=>=Vw9t4) zVSFB{ArOy!!nOKSsT?Y?@&4(>)>48uT5!X)GRh@Z)Q_}I%0>tY_ebMW!4k%0A8hk4|rJhHIff>)tNLb3N#CD_Z%}X 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 agent -> broker -> egress path in one session: + + 1. start_broker (trusted egress proxy) + 2. start_agent (untrusted sandbox, no network of its own) + 3. configure_broker (set the egress allowlist at runtime) + 4. status (both containers running) + 5. ping_domain ALLOW (amazon.com -> permitted, ping executes) + 6. ping_domain DENY (aws.amazon.com -> blocked by the broker allowlist) + +The allow-vs-deny contrast is the security boundary this sample demonstrates. Both +domains are Amazon's: the allowlist entry ``amazon.com`` is an exact match, so the +subdomain ``aws.amazon.com`` is denied — showing the policy is a strict allowlist, not a +substring/suffix match. + +Usage: + python invoke.py +""" + +import json +import sys +import uuid + +import boto3 + +CONFIG_FILE = "runtime_config.json" + +# Allowlist applied at runtime via configure_broker (dynamic egress policy). +# Exact-match only (fnmatch); use a glob like "*.amazon.com" to allow subdomains. +ALLOWED_PING_DOMAINS = ["amazon.com"] + + +def load_config(): + try: + with open(CONFIG_FILE) as f: + return json.load(f) + except FileNotFoundError: + print(f"Error: {CONFIG_FILE} not found. Run: python deploy.py") + sys.exit(1) + + +def make_invoker(runtime, runtime_arn, session_id): + """Return an ``invoke(command, params)`` bound to one runtime session.""" + + def invoke(command, params=None, show=True): + body = {"command": command, "params": params or {}} + resp = runtime.invoke_agent_runtime( + agentRuntimeArn=runtime_arn, + contentType="application/json", + accept="application/json", + runtimeSessionId=session_id, + payload=json.dumps(body).encode("utf-8"), + ) + result = json.loads(resp["response"].read().decode("utf-8")) + if show: + print(f"\n$ {command} {json.dumps(params or {})}") + print(json.dumps(result, indent=2)) + return result + + return invoke + + +def main(): + config = load_config() + region = config["region"] + runtime = boto3.client("bedrock-agentcore", region_name=region) + + # One session id (>= 33 chars), reused so every command hits the same + # supervisor session and its running containers. + session_id = f"egress-coding-exec-demo-{uuid.uuid4().hex}" + assert len(session_id) >= 33, "runtimeSessionId must be at least 33 characters" + print(f"Session id: {session_id}") + + invoke = make_invoker(runtime, config["runtime_arn"], session_id) + + # 1. Start the broker (trusted egress proxy) + resp = invoke("start_broker", {"image_uri": config["broker_image"]}) + assert resp.get("status") == "ok", f"start_broker failed: {resp}" + + # 2. Start the agent (untrusted sandbox) + resp = invoke("start_agent", {"image_uri": config["agent_image"]}) + assert resp.get("status") == "ok", f"start_agent failed: {resp}" + + # 3. Configure the broker's egress allowlist (at runtime, no restart) + resp = invoke("configure_broker", {"allowed_ping_domains": ALLOWED_PING_DOMAINS}) + assert resp.get("status") == "ok", f"configure_broker failed: {resp}" + assert "allowed_ping_domains" in resp.get("result", {}).get("updated", []), resp + + # 4. Status — both containers should be running + resp = invoke("status") + assert resp.get("broker") == "running", f"broker not running: {resp}" + assert resp.get("agent") == "running", f"agent not running: {resp}" + + # 5. ALLOW: broker lets the request through and the ping executes. + # We do NOT assert ICMP reachability (exit_code 0): inside the microVM the + # echo replies may not complete, which is a network-path artifact, not a + # policy result. + allow = invoke("ping_domain", {"domain": "amazon.com", "count": 3, "timeout": 5}) + assert allow.get("status") == "ok", f"expected ok, got: {allow}" + allow_result = allow.get("result", {}) + assert "not in ping allowlist" not in allow_result.get("stderr", ""), f"unexpectedly denied: {allow_result}" + assert "PING amazon.com" in allow_result.get("stdout", ""), f"ping did not execute: {allow_result}" + print("\nALLOW: broker PERMITTED the request and ping executed against amazon.com.") + + # 6. DENY: aws.amazon.com is also Amazon's, but the allowlist entry "amazon.com" + # is an exact match, so the subdomain is blocked before any ping runs. The + # agent wraps the POLICY_DENIED error into a ping-style result (status stays + # "ok", exit_code -1, stderr carries the denial). + deny = invoke("ping_domain", {"domain": "aws.amazon.com", "count": 3, "timeout": 5}) + assert deny.get("status") == "ok", f"unexpected envelope: {deny}" + deny_result = deny.get("result", {}) + assert "not in ping allowlist" in deny_result.get("stderr", ""), f"expected a policy denial, got: {deny_result}" + print("DENY: broker BLOCKED the ping to aws.amazon.com (not in the allowlist).") + + print("\n✓ Demo complete. Tear down with: python cleanup.py") + + +if __name__ == "__main__": + main() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/requirements-dev.txt b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/requirements-dev.txt new file mode 100644 index 000000000..666f0248d --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/requirements-dev.txt @@ -0,0 +1,2 @@ +-r requirements.txt +pytest>=7.4 diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/requirements.txt b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/requirements.txt new file mode 100644 index 000000000..63d05e023 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/requirements.txt @@ -0,0 +1 @@ +boto3>=1.38.0 diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/shared/ipc.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/shared/ipc.py new file mode 100644 index 000000000..589a3e2c3 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/shared/ipc.py @@ -0,0 +1,35 @@ +import json +import socket +import struct +from typing import Optional + +HEADER_SIZE = 4 +HEADER_FORMAT = ">I" + + +def send_message(sock: socket.socket, msg: dict) -> None: + payload = json.dumps(msg).encode("utf-8") + header = struct.pack(HEADER_FORMAT, len(payload)) + sock.sendall(header + payload) + + +def recv_message(sock: socket.socket) -> Optional[dict]: + header = _recv_exact(sock, HEADER_SIZE) + if header is None: + return None + (length,) = struct.unpack(HEADER_FORMAT, header) + payload = _recv_exact(sock, length) + if payload is None: + return None + message: dict = json.loads(payload.decode("utf-8")) + return message + + +def _recv_exact(sock: socket.socket, n: int) -> Optional[bytes]: + buf = bytearray() + while len(buf) < n: + chunk = sock.recv(n - len(buf)) + if not chunk: + return None + buf.extend(chunk) + return bytes(buf) diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/requirements.txt b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/requirements.txt new file mode 100644 index 000000000..1b449a3bf --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/requirements.txt @@ -0,0 +1,2 @@ +bedrock-agentcore>=0.1.0 +boto3>=1.38.0 diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/__init__.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/containerd.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/containerd.py new file mode 100644 index 000000000..29e8ecf95 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/containerd.py @@ -0,0 +1,94 @@ +import logging +import os +import subprocess + +logger = logging.getLogger(__name__) + +CONTAINERD_SOCKET = os.environ.get("CONTAINERD_SOCKET", "/run/containerd/containerd.sock") + + +def pull_image(image_uri: str, ecr_token: str) -> None: + cmd = [ + "ctr", + "-a", + CONTAINERD_SOCKET, + "images", + "pull", + "--user", + f"AWS:{ecr_token}", + image_uri, + ] + logger.info("Pulling image: %s", image_uri) + result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) + if result.returncode != 0: + raise RuntimeError(f"Image pull failed: {result.stderr}") + logger.info("Image pulled successfully: %s", image_uri) + + +def start_container(ctr_args: list) -> None: + logger.info("Starting container: %s", " ".join(ctr_args)) + result = subprocess.run(ctr_args, capture_output=True, text=True, timeout=60) + if result.returncode != 0: + raise RuntimeError(f"Container start failed: {result.stderr}") + logger.info("Container started successfully") + + +def stop_container(container_name: str) -> None: + kill_cmd = ["ctr", "-a", CONTAINERD_SOCKET, "tasks", "kill", container_name] + logger.info("Killing container task: %s", container_name) + subprocess.run(kill_cmd, capture_output=True, text=True, timeout=30) + + task_del_cmd = ["ctr", "-a", CONTAINERD_SOCKET, "tasks", "delete", container_name] + logger.info("Deleting task: %s", container_name) + subprocess.run(task_del_cmd, capture_output=True, text=True, timeout=30) + + delete_cmd = [ + "ctr", + "-a", + CONTAINERD_SOCKET, + "containers", + "delete", + container_name, + ] + logger.info("Deleting container: %s", container_name) + result = subprocess.run(delete_cmd, capture_output=True, text=True, timeout=30) + if result.returncode != 0: + logger.warning("Container delete may have failed: %s", result.stderr) + + +def get_container_status(container_name: str) -> str: + cmd = ["ctr", "-a", CONTAINERD_SOCKET, "tasks", "ls"] + result = subprocess.run(cmd, capture_output=True, text=True, timeout=10) + if result.returncode != 0: + return "unknown" + + for line in result.stdout.strip().split("\n"): + parts = line.split() + if parts and parts[0] == container_name: + return parts[2].lower() if len(parts) > 2 else "exists" + + return "not_started" + + +def list_containers() -> dict: + """Return the raw containerd view from inside the runtime microVM. + + Captures `ctr tasks ls` (running tasks + PIDs + state) and + `ctr containers ls` (all created containers + their images). + """ + tasks = subprocess.run( + ["ctr", "-a", CONTAINERD_SOCKET, "tasks", "ls"], + capture_output=True, + text=True, + timeout=10, + ) + containers = subprocess.run( + ["ctr", "-a", CONTAINERD_SOCKET, "containers", "ls"], + capture_output=True, + text=True, + timeout=10, + ) + return { + "tasks_ls": tasks.stdout if tasks.returncode == 0 else tasks.stderr, + "containers_ls": (containers.stdout if containers.returncode == 0 else containers.stderr), + } diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/ecr.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/ecr.py new file mode 100644 index 000000000..83c4ecce7 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/ecr.py @@ -0,0 +1,15 @@ +import base64 +import logging + +import boto3 + +logger = logging.getLogger(__name__) + + +def get_ecr_token(region: str = "us-east-1") -> str: + client = boto3.client("ecr", region_name=region) + response = client.get_authorization_token() + auth_data = response["authorizationData"][0] + token = base64.b64decode(auth_data["authorizationToken"]).decode("utf-8") + # Token format is "AWS:" + return token.split(":", 1)[1] diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/main.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/main.py new file mode 100644 index 000000000..252a26a39 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/main.py @@ -0,0 +1,204 @@ +import json +import logging +import os +import sys +from pathlib import Path + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..")) + +from bedrock_agentcore.runtime import BedrockAgentCoreApp + +from .containerd import ( + get_container_status, + list_containers, + pull_image, + start_container, + stop_container, +) +from .ecr import get_ecr_token +from .profiles import IPC_DIR, WORKSPACE_DIR, get_agent_ctr_args, get_broker_ctr_args +from .task_dispatch import TaskDispatcher + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [supervisor] %(levelname)s: %(message)s", +) +logger = logging.getLogger(__name__) + +BROKER_CONTAINER = "broker" +AGENT_CONTAINER = "agent" + +dispatcher = TaskDispatcher(socket_path=os.path.join(IPC_DIR, "supervisor.sock")) + +Path(IPC_DIR).mkdir(parents=True, exist_ok=True) +Path(WORKSPACE_DIR).mkdir(parents=True, exist_ok=True) +dispatcher.start() +logger.info("Supervisor ready") + +app = BedrockAgentCoreApp() + + +@app.entrypoint +async def handle(payload): + data = json.loads(payload) if isinstance(payload, str) else payload + command = data.get("command") + params = data.get("params", {}) + + if command == "start_broker": + return await _start_broker(params) + elif command == "start_agent": + return await _start_agent(params) + elif command == "ping_domain": + return await _ping_domain(params) + elif command == "configure_broker": + return await _configure_broker(params) + elif command == "stop_broker": + return await _stop_broker() + elif command == "stop_agent": + return await _stop_agent() + elif command == "status": + return _status() + elif command == "list_containers": + return _list_containers() + else: + return {"status": "error", "message": f"Unknown command: {command}"} + + +def _status(): + return { + "status": "ok", + "broker": get_container_status(BROKER_CONTAINER), + "agent": get_container_status(AGENT_CONTAINER), + } + + +def _list_containers(): + return {"status": "ok", "result": list_containers()} + + +async def _start_broker(params: dict): + try: + image_uri = params["image_uri"] + env = params.get("env") + + region = os.environ.get("AWS_REGION", "us-east-1") + token = get_ecr_token(region) + pull_image(image_uri, token) + + ctr_args = get_broker_ctr_args(BROKER_CONTAINER, image_uri, env=env) + start_container(ctr_args) + + return {"status": "ok", "message": "Broker started"} + except Exception as e: + logger.exception("Failed to start broker") + return {"status": "error", "message": str(e)} + + +async def _start_agent(params: dict): + try: + image_uri = params["image_uri"] + + region = os.environ.get("AWS_REGION", "us-east-1") + token = get_ecr_token(region) + pull_image(image_uri, token) + + ctr_args = get_agent_ctr_args(AGENT_CONTAINER, image_uri) + start_container(ctr_args) + + if not dispatcher.wait_for_agent(timeout=60): + raise RuntimeError("Agent did not connect within 60 seconds") + + return {"status": "ok", "message": "Agent started and connected"} + except Exception as e: + logger.exception("Failed to start agent") + return {"status": "error", "message": str(e)} + + +async def _ping_domain(params: dict): + broker_status = get_container_status(BROKER_CONTAINER) + agent_status = get_container_status(AGENT_CONTAINER) + + if broker_status != "running": + return { + "status": "error", + "message": f"Broker not running (status: {broker_status})", + } + if agent_status != "running": + return { + "status": "error", + "message": f"Agent not running (status: {agent_status})", + } + + domain = params.get("domain") + if not domain: + return {"status": "error", "message": "Missing 'domain' parameter"} + + result = dispatcher.dispatch_task( + "ping_domain", + { + "domain": domain, + "count": params.get("count", 3), + "timeout": params.get("timeout", 5), + }, + ) + + if result and result.get("status") == "ok": + return {"status": "ok", "result": result.get("result", {})} + else: + error = result.get("error", {}) if result else {} + return {"status": "error", "message": error.get("message", "Ping task failed")} + + +async def _configure_broker(params: dict): + broker_status = get_container_status(BROKER_CONTAINER) + if broker_status != "running": + return { + "status": "error", + "message": f"Broker not running (status: {broker_status})", + } + + import socket + import uuid + + from shared.ipc import recv_message, send_message + + broker_socket_path = os.path.join(IPC_DIR, "broker.sock") + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + try: + sock.connect(broker_socket_path) + msg = { + "id": str(uuid.uuid4()), + "method": "configure", + "params": { + "allowed_ping_domains": params.get("allowed_ping_domains"), + "allowed_domains": params.get("allowed_domains"), + }, + } + send_message(sock, msg) + response = recv_message(sock) + return response if response else {"status": "error", "message": "No response from broker"} + except Exception as e: + logger.exception("Failed to configure broker") + return {"status": "error", "message": str(e)} + finally: + sock.close() + + +async def _stop_agent(): + try: + stop_container(AGENT_CONTAINER) + return {"status": "ok", "message": "Agent stopped"} + except Exception as e: + return {"status": "error", "message": str(e)} + + +async def _stop_broker(): + try: + stop_container(BROKER_CONTAINER) + return {"status": "ok", "message": "Broker stopped"} + except Exception as e: + return {"status": "error", "message": str(e)} + + +if __name__ == "__main__": + app.run() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/profiles.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/profiles.py new file mode 100644 index 000000000..6472a21ed --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/profiles.py @@ -0,0 +1,55 @@ +import os +from typing import Optional + +CONTAINERD_SOCKET = os.environ.get("CONTAINERD_SOCKET", "/run/containerd/containerd.sock") +IPC_DIR = "/run/containerd/sandbox-ipc" +WORKSPACE_DIR = "/run/containerd/sandbox-workspace" + + +def get_broker_ctr_args(container_name: str, image_uri: str, env: Optional[dict] = None) -> list: + args = [ + "ctr", + "-a", + CONTAINERD_SOCKET, + "run", + "-d", + "--net-host", + "--mount", + f"type=bind,src={IPC_DIR},dst=/tmp/ipc,options=rbind:rw", + "--mount", + f"type=bind,src={WORKSPACE_DIR},dst=/tmp/workspace,options=rbind:rw", + "--env", + "IPC_SOCKET_PATH=/tmp/ipc/broker.sock", + "--env", + "WORKSPACE_PATH=/tmp/workspace", + ] + + if env: + for key, value in env.items(): + args.extend(["--env", f"{key}={value}"]) + + args.extend([image_uri, container_name]) + return args + + +def get_agent_ctr_args(container_name: str, image_uri: str) -> list: + args = [ + "ctr", + "-a", + CONTAINERD_SOCKET, + "run", + "-d", + "--mount", + f"type=bind,src={IPC_DIR},dst=/tmp/ipc,options=rbind:rw", + "--mount", + f"type=bind,src={WORKSPACE_DIR},dst=/tmp/workspace,options=rbind:rw", + "--env", + "BROKER_SOCKET_PATH=/tmp/ipc/broker.sock", + "--env", + "SUPERVISOR_SOCKET_PATH=/tmp/ipc/supervisor.sock", + "--env", + "WORKSPACE_PATH=/tmp/workspace", + image_uri, + container_name, + ] + return args diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/task_dispatch.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/task_dispatch.py new file mode 100644 index 000000000..de86a2333 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/supervisor/src/task_dispatch.py @@ -0,0 +1,99 @@ +import logging +import os +import socket +import sys +import threading +import uuid +from pathlib import Path +from typing import Optional + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..")) + +from shared.ipc import recv_message, send_message + +logger = logging.getLogger(__name__) + +SUPERVISOR_SOCKET_PATH = os.environ.get("SUPERVISOR_SOCKET_PATH", "/run/containerd/sandbox-ipc/supervisor.sock") + + +class TaskDispatcher: + def __init__(self, socket_path: Optional[str] = None): + self._socket_path = socket_path or SUPERVISOR_SOCKET_PATH + self._server_sock: Optional[socket.socket] = None + self._agent_conn: Optional[socket.socket] = None + self._lock = threading.Lock() + + def start(self): + path = Path(self._socket_path) + if path.exists(): + path.unlink() + path.parent.mkdir(parents=True, exist_ok=True) + + self._server_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self._server_sock.bind(self._socket_path) + self._server_sock.listen(1) + # Intentional: the socket is created by the (root) supervisor, but the + # untrusted agent runs as UID 1000 and must be able to connect to it. + # Cross-UID access to this IPC socket is core to the sandbox design. + os.chmod(self._socket_path, 0o777) # nosec B103 + logger.info("Task dispatch socket listening at %s", self._socket_path) + + def wait_for_agent(self, timeout: float = 60) -> bool: + if self._server_sock is None: + raise RuntimeError("Dispatcher not started; call start() first") + self._server_sock.settimeout(timeout) + try: + self._agent_conn, addr = self._server_sock.accept() + logger.info("Agent connected to task dispatch socket") + return True + except socket.timeout: + logger.error("Timed out waiting for agent to connect") + return False + + def dispatch_task(self, method: str, params: dict, timeout: float = 660) -> dict: + with self._lock: + if not self._agent_conn: + return { + "status": "error", + "error": {"code": "NO_AGENT", "message": "Agent not connected"}, + } + + request_id = str(uuid.uuid4()) + msg = {"id": request_id, "method": method, "params": params} + + self._agent_conn.settimeout(timeout) + try: + send_message(self._agent_conn, msg) + response = recv_message(self._agent_conn) + return ( + response + if response + else { + "status": "error", + "error": { + "code": "NO_RESPONSE", + "message": "Agent disconnected", + }, + } + ) + except socket.timeout: + return { + "status": "error", + "error": {"code": "TIMEOUT", "message": "Agent task timed out"}, + } + except Exception as e: + return { + "status": "error", + "error": {"code": "DISPATCH_ERROR", "message": str(e)}, + } + + def stop(self): + if self._agent_conn: + self._agent_conn.close() + self._agent_conn = None + if self._server_sock: + self._server_sock.close() + self._server_sock = None + path = Path(self._socket_path) + if path.exists(): + path.unlink() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/conftest.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/conftest.py new file mode 100644 index 000000000..d74d60349 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/conftest.py @@ -0,0 +1,16 @@ +"""Pytest path setup. + +The sample is a multi-image project (not an installed package), so the source +directories are made importable here the same way the containers do it via +PYTHONPATH=/app. This lets the tests import `shared.ipc` and the broker sources. +""" + +import os +import sys + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# Sample root (for `shared.ipc`) and the broker package root (for `src.config`). +for path in (ROOT, os.path.join(ROOT, "broker")): + if path not in sys.path: + sys.path.insert(0, path) diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/unit/test_broker_config.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/unit/test_broker_config.py new file mode 100644 index 000000000..c70577b0f --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/unit/test_broker_config.py @@ -0,0 +1,49 @@ +"""Unit tests for the broker allowlist policy (broker/src/config.py).""" + +from src.config import BrokerConfig + + +def test_exact_domain_match_allowed(): + cfg = BrokerConfig() + cfg.update(allowed_ping_domains=["google.com", "amazon.com"]) + assert cfg.is_ping_domain_allowed("google.com") is True + assert cfg.is_ping_domain_allowed("amazon.com") is True + + +def test_domain_not_in_allowlist_is_denied(): + cfg = BrokerConfig() + cfg.update(allowed_ping_domains=["google.com"]) + assert cfg.is_ping_domain_allowed("example.com") is False + + +def test_glob_wildcard_matching(): + """fnmatch glob patterns (e.g. *.amazon.com) are honored.""" + cfg = BrokerConfig() + cfg.update(allowed_ping_domains=["*.amazon.com"]) + assert cfg.is_ping_domain_allowed("aws.amazon.com") is True + assert cfg.is_ping_domain_allowed("docs.amazon.com") is True + assert cfg.is_ping_domain_allowed("amazon.com") is False # no subdomain + + +def test_empty_allowlist_denies_everything(): + cfg = BrokerConfig() + assert cfg.is_ping_domain_allowed("google.com") is False + + +def test_update_reports_which_lists_changed(): + cfg = BrokerConfig() + updated = cfg.update(allowed_ping_domains=["a.com"], allowed_domains=["b.com"]) + assert set(updated) == {"allowed_ping_domains", "allowed_domains"} + + # Only the ping list this time. + updated = cfg.update(allowed_ping_domains=["c.com"]) + assert updated == ["allowed_ping_domains"] + + +def test_allowlist_getters_return_copies(): + """Mutating a returned list must not affect internal state.""" + cfg = BrokerConfig() + cfg.update(allowed_ping_domains=["google.com"]) + returned = cfg.allowed_ping_domains + returned.append("evil.com") + assert "evil.com" not in cfg.allowed_ping_domains diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/unit/test_ipc.py b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/unit/test_ipc.py new file mode 100644 index 000000000..9f56826a3 --- /dev/null +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/tests/unit/test_ipc.py @@ -0,0 +1,55 @@ +"""Unit tests for the shared length-prefixed JSON IPC framing.""" + +import socket +import struct + +from shared.ipc import HEADER_SIZE, recv_message, send_message + + +def test_round_trip_simple_message(): + """A message sent on one end is received identically on the other.""" + a, b = socket.socketpair() + try: + msg = {"id": "abc-123", "method": "ping", "params": {"domain": "google.com"}} + send_message(a, msg) + assert recv_message(b) == msg + finally: + a.close() + b.close() + + +def test_round_trip_preserves_unicode_and_nesting(): + """Nested structures and non-ASCII content survive the round trip.""" + a, b = socket.socketpair() + try: + msg = {"result": {"stdout": "café ✓ 日本", "nested": [1, 2, {"x": True}]}} + send_message(a, msg) + assert recv_message(b) == msg + finally: + a.close() + b.close() + + +def test_recv_returns_none_on_closed_connection(): + """recv_message returns None (not an exception) when the peer closed.""" + a, b = socket.socketpair() + a.close() + try: + assert recv_message(b) is None + finally: + b.close() + + +def test_wire_format_is_big_endian_length_prefix(): + """The 4-byte header is a big-endian uint32 of the JSON payload length.""" + a, b = socket.socketpair() + try: + send_message(a, {"k": "v"}) + header = b.recv(HEADER_SIZE) + (length,) = struct.unpack(">I", header) + payload = b.recv(length) + assert length == len(payload) + assert payload == b'{"k": "v"}' + finally: + a.close() + b.close() diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/README.md b/01-features/02-host-your-agent/01-runtime/03-advanced/README.md index 3525034f2..5d61173d2 100644 --- a/01-features/02-host-your-agent/01-runtime/03-advanced/README.md +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/README.md @@ -10,14 +10,14 @@ Beyond basic agent and tool hosting, AgentCore runtime provides advanced capabil | 02 | [Session Management](02-session-management/) | Maintain context across invocations, session isolation | deploy/invoke/cleanup | | 03 | [Bidirectional Streaming](03-bidirectional-streaming/) | WebSocket-based real-time voice agents | Reference (Docker-based) | | 04 | [Async Agents](04-async-agents/) | Long-running background tasks with async task tracking | Notebooks | -| 04b | [Bidirectional Streaming (WebRTC)](04-bidirectional-streaming-webrtc/) | Voice agents with Kinesis Video Streams | Reference (Docker-based) | | 05 | [Execute Commands](05-execute-commands/) | Run shell commands inside runtime sessions | deploy/invoke/cleanup | | 06 | [Multi-Agent](06-multi-agent/) | Orchestrate multiple agents across runtimes | deploy/invoke/cleanup | -| 06b | [Persistent Filesystems](06-persistent-filesystems/) | Persist files across session stop/resume cycles | deploy/invoke/cleanup | +| 07 | [Persistent Filesystems](07-persistent-filesystems/) | Persist files across session stop/resume cycles | deploy/invoke/cleanup | | 08 | [Connect to VPC Resources](08-connect-to-vpc-resources/) | Deploy agents in your VPC for private resource access | CDK (TypeScript) | -| 08b | [MCP End-to-End](08-mcp-e2e/) | Full MCP feature set: tools, resources, prompts, sampling, elicitation, progress | Notebooks | -| 09 | [MCP Dynamic Client Registration](09-mcp-dynamic-client-registration/) | Auth0 OAuth + DCR for MCP server authentication | deploy/invoke/cleanup | -| 10 | [Middleware Support](10-middleware-support/) | Starlette middleware for observability and error handling | deploy/invoke/cleanup | +| 09 | [MCP End-to-End](09-mcp-e2e/) | Full MCP feature set: tools, resources, prompts, sampling, elicitation, progress | Notebooks | +| 10 | [MCP Dynamic Client Registration](10-mcp-dynamic-client-registration/) | Auth0 OAuth + DCR for MCP server authentication | deploy/invoke/cleanup | +| 11 | [Middleware Support](11-middleware-support/) | Starlette middleware for observability and error handling | deploy/invoke/cleanup | +| 12 | [Egress-Controlled Code Execution](12-egress-coding-execution/) | Sandbox untrusted code in the microVM with broker-mediated, allowlisted egress | Reference (Docker-based) | ## Tutorial Formats From 6f2eee4674aa01cf9a442d66914ffe6b75d16593 Mon Sep 17 00:00:00 2001 From: Fabio Balancin Date: Fri, 10 Jul 2026 04:33:01 -0300 Subject: [PATCH 2/3] Add contributors to CONTRIBUTORS.md Add Fabio Balancin (balancin) and Varun Gunda (vvargu) for the egress-controlled code execution sample. Co-Authored-By: Claude Opus 4.8 (1M context) --- CONTRIBUTORS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 13e076748..c75cd98fe 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -122,3 +122,5 @@ - JobRamos (jobdram) - Will Matos (wilmatos) - Senthil Mohan (skmohan) +- Fabio Balancin (balancin) +- Varun Gunda (vvargu) From d794cc010452a319bb36d754ad08d5ce1dfdea50 Mon Sep 17 00:00:00 2001 From: Fabio Balancin Date: Tue, 14 Jul 2026 15:21:56 -0300 Subject: [PATCH 3/3] Remove redundant Roadmap and Cost Considerations sections from egress-coding-execution README Consolidate into the existing Current status section and drop the broken Roadmap anchor link. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../12-egress-coding-execution/README.md | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/README.md b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/README.md index ab3348b9d..1d541598f 100644 --- a/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/README.md +++ b/01-features/02-host-your-agent/01-runtime/03-advanced/12-egress-coding-execution/README.md @@ -259,30 +259,12 @@ Dockerfile `USER sandbox` (UID 1000) for non-root execution. Explicit namespace capability dropping, and cgroup memory/CPU limits are **deferred to Phase 2** and should be added before any non-experimental use. -## Roadmap - -- **Phase 1 (this sample):** supervisor/broker/agent architecture with `ping_domain` as the - working egress-controlled operation; runtime-configurable allowlist. -- **Phase 2 (deferred):** HTTP proxy + `get_secret` broker handlers (stubs exist), broker - rate/size limits, explicit namespace/capability/cgroup hardening in the `ctr` args. - -## Cost Considerations - -- **AgentCore Runtime** — billed while the runtime exists. `python cleanup.py` deletes it; - run it when you are done. -- **ECR** — storage for the three images. `python cleanup.py --delete-ecr` also deletes the - three repositories. -- **IAM role** — no cost, but `python cleanup.py --delete-role` removes it if `deploy.py` - created it (a role you supplied via `ROLE_ARN` is left untouched). - -For development and testing, tear everything down when not in use. - ## Current status Only **Phase 1** is implemented: the supervisor/broker/agent architecture with `ping_domain` as the working egress-controlled operation. HTTP proxying, secret retrieval, rate limiting, and explicit cgroup/namespace hardening are stubbed or deferred -to Phase 2 — see the [Roadmap](#roadmap) above for the full breakdown. +to Phase 2. ## Disclaimer