Skip to main content

k8s-agent-sandbox-awx

A broker-backed, kubeconfig-free overlay for the Agentic Sandbox client. It adds a BrokerSandboxClient that drives the sandbox control plane (create → wait ready → terminate, commands, and files) through one identity broker service over HTTPS instead of the Kubernetes API or a public router. The broker proxies authorized data operations to its internal router, so client applications need no kubeconfig and no direct Kubernetes or router access.

pip install k8s-agent-sandbox-awx==0.6.0
from k8s_agent_sandbox_awx import Sandbox

sandbox = Sandbox.create(keepalive_ttl_seconds=0)
result = sandbox.commands.run('echo "Hello from Agent Sandbox!"')
print(result.stdout)
# Leave it available until its timeout; call sandbox.kill() for early cleanup.

Streaming and background commands

SDK 0.6.0 adds managed commands on Python runtime v0.3.0 and Codex runtime v0.2.0, through broker v0.11.0. Create a new sandbox after the runtime upgrade; existing claimed sandboxes are not replaced. Plain run() calls fall back to the old execution endpoint on older runtimes, but the new options require the updated runtime and broker.

Stream stdout and stderr while the command runs:

result = sandbox.commands.run(
    ["python3", "-u", "-c", "import os,time; print(os.getenv('DEMO')); time.sleep(1); print('done')"],
    timeout=30,
    envs={"DEMO": "hello"},
    cwd="/app",
    on_stdout=lambda chunk: print(chunk, end="", flush=True),
    on_stderr=lambda chunk: print(chunk, end="", flush=True),
)
print(result.exit_code)

Callbacks receive text chunks, not necessarily complete lines. Use unbuffered output (python3 -u or flush=True) in the program when you need prompt output. The result still contains the collected stdout, stderr, and exit code.

Start a background command, wait later, or cancel its process group:

task = sandbox.commands.run(["sleep", "60"], background=True, timeout=120)
print(task.command_id)
print(task.status()["state"])

# Reattach to a known command using the same sandbox/caller:
task = sandbox.commands.get(task.command_id)
# result = task.wait(timeout=10, on_stdout=print)  # wait timeout does NOT kill it
result = task.kill()  # cancel this command, not the sandbox; safe to repeat
print(result.state)   # cancelled

Optional stdin is available only for background commands:

task = sandbox.commands.run(["cat"], background=True, stdin=True)
task.send_stdin("hello\n", eof=True)
print(task.wait().stdout)

timeout limits command execution (default 60 seconds), capped by the runtime's SANDBOX_EXEC_TIMEOUT_SECONDS (default 300 seconds). task.wait(timeout=...) only limits waiting; call kill() to cancel. Sandbox expiry still kills all work; background commands do not extend its lifetime automatically. Cancellation kills the process group, including normal descendants; it is not a separate security boundary against processes deliberately escaping their group.

Environment overrides are per-command. cwd is an absolute path inside the sandbox; choose the template's PVC path for durable outputs. String commands still use shlex without an implicit shell; pass an argv list or explicitly use ["sh", "-c", "..."] for shell syntax.

The runtime retains up to 1 MiB of combined output per command and reports output_truncated=True when it reaches the byte/event limit. It drains further output to avoid blocking the process. It allows 16 running managed commands and retains at most 64 handles. Results expire after 15 minutes, or earlier under retention pressure. These are runtime safeguards, not per-caller sandbox quotas. Handles/results are in-memory and do not survive runtime restart or sandbox deletion. They are not part of the PostgreSQL audit store.

Output streams reconnect with a cursor every 20 seconds through the broker, refreshing the caller token and rechecking ownership and sandbox.exec policy. Disconnecting does not cancel background commands. Do not concurrently call wait() on the same handle. A fresh handle replays its retained output.

How it works

The client presents an audience-bound Kubernetes or GitLab OIDC token to the broker. The broker cryptographically verifies the caller from that token, creates the SandboxClaim under its own identity, and stamps the verified caller identity onto the claim — attribution the client cannot forge.

Set both broker_url and api_url to the broker URL. The model rejects a different api_url to prevent accidental direct-router bypass.

This package is a purely additive overlay: it builds on k8s-agent-sandbox-base (a seamed re-publish of the upstream client) and edits zero upstream files. The import package is k8s_agent_sandbox_awx.

Configuration

The zero-argument API reads:

Variable Purpose
AGENT_SANDBOX_BROKER_URL Public HTTPS broker endpoint
AGENT_SANDBOX_TOKEN_PATH Rotating Kubernetes projected-token file
AGENT_SANDBOX_TOKEN GitLab or other OIDC ID token
AGENT_SANDBOX_WARMPOOL Approved warm pool; defaults to python-sandbox-warmpool
AGENT_SANDBOX_NAMESPACE Broker-owned claim namespace; defaults to agent-sandbox
AGENT_SANDBOX_TTL_SECONDS Sandbox timeout in seconds; defaults to 300
AGENT_SANDBOX_KEEPALIVE_TTL_SECONDS Opt-in activity timeout reset; defaults to 0 (disabled)

