Pass secrets into a sandbox
Read secrets from the host and inject them into a sandbox at runtime.
Pass secrets from the host environment into a sandbox at runtime, and keep image metadata for non-sensitive configuration.
Set the Cua API key#
The Cua API key is read from CUA_API_KEY environment variable. You can also pass it explicitly:
async with Sandbox.ephemeral(Image.linux(), api_key=my_key) as sb:
...Inject secrets at runtime#
Read secrets from the host environment, then inject them into the sandbox with sb.shell.run.
import os
import asyncio
from cua import Sandbox, Image
async def main():
db_url = os.environ['DATABASE_URL']
gh_token = os.environ['GITHUB_TOKEN']
async with Sandbox.ephemeral(Image.linux()) as sb:
await sb.shell.run(f"export DATABASE_URL='{db_url}'")
await sb.shell.run(f"export GITHUB_TOKEN='{gh_token}'")
await sb.shell.run('python /app/main.py')
asyncio.run(main())For multi-command sessions, use a wrapper script:
script = f"""
export DATABASE_URL='{db_url}'
export GITHUB_TOKEN='{gh_token}'
python /app/main.py
"""
result = await sb.shell.run(script)Non-sensitive config with Image.env()#
Use Image.env() for non-sensitive config, not for secrets.
img = (
Image.linux()
.apt_install('python3')
.env(
LOG_LEVEL='info',
APP_ENV='production',
PORT='8080',
)
).env() values are stored in the Image spec and visible to anyone who can inspect it. Do not use .env() for API keys, passwords, or tokens.
Copy secret files into the sandbox#
Copy SSH keys, certificates, and other secret files into the sandbox at runtime, then set file permissions.
async with Sandbox.ephemeral(Image.linux()) as sb:
with open(os.path.expanduser('~/.ssh/id_rsa')) as f:
key_content = f.read()
await sb.shell.run('mkdir -p /root/.ssh && chmod 700 /root/.ssh')
await sb.shell.run(f"cat > /root/.ssh/id_rsa << 'EOF'\n{key_content}\nEOF")
await sb.shell.run('chmod 600 /root/.ssh/id_rsa')For files safe to bake in, use Image.copy():
img = Image.linux().copy('./app-config.json', '/app/config.json')Best practices#
| Do | Don't |
|---|---|
| Read secrets from host environment variables | Hardcode secrets in Python source |
| Inject secrets at runtime via sb.shell.run | Store secrets in Image.env() |
| Use .env files + python-dotenv locally | Commit .env files to version control |
| Use your CI/CD provider's secret manager | Log or print secret values |