Back to blog

Agentic workflows / Infrastructure

Executing Agentic Workflows for Infra Resources in Sandboxes

Designing a cloud execution environment for infrastructure agents: persistent workspaces, sandbox mounts, resource grants, and evidence-based process cleanup.

An infrastructure agent needs more than a terminal. It needs somewhere to keep its work, access to the right resources, and an execution environment that can be stopped without losing the files it created.

Consider a workflow where an agent investigates a Kubernetes deployment, reads its manifests, prepares a configuration change, and validates the result. The agent may alternate between reading files, editing YAML, and running kubectl. Those operations need a consistent view of the workspace, even though they happen through different tools.

Moving this workflow into the cloud introduces a few design questions. What should each sandbox mount? Where should credentials live? What survives when a sandbox is replaced? How do we know a timed-out command has actually stopped writing files?

We approached these questions by separating the workflow's workspace from its command runtime, then building a custom Bash tool that connects the two.

1. What infrastructure agents need from their execution environment

For our running example, imagine an agent investigating why a deployment is unavailable. It reads the repository's manifests, queries the selected cluster, writes its findings, and prepares a patch for review.

That workflow needs three kinds of state:

Three kinds of workflow state and their intended lifetimes
StateExamplesIntended lifetime
Workflow stateConversation, command history, ownershipAcross turns and browser reconnects
Workspace stateManifests, patches, reports, uncommitted filesAcross sandbox replacement
Runtime stateInstalled packages, temporary home files, running processesUntil the sandbox is retired

Keeping these lifetimes separate makes recovery easier to reason about. An idle sandbox can be removed while the agent's patch remains available. A new sandbox can mount the same workspace and continue the investigation.

Resource access is another part of the environment. A workspace containing deployment manifests does not itself authorize access to the corresponding cluster. The workflow must receive an explicit resource grant before commands can use that resource.

2. Giving each workflow its own workspace

Our implementation separates the agent session from shell execution. The provider session and its file tools run on a supervising daemon. Shell commands run in an OpenSandbox workload. Both see the same session worktree on persistent storage.

A shared workspace with a separate command runtimeThe agent uses read and edit tools to access the session worktree. Its custom Bash tool calls the trusted supervisor, backend authorization, sandbox manager, and sandbox command runtime in order. The runtime accesses the same worktree and the granted infrastructure resource.Agent sessionRead and edit toolsCustom Bash toolTrusted supervisorBackend authorizationSandbox managerSandbox command runtimeSession worktreeGranted infra resource
File tools and sandbox commands share a persistent session worktree. Trusted services select the runtime and its resource authority.

Each session receives a dedicated Git worktree and branch. This gives the agent its own working files while reusing an existing repository's Git objects. Another session can work on a different branch without switching the first session's checkout.

The worktree lives independently of the sandbox. Replacing the command runtime preserves dirty files, untracked reports, and the current patch. Deleting a workspace is a separate lifecycle operation that first requires its writers to stop.

For the deployment investigation, this means a manifest edited through the file tool is immediately available to the next Bash call. There is no upload step between editing and validation.

3. Designing sandbox mounts

The mount layout defines which files a command can reach. It also determines whether everyday development tools behave as expected.

The following paths are illustrative; the important properties are the selected directories and their visibility:

persistent-volume/
  identities/<identity>/
    repositories/service-config/   # Base clone and common Git metadata
    workspaces/investigate-api/    # Selected session worktree
    private-state/                # Supervisor records and journals
    provider-auth/                # Provider authentication source

The sandbox receives the selected repository and worktree. Private supervisor state and provider authentication remain outside its mounts.

Use the same absolute paths

The daemon and sandbox mount the worktree at the same absolute location. If a file tool edits /home/agent/workspaces/investigate-api/deployment.yaml, the shell sees that exact path.

This removes path translation from tool calls, diagnostics, and generated artifacts. It also matters for Git: a linked worktree's .git file points back to metadata in the base repository. Those pointers must resolve inside the sandbox.

Mount the Git metadata that operations need

Mounting only the working files leaves a linked worktree incomplete. Commands such as git status and git commit also need the common Git directory and the selected worktree's metadata.

Our layout makes the base clone read-only except for the Git areas required by supported operations, including objects, refs, logs, and selected worktree metadata. Configuration, hooks, alternates, and ownership pointers have additional read-only protection.

Access granted to each mounted area
Mounted areaAccess
Selected session worktreeRead and write
Required Git objects, refs, logs, and worktree metadataSelective write access
Git configuration, hooks, and ownership pointersRead-only protection
Sibling working directoriesNot mounted
Supervisor state and provider authenticationNot mounted

This detail matters because Git configuration can cause programs to execute. A checkout filter written by an agent could otherwise run during a later repository operation performed by trusted code. Repositories with configuration includes or checkout filters are rejected from this shared Bash path.

Linked worktrees still share repository metadata. They suit workflows within a repository trust domain; mutually untrusted tenants would require reviewing stronger separation, such as independent clones.

Make scratch files visible to both tool paths

An agent may generate a report in Bash and then read it through a file tool. Sandbox-local /tmp does not provide that shared visibility.

We configure standard temporary-file environment variables to point at a locally ignored scratch directory inside the worktree. Files created there remain visible to both tools and survive sandbox replacement. Files written directly to sandbox-local /tmp have the runtime's shorter lifetime.

The storage layer must also support the actual filesystem operations involved: Git locks, atomic renames, and visibility across mounts. A successfully attached volume does not establish those properties by itself.

4. Building a custom Bash tool

The agent sees a small interface:

{
  "command": "kubectl get deployments -n payments",
  "timeout_seconds": 60
}

