Environments

Portable access to files, commands, processes, and ports in local, container, cloud, and remote targets.

An Environment gives portable access to files, commands, processes, retained output, and ports. Use it directly in automation, or supply a fresh adapter to Harness so an Agent can work in a selected workspace, sandbox, container, VM, or remote execution target. It requires no Agent, model credential, or hosted service.

Environment Providers ship in a13n-harness; only vendor SDKs live behind extras. You do not need an Environment for an Agent that only calls ordinary application tools or remote APIs.

Start here

TaskGuide
Read and write a file with no network dependenciesGetting started
Choose local, sandbox, container, or remote executionChoose a backend
Understand close, state, re-entry, and destructionLifecycle and state
Configure built-ins, credentials, and runtime collaboratorsProvider configuration
Compare the six cloud providersCloud providers
Implement a Provider or supply Host runtimesProviders and runtime
Run commands, inspect processes, and read retained outputCommands and processes
Understand paths, search patterns, and output limitsOperations
Run a complete built-in lifecycleRunnable examples
Connect HTTP or reverse WebSocket EnvdRemote Envd
Expose Environment tools to an AgentHarness integration

Three concepts

  • Provider definition: validates account inputs, credentials, and the target recipe, then constructs adapters without target I/O.
  • Environment: one single-use adapter that prepares a target, exposes operations, and closes local resources.
  • EnvironmentState: portable Provider-owned target evidence, supplied to a later fresh adapter.

close() is non-destructive; explicit destroy() is a separate Host decision. Some Providers, including Direct Local, have no portable target state and own no target destruction. A root directory, target ID, or successful connection is not proof of isolation.

Choose a backend

Use no Environment when the Agent needs only ordinary tools or remote APIs. Otherwise select a Native or Envd route:

RouteProviderUse it forOperation and ownership boundary
Nativedirect_localTrusted local automationHost OS operations; existing directory, no sandbox claim
Nativee2bNative managed cloud sandboxE2B SDK; sandbox create/pause/resume/renew/destroy
NativedaytonaCloud sandboxNative stop/start and preserved files
NativemodalCloud sandboxSnapshot-backed stop/resume; fixed running lifetime
NativevercelCloud sandboxNamed persistent sandbox with native sessions
NativespritesCloud sandboxPersistent disk and automatic sleep/wake
NativerunloopCloud sandboxDevbox suspend/resume and idle keepalive
Envdlocal_envdCLI and local AgentsPrivate stdio daemon; close preserves workspace
NativedockerSingle-host servicesDocker Engine lifecycle and exec; close preserves container
Envdhttp_envdNetwork-reachable external environmentsHTTP(S) EIP; connect-only
Envdwebsocket_envdEnvironments that connect back to a HostReverse WebSocket EIP; Host-integrated SDK, connect-only

Try the remote examples locally without a model, Docker or cloud account.

How the layers fit

  • Host selects a trusted Provider, desired configuration, current state, runtime collaborators, retention policy, and authorization.
  • Environment Provider definition validates account inputs, credentials, and the target recipe, then constructs fresh single-use adapters; it acquires a live collaborator only in its runtime factory.
  • Environment enters or creates one exact target, exposes typed operations, caches the latest state, closes process-local resources, and supports explicit Host destruction.
  • Agent Harness owns Run-local mount names, access ceilings, routing, state aggregation, and non-destructive cleanup.
  • EIP is the typed operation protocol used by a13n-envd and remote backends.

EnvironmentState and HarnessState are different records. The former is a Provider-owned soft reference to a target; the latter is Agent continuation state. Neither restores current credentials or authorization.

Build an Environment-aware Agent

Binding an Environment supplies runtime authority but does not automatically expose operations to the model. Add the dynamic Environment Capability; it derives model-visible tools from each mount's effective access and Provider capabilities:

from a13n_harness import AgentSpec, HarnessBuilder
from a13n_harness.environment import (
    DynamicEnvironmentCapability,
    DynamicEnvironmentConfiguration,
)

executable = HarnessBuilder().build(
    AgentSpec(model="openai-responses:gpt-5"),
    output_type=str,
    capabilities=(
        DynamicEnvironmentCapability(DynamicEnvironmentConfiguration()),
    ),
)

Configure the selected model provider before running the examples, or replace the model with a deterministic FunctionModel in tests.

Start with Direct Local

Direct Local exposes an existing directory selected by the Host:

from pathlib import Path

from a13n_harness.providers.environment.builtins import select_builtin_environment_providers

(direct_local,) = select_builtin_environment_providers(("direct_local",))
environment = await direct_local.create(
    {"root": {"path": str(Path("./workspace").resolve())}},
    environment_id="workspace",
)

