Environment variables
Set encrypted environment variables on a sandbox at spawn or at runtime — available to every process you start in it.
Sandboxes can carry environment variables: API keys, config flags, connection
strings. qbox stores them encrypted at rest (AES-256-GCM) and pushes them
into the running sandbox, so any process you start afterward — commands.run,
run_code, an SSH shell — inherits them.
Where envs come from
The set a process sees is the merge of two layers, sandbox winning on a tie:
| Source | Set on | Notes |
|---|---|---|
template | the template | inherited by every sandbox built from it |
user | the sandbox | what you set via the SDK/CLI/API/dashboard |
volume | derived | QBOX_VOLUME_<name>_*, added automatically when you attach a volume |
list annotates each variable with its source.
At spawn time
import qbox
sandbox = qbox.Sandbox.create(
"python-3.12",
envs={"OPENAI_API_KEY": "sk-...", "LOG_LEVEL": "debug"},
)
At runtime
sandbox.envs.set({"OPENAI_API_KEY": "sk-new"}) # upsert
sandbox.envs.delete(["OLD_KEY"]) # remove some
sandbox.envs.clear() # remove all *user* envs
sandbox.envs.set_all({"A": "1"}) # replace all user envs
sandbox.envs.get("OPENAI_API_KEY") # -> "sk-new" | None
sandbox.envs.get_all() # -> {"OPENAI_API_KEY": ..., ...}
sandbox.envs.list(mask=True) # values elided for logging
sandbox.envs.upload_dotenv("./.env") # bulk-load a .env file
New processes pick up changes immediately; already-running processes keep the environment they started with.
Rules
- Keys match
[A-Z_][A-Z0-9_]*(uppercase, digits, underscore; can’t start with a digit). - The
QBOX_prefix is reserved (qbox uses it for volume-derived vars). - Up to 64 KB per value, 256 KB per sandbox total.
Violations return 422 with a code like env_key_invalid, env_key_reserved,
or env_value_too_large.
CLI
qbox sandboxes envs set sb_123 OPENAI_API_KEY=sk-... LOG_LEVEL=debug
qbox sandboxes envs list sb_123 # masked by default
qbox sandboxes envs list sb_123 --reveal # show values
qbox sandboxes envs delete sb_123 OLD_KEY
qbox sandboxes envs upload sb_123 ./.env
qbox sandboxes create python-3.12 --env OPENAI_API_KEY=sk-... --env LOG_LEVEL=debug
HTTP
| Method | Path | Notes |
|---|---|---|
GET | /v1/sandboxes/{id}/envs | ?mask=true to elide values; returns a version (ETag) |
PATCH | /v1/sandboxes/{id}/envs | upsert { "envs": {…} } |
PUT | /v1/sandboxes/{id}/envs | replace all user envs |
DELETE | /v1/sandboxes/{id}/envs | { "keys": [...] } |
POST | /v1/sandboxes/{id}/envs/upload | raw .env body |
Writes accept an If-Match: <version> header for optimistic concurrency
(412 version_mismatch if it changed since you read it). API keys need the
sandboxes:envs scope to read or write envs.
Security
Values are encrypted with the server’s master key (QBOX_ENV_MASTER_KEY) and
the ciphertext is bound to its row, so it can’t be moved between sandboxes. The
audit log records key names and lengths — never values. The list API can mask
values; the dashboard hides them behind a reveal toggle.