SCH: An affordable sandbox for Coding Agents in your AWS account A developer built SCH, a serverless coding harness on AWS AgentCore Runtime that lets coding agents run unattended in isolated cloud containers for a few cents of remote compute per session, excluding model inference costs. SCH addresses two problems the developer identified: keeping a laptop or rented server running for eight-hour agent loops, and the security risk of running long loops with auto-approval flags such as --dangerously-skip-permissions on a machine holding SSH keys and cloud credentials. The harness targets compatibility with at least OpenCode and Claude Code and relies on AWS's pay-as-you-go, session-isolated runtime that shuts down on idle timeout. SCH: an affordable sandbox for Coding Agents in your AWS account Table of Contents Intro intro One Friday morning, I closed my laptop lid while a coding agent kept working in a lightweight container in the cloud. When I opened it again a few hours later, the branch was ready for review, the runtime was already gone, and the remote compute alone had added only a few cents. That figure does not include model inference, which remains a separate line item. Getting there forced me to answer two questions: 1. do I really need to keep my PC, or a remote machine, running for an eight-hour loop? 2. can I let an agent work unattended without also having to build my own sandboxing system? This post is my answer: SCH, a serverless coding harness built on AWS AgentCore . Over the past two years, quite a few labels ending in “engineering” have piled up. Context engineering https://simonwillison.net/2025/Jun/27/context-engineering/ shifted attention from the individual prompt to the information available for the next step. Geoffrey Huntley’s Ralph Wiggum loop https://ghuntley.com/ralph/ , literally while :; do cat PROMPT.md | claude-code; done , showed how much a bash loop can achieve with a fresh context at each iteration and state stored on disk. Loop, graph, and harness engineering followed. The labels change quickly; I mainly needed three concepts to build SCH: - State. Where the work lives after the context window is gone: files, planning documents, git history, and checkpoints. Every loop technique must externalize enough state for the next iteration to pick up where the previous one left off. - Harness. Everything around the model call: tools, hooks, permissions, checks, and the outer loop that decides whether “done” really means done. As a rough approximation, “agent” = “model” + “harness”. - Runtime. The machine that runs the harness: filesystem, network, credentials, and lifetime. Very often, it is the developer’s laptop, with all the limitations that entails. Newer models, combined with the work on these three elements, have also changed the unit of work. A task can run unattended for hours and, across multiple sessions and checkpoints, even for days. This creates two practical problems. 1. Someone has to keep the machine running. An eight-hour loop means eight hours with the laptop on, or a remote server that I have to rent, update, and remember to shut down. 2. Long loops encourage YOLO mode. Unattended work stops as soon as the harness asks for permission. With permission gates enabled, it is easy to come back and find the agent stalled after twelve minutes, waiting for an “okay, proceed.” Many people end up using options such as --dangerously-skip-permissions , --auto , or --yolo . A long session has more opportunities to take an unexpected turn. If it runs with auto-approval on a laptop, the same machine keeping the loop alive often holds SSH keys, cloud credentials, and personal data. The problem grows as soon as you go from one session to three across different branches and tasks: the laptop becomes a host shared by several agents with plenty of room to act. Isolation reduces the blast radius of an error, but it only works if network access and permissions are tuned to the job. A sandbox that is too restrictive stops the agent at the first denied command; one that is too permissive merely moves the problem elsewhere. Over the past few weeks, I looked for a setup that would let me isolate the runtime, run asynchronous, detached tasks, and work with at least OpenCode and Claude Code. I also wanted to avoid servers to administer and sandbox rules to maintain by hand. Because I work extensively with AWS, I had already used Amazon Bedrock AgentCore Runtime https://aws.amazon.com/bedrock/agentcore/ . The closest analogy is a Lambda designed to host AI agents: a serverless runtime with pay-as-you-go pricing and isolated sessions. When the idle timeout kicks in, the runtime disappears and compute returns to zero. Later, I show the figures I collected over roughly ten days of intermittent use. That is how SCH - Serverless Coding Harness came about. It is now public at c-daniele/sch https://github.com/c-daniele/sch . When I need it, AgentCore starts a remote harness that I can reach from the terminal. The runtime does the work and then terminates; SCH saves its state and brings the changes back to the local working copy or to a separate branch. The architectural principle is that durability belongs in the checkpoints, not the runtime . If the repository, agent sessions, and git history can be restored, there is no reason to keep the microVM running. SCH is still a proof of concept, retains some early design decisions, and currently runs only on AWS. I discuss its limitations later. Compared with Claude Code on the web, Codex cloud, or Copilot’s coding agent, SCH requires more setup. In return, repositories, sessions, checkpoints, and inference stay in my AWS account, under IAM policies I define, without locking me into a single harness or provider. What changes in my workflow what-changes-in-my-workflow SCH combines a local CLI with an ARM image that runs OpenCode, Claude Code, or Pi inside an AgentCore microVM. Workspace state is stored in S3, changes come back through Git, and the runtime is removed when it is no longer needed. | Feature | What it lets me do | |---|---| | Session handoff | Start work locally and continue in the cloud without rebuilding the context | | Detached tasks | Turn off the laptop without interrupting execution | | State and checkpoints outside the runtime | Check on a task and resume it even after the microVM has been deleted | | Supervision from Telegram | Receive updates, approve a tool, or send a follow-up away from the terminal | | One workspace per branch | Run several tasks in parallel without sharing writable state | | Centralized image and policies | Use a repeatable environment with harnesses, tools, models, and permissions defined in advance | Three SCH use cases: handoff, workbench, and batch three-sch-use-cases-handoff-workbench-and-batch The following commands assume that SCH has already been deployed. The README quickstart https://github.com/c-daniele/sch covers the prerequisites and initial deployment. 1. Brainstorm locally, hand off, supervise from your phone 1-brainstorm-locally-hand-off-supervise-from-your-phone This is the mode I use most often for non-trivial work. I brainstorm with OpenCode on my laptop until the objectives, files to change, tests, and definition of done are clear. Once the context is ready and the local state is suitable for launching the task, I send the entire conversation to a remote workspace and let the agent continue there: Export the local OpenCode conversation, seed a branch from local HEAD, import the conversation remotely and start the headless task implies --continue : sch task my-project --handoff --branch change/plan-a \ "implement what we agreed, run the tests, fix what breaks" a1b2c3... returns immediately; laptop can go offline Any time later - reads S3, does not wake the microVM: sch status my-project state : succeeded continuation : resumed prior session checkpoint : confirmed The branch lands locally, fast-forward only; review at your pace: sch fetch my-project From this point on, the laptop is optional. Each workspace has a topic in a Telegram group and a workspace prefix on its messages. I receive milestones, to-do list updates, a digest of tool activity, a warning if the heartbeat stops responding, and finally the task outcome with the checkpoint status. Headless tasks run with auto-approval by design. Interactive sessions, however, also have an intermediate detached mode: after starting a session, I leave it running with Ctrl+ , and when the agent asks for permission, I receive Approve/Deny buttons on my phone. The response goes back to the harness hook. If I do not respond within ten minutes SCH APPROVAL TIMEOUT S , SCH falls back to the policy configured in the harness. Free text entered in the topic becomes a follow-up prompt through task --continue . I can type “now update the README too” from my phone and let the harness continue. 2. An isolated AWS workbench 2-an-isolated-aws-workbench Another use case is an isolated workbench for developers who work mainly with AWS services. By attaching an appropriate policy to the AgentCore Runtime IAM role, the remote harness can read a CloudWatch log group, check an IAM policy, prototype a Lambda, or access a DynamoDB table without inheriting the workstation’s credentials. sch run aws-lab fresh remote workspace, straight into the OpenCode TUI sch web aws-lab same backend, in a browser tab sch acp aws-lab same backend, from Zed over ACP The image contains the AWS CLI, the AWS MCP Server, the AWS Documentation MCP Server, and the standard development tools. Bedrock inference uses the same execution role. The default role combines ReadOnlyAccess with permission to invoke Bedrock: convenient for a POC, but too broad for production data, and it should be narrowed for each workspace. Once the session ends, the microVM is destroyed. 3. A backlog of tasks across multiple harnesses and providers 3-a-backlog-of-tasks-across-multiple-harnesses-and-providers For the third workflow, I start with a backlog of tasks that already have specifications, tests, and completion criteria. I can run them unattended, each on its own branch and even with different coding agents: sch task svc-a --branch change/a --harness opencode "implement change A per docs/specs/a.md" sch task svc-b --branch change/b --harness claude "implement change B per docs/specs/b.md" sch task svc-c --branch change/c --harness pi --model