Timeouts

Sandbox.create() defaults to 300 seconds (five minutes). An explicit shutdown_after_seconds overrides AGENT_SANDBOX_TTL_SECONDS (or legacy SANDBOX_TTL_SECONDS), which overrides that default. Values must be positive. Commands do not reset the deadline unless keepalive is explicitly enabled. sandbox.set_timeout(600) resets it to ten minutes from the call and can shorten or extend it. The broker enforces its hard lifetime from the original claim creation time (24 hours in US nonprod); extensions cannot reset that cap, and caller policy may impose a shorter per-request maximum.

Plain assignment leaves the sandbox running after the script exits. with Sandbox.create() as sandbox: and sandbox.kill() intentionally delete it immediately. Job ttlSecondsAfterFinished cleans the caller Job/Pod, not the sandbox. A replacement caller Pod cannot take ownership of the previous Pod's claim merely by using the same ServiceAccount.

These defaults apply to SDK 0.5.2. When using older 0.5.0, the broker supplies the five-minute default, but pass keepalive_ttl_seconds=0 explicitly for fixed-deadline behavior.

Kubernetes normally needs no Python authentication code:

from k8s_agent_sandbox_awx import Sandbox

with Sandbox.create() as sandbox:
    print(sandbox.commands.run("python3 -c 'print(6 * 7)'").stdout)

Mount a projected ServiceAccount token at the configured path with its audience set to the broker URL. The file is re-read on every request so token rotation is honored.

Cleanup activity

If sandbox creation or readiness fails, upstream attempts a cleanup delete. The broker overlay marks that delete with request_purpose: create_cleanup; normal explicit deletes are not marked. This is diagnostic client intent only and never bypasses admission, action-policy or ownership checks. Broker v0.10.2 and the console can distinguish create, delete and SDK-reported cleanup even when caller admission fails. Older records cannot be retroactively labeled. SDK 0.5.2 includes this cleanup attribution; older 0.5.0 does not.

GitLab supplies the same zero-argument API using a native ID token:

job:
  id_tokens:
    AGENT_SANDBOX_TOKEN:
      aud: https://sandbox-broker.example
  variables:
    AGENT_SANDBOX_BROKER_URL: https://sandbox-broker.example
  script:
    - python app.py

Explicit authentication objects are available when environment discovery is not appropriate:

from k8s_agent_sandbox_awx import KubernetesAuth, OIDCTokenAuth, Sandbox

k8s = Sandbox.create(auth=KubernetesAuth("/var/run/secrets/tokens/broker"))
ci = Sandbox.create(auth=OIDCTokenAuth.from_env("MY_ID_TOKEN"))

The SDK deliberately has no provider="gitlab" or provider="kubernetes" switch. It transports the token; the broker derives the provider from the verified issuer and applies the matching policy.

Requirements

  • A deployed identity broker service reachable over HTTPS.
  • An OIDC token whose audience matches the broker's. Kubernetes projected tokens and GitLab id_tokens: are supported by the broker policy.
  • k8s-agent-sandbox-base (installed automatically as a dependency).

License

Apache-2.0 — see LICENSE.

Metadata

Release files for k8s-agent-sandbox-awx 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for k8s-agent-sandbox-awx 0.6.0
File Size Uploaded
k8s_agent_sandbox_awx-0.6.0.tar.gz 36.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for k8s-agent-sandbox-awx 0.6.0
File Interpreter ABI Platform
k8s_agent_sandbox_awx-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 64.6 kB

Release files / k8s_agent_sandbox_awx-0.6.0.tar.gz

Download URL k8s_agent_sandbox_awx-0.6.0.tar.gz
Size 36.6 kB
Tags Source
SHA-256 checksum
How to use checksums
586fc4ad07ad3b8ee6dd26e6e6b202d81a6de7c775fcbb267163eeb0530fc23d
BLAKE2b-256 checksum
How to use checksums
2aac515e30b174965de656c8e2e9eade1f9ba83236cbab2483a862de8f13fac7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.11

Release files / k8s_agent_sandbox_awx-0.6.0-py3-none-any.whl

Download URL k8s_agent_sandbox_awx-0.6.0-py3-none-any.whl
Size 28.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
881f2e99f569efac65d9f3da647c97bae02aa966323519f447ebd39ac952431c
BLAKE2b-256 checksum
How to use checksums
7b6266b4b0d5ddbdb6f5f5eb780f67668e51343bac3a36e2e6115ef61a677bff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.11

Release history Release notifications | RSS feed

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

This release

0.6.0 This release

2 release files

0.5.2

2 release files

0.5.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page