Only command is required. The optional timeout has a configured upper bound. There are no tool arguments for a sandbox ID, mount path, credential, resource grant, or execution host.

Those choices belong to trusted code. A model-supplied working directory or resource identifier cannot grant access to another workspace or cluster.

Replace the shell tool at registration

We investigated routing built-in shell commands through pre-execution hooks. The happy path worked, but a local probe showed that some hook failures allowed the original command to execute. Successful rewriting did not establish reliable enforcement when the hook crashed or timed out.

We therefore disable the provider's local shell tools and register a managed Bash replacement. One provider adapter exposes it through an SDK-managed MCP tool; the other registers a dynamic tool. Both feed the same trusted execution path.

If sandbox execution is unavailable, the tool returns a failure. It has no local-shell fallback.

Keep execution authority outside the tool call

A call follows this sequence:

  1. The provider adapter validates the command and timeout.
  2. The trusted supervisor binds the request to the active session and turn.
  3. The backend checks current ownership, workspace, resource grants, and runtime generation.
  4. The manager obtains or prepares the session sandbox and rechecks authority.
  5. The runtime executes the command at the recorded worktree path.
  6. Bounded output, execution status, and exit code return to the waiting tool call.

Commands are serialized per session. Each has its own execution record even though several commands reuse one sandbox. A result must match the waiting request and its ownership generation, preventing an old worker's response from being delivered into a newer execution.

The tool should report a nonzero exit, a timeout, or an uncertain outcome accurately. A missing response cannot safely be treated as permission to run an infrastructure mutation again.

5. Providing access to infrastructure resources

The sandbox starts with the resource grants selected for the workflow. The agent can then use familiar command-line tools without discovering connector IDs or assembling authentication configuration.

In our implemented infrastructure path, connected Kubernetes resources are exposed through Rancher integration. Resource grants and connector permissions determine the available access. Cloud-provider login flows for tools such as Azure CLI, gcloud, and Terraform remain separate unfinished work.

Credentials and command-line configuration are provisioned outside the shared worktree. The agent does not receive the daemon's installation credential or the sandbox manager's control credential. Any delegated application API credential has a short lifetime and is bound to the live runtime, with authority rechecked on use.

When grants change, the system retires the existing sandbox and prepares a replacement with the new authority snapshot. This avoids silently broadening credentials inside an already running environment. Revocation also needs to stop existing execution; blocking future calls alone leaves active processes untouched.

For our investigation example, read access supports cluster inspection. Preparing a local manifest patch remains distinct from receiving permission to apply it.

Network reachability is a separate consideration. Our current sandbox configuration permits general outbound connectivity while blocking runtime management listeners. It does not provide a general destination allowlist. Resource permissions and filesystem/process isolation must be described according to the boundaries they actually enforce.

6. Handling timeouts, cancellation, and sandbox cleanup

We reuse one sandbox per session to avoid provisioning a workload for every command. However, each call starts a fresh Bash process at the recorded working directory.

Files persist between calls while the sandbox lives. Shell variables and cd do not. Commands that need a subdirectory must express that within the call. Interactive stdin and persistent background sessions are unsupported.

Idle eviction removes runtime-local state while keeping the mounted worktree. Returning to the deployment investigation can therefore mean provisioning a fresh runtime, restoring its authorized configuration, and inspecting the existing patch.

Shell exit is not complete process cleanup

A shell can launch a detached child and exit successfully while that child continues writing files. Releasing the workspace at that point allows old work to overlap with the next command.

Our runtime executes each command inside a fresh unprivileged user/PID namespace. A protected process acts as namespace PID 1. When the command finishes or times out, that process exits, and the kernel terminates the remaining namespace processes.

An outer helper waits for this boundary and writes a completion receipt containing a per-invocation nonce. The command cannot write that receipt. The manager requires both execution status and the trusted receipt before completing the command and reusing the sandbox. Missing evidence stops the workload.

Commands are also prevented from connecting to the runtime's execution and egress management listeners. Otherwise, they could try to launch work outside their own invocation boundary.

Cancellation needs evidence

Cancelling an executing command stops the retained sandbox. Before releasing its workspace, the manager requires container termination evidence for the recorded Pod identity.

An accepted deletion request, an expired lease, or a missing Pod is insufficient. If cleanup cannot be established, the runtime stays uncertain and the workspace remains reserved.

The same caution applies after a lost response. A cluster API may have accepted a change before the connection failed. Recovery should inspect command history and external state before submitting another operation. Workspace cleanup cannot undo an external infrastructure mutation.

7. Design tradeoffs and lessons learned

The design keeps several boundaries explicit:

  • Workspace lifetime and runtime lifetime differ. Persistent work survives an idle eviction or runtime replacement.
  • Mounts define part of the execution contract. Exact paths, necessary Git metadata, and protected configuration determine both usability and isolation.
  • The Bash interface stays small. Trusted services own resource selection, mounts, credentials, and execution identity.
  • Completion includes descendants. A successful shell exit needs additional process-boundary evidence before another command can safely proceed.
  • Recovery preserves uncertainty. A request that may have changed infrastructure requires reconciliation before retry.

These choices have costs. Shared Git metadata needs careful protection. Strong process isolation introduces host-kernel requirements and compatibility limits. A fresh shell cannot support every interactive workflow, and stopping a sandbox cannot roll back changes already accepted by a remote service.

For the agent, the workflow remains straightforward: inspect the selected cluster, edit the manifest, validate the patch, and retain the evidence. Underneath that interaction, the system tracks which workspace, resource authority, and processes belong to each operation—and when it is safe to let the next operation begin.