result = await executable.run(
    "Inspect the workspace",
    environment=environment,
)

The Provider inspects the directory during preparation, not scope entry. Harness closes the adapter after the Run but never destroys a target. Direct Local preserves the directory on close and rejects target destruction.

Direct Local restrictions apply through the current Environment mount. They do not isolate an allowed child process from the Host user account.

Use Local Envd

The Host owns a shared Local Envd runtime and its lazily launched Device. Each fresh adapter opens an independent Session with a fixed Device working directory:

from a13n_harness.providers.environment.builtins import select_builtin_environment_providers
from a13n_harness.providers.environment.local_envd.runtime import (
    LocalEnvdProviderRuntime,
    TemporaryLocalEnvdRuntimeAllocator,
    resolve_a13n_envd_executable,
)

(local_envd,) = select_builtin_environment_providers(("local_envd",))
async with LocalEnvdProviderRuntime(
    executable=resolve_a13n_envd_executable(),
    allocate_private_runtime=TemporaryLocalEnvdRuntimeAllocator(),
) as runtime:
    environment = await local_envd.create(
        {"working_directory": "/absolute/path/to/workspace"},
        environment_id="workspace",
        runtime=runtime,
    )
    result = await executable.run(
        "Inspect the working directory",
        environment=environment,
    )
    # Harness closes this adapter's Session. The Host can use another adapter
    # on the same runtime; leaving this context closes the shared Device.

Executable resolution checks an explicit argument, A13N_ENVD_EXECUTABLE, then a13n-envd on PATH. The client and Provider packages do not install or download the native binary.

Local Envd validates exact daemon/client compatibility and never falls back to Direct Local. Envd paths address the Device filesystem; a fixed cwd is not containment. Host-managed accounts, containers, or sandboxes own filesystem and network isolation. Read the a13n-envd guide for setup and security boundaries.

Re-enter and retain a target

A stateful Provider such as Docker returns EnvironmentState. The Host persists the latest state and supplies it when constructing the next fresh adapter:

current_state = await state_store.load(environment_key)
environment = await docker.create(
    recipe,
    configuration={"docker_host": "unix:///var/run/docker.sock"},
    environment_id="workspace",
    state=current_state,
)

try:
    result = await executable.run(
        "Continue the task",
        environment=environment,
        previous_state=previous_harness_state,
    )
finally:
    await state_store.publish(environment_key, environment.dump_state())

dump_state() is a synchronous detached read of the adapter's latest validated cache. The Host can call it after entry failure, cancellation, Run failure, or close failure without causing more provider I/O.

Close and destruction are deliberately separate:

OperationOwnerEffect
Enter and Run-local useHarnessEnters one fresh adapter and mounts its operations
close()HarnessReleases process-local resources without removing the target
State persistenceHostSelects and stores the latest authoritative EnvironmentState
Fresh-adapter destroy()HostRemoves the exact Provider-owned target and bootstrap material when retention selects it

A suspended or failed Run still closes its adapter non-destructively. Harness never infers temporary ownership and never calls destroy().

Use several Environments

Pass multiple fresh adapters with explicit Run-local policy:

from a13n_harness import EnvironmentMount
from a13n_harness.environment import FILE_READ_ACTIONS, EnvironmentPermissionSet

result = await executable.run(
    "Read the source data and write the build output",
    environments={
        "build": build_environment,
        "data": EnvironmentMount(
            data_environment,
            permission_ceiling=EnvironmentPermissionSet(operations=FILE_READ_ACTIONS),
        ),
    },
    default_environment="build",
)

The default mount is available at /workspace; named mounts are available at /environment/{name}. When several entries are present, select default_environment explicitly or leave /workspace unbound. Mapping order never grants authority.

Harness validates the complete mount set before entry. If one adapter fails, it closes every supplied adapter that may own process-local resources and publishes no partial mount set. It never destroys a target during unwind.

Select only required operations

EnvironmentMount narrows Provider capability with an exact permission_ceiling; FILE_READ_ACTIONS and FILE_ACTIONS are the shared action sets. DynamicEnvironmentConfiguration controls which stable Environment Toolsets the model can see. Keep shell, background-process, retained-output, and port operations absent unless the Agent definition requires them.

The Harness Environment guide covers complete Capability configuration, deterministic routing, state export, portable process references, and advanced Host runtimes.

Next steps

Hosted preparation and recovery

The Service builds on these providers: it creates managed Docker and cloud sandbox environments from templates, connects to external envd targets by endpoint and token, and freezes each run's mounts; see Service environments. The embedded Provider lifecycle described above remains usable independently.

For direct SDK integrations, use Environment lifecycle and errors and remote Envd.

On this page