Pass secrets into a sandbox
Pass credentials from the host into a local or cloud sandbox at runtime, and keep them out of images.
Pass credentials from the host into a local or cloud sandbox at runtime, and keep them out of images.
Read secrets on the host and hand them to one process in the sandbox at
runtime. Never put them in an image spec. The examples take a connected Linux
sandbox sb with an application at /app/main.py; they work locally and in
the cloud.
| Value | Where it goes |
|---|---|
| API keys, tokens, passwords | The process environment at runtime (below) |
| Key files | A temporary file that is removed when the process exits (below) |
| Registry credentials | A RegistrySecret, never logged or saved |
| Non-sensitive settings | Image.env(), env= on Sandbox.create, Container(env=...) |
| A per-claim token on a Fleet pool | Claim secrets |
Set DATABASE_URL and GITHUB_TOKEN on the host from your secret manager,
then call await run_with_secrets(sb):
import os
import shlex
from cua_sandbox import Sandbox
async def run_with_secrets(sb: Sandbox):
db_url = os.environ['DATABASE_URL']
gh_token = os.environ['GITHUB_TOKEN']
command = (
f'DATABASE_URL={shlex.quote(db_url)} '
f'GITHUB_TOKEN={shlex.quote(gh_token)} '
'python3 /app/main.py'
)
result = await sb.shell.run(command)
if not result.success:
raise RuntimeError('Application failed; inspect sanitized diagnostics')Keep the assignments and the application in one shell.run() call: an
export does not persist into the next call. shlex.quote() keeps spaces,
quotes and newlines literal.
For an application that reads a key file, point TASK_SSH_KEY_FILE at the
host file (mode 600), then call await run_with_key_file(sb):
import os
from pathlib import Path
import shlex
from cua_sandbox import Sandbox
async def run_with_key_file(sb: Sandbox):
key_content = Path(os.environ['TASK_SSH_KEY_FILE']).read_bytes().decode('utf-8')
script = f"""
set -eu
umask 077
secret_dir=$(mktemp -d /tmp/cua-task-secret.XXXXXXXXXX)
trap 'rm -f "$secret_dir/task-key"; rmdir "$secret_dir"' EXIT
trap 'exit 1' HUP INT TERM
printf '%s' {shlex.quote(key_content)} > "$secret_dir/task-key"
chmod 600 "$secret_dir/task-key"
TASK_SSH_KEY_FILE="$secret_dir/task-key" python3 /app/main.py
"""
result = await sb.shell.run(script)
if not result.success:
raise RuntimeError('Credential task failed; inspect sanitized diagnostics')The file lives in a private directory and is removed when the application exits, including on failure. A killed shell or a lost connection can skip the cleanup: destroy the sandbox then.
These commands contain the secret values. Quoting does not redact logs,
traces or process listings: do not print the command, do not enable
set -x, use short-lived credentials, and revoke them when the task ends.