The CLI
caas is the caas.sh command line. Use it to run commands in new sandboxes, manage sandboxes and their snapshots, deploy MCP servers, push images, start workflows, connect credentials and manage billing from a terminal or a script. It calls the same API as the console, with an API key from your workspace.
Install the CLI
The CLI needs Node 22 or later. Install the @caascade/cli package globally:
npm i -g @caascade/cliThe package isn't on npm yet. Once it's published, this command installs it.
This installs the caas command. To list every command and option, run caas help, or caas on its own. Adding --help to any command does the same.
Some commands use other tools: caas registry login runs Docker, and --from uses Git.
Connect the CLI to your workspace
The CLI doesn't sign in with your email and password. It uses an API key, which belongs to one workspace, together with that workspace's tenant ID.
Create an API key
Sign in to the console and open Settings.
Under Workspace, copy the Tenant ID.
Under API keys, enter a Key name, such as
my laptop. If you're an owner and want to usecaas billing, check Billing access.Choose Create key, then copy the key. It starts with
ck_, and the console shows it only once.
Owners and operators can create keys. Viewers can't.
Configure the CLI
Save the tenant ID and key:
caas configure --tenant <tenant-id> --key <api-key>The CLI saves them in ~/.config/caas/config.json, or in $XDG_CONFIG_HOME/caas/config.json if XDG_CONFIG_HOME is set. Only you can read the file. Every later command uses what you saved. To check that everything works, list your sandboxes:
caas sandboxes listRunning caas configure again replaces the saved tenant ID and key.
What a key can do
A new key can:
list, create, start, stop and delete sandboxes, and run commands in them
deploy MCP servers and manage their client tokens
push and pull images in the registry
start and control workflow runs
read credentials, egress rules and the audit log
A key with Billing access can also read the balance and usage and add funds (caas billing).
A key can never do more than the member who created it. An operator's key can't use caas billing, and only an owner's key can connect or remove credentials or apps, or change egress rules. If the member who created a key leaves the workspace, the key stops working. To revoke a key, choose Revoke next to it under Settings → API keys.
Choose a workspace
The CLI always works in one workspace: the one whose tenant ID you pass, with a key created in that workspace. A key from one workspace doesn't work in another.
To work in another workspace:
In the console, open the workspace card at the top of the sidebar and switch to that workspace.
Create an API key there, as in Create an API key, and copy that workspace's tenant ID.
Either save the new pair, which replaces the one you saved before:
shellcaas configure --tenant <other-tenant-id> --key <other-api-key>Or pass the pair to a single command and keep what you saved:
shellcaas sandboxes list --tenant <other-tenant-id> --key <other-api-key>
Options for every command
| Option | What it does |
|---|---|
--tenant ID | Use this workspace instead of the saved one. Pass --key with it. |
--key KEY | Use this API key instead of the saved one. |
--api-url URL | Use another API address. The default is https://api.caas.sh. It must use https://, except on localhost. caas configure saves it. |
--json | Print the API's JSON response instead of the text output. |
--help | Print every command and option. |
caas run, caas mcp deploy, caas sandboxes exec, caas workflows run and caas billing add-funds send their request with an idempotency key. If the CLI can't reach the API, the error names the key. Run the same command again with --idempotency-key KEY to retry without creating a second sandbox, command, run or payment.
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | The request or the command failed. |
2 | The command line isn't valid, for example an unknown option, a missing value or a value out of range. Nothing was changed. |
3 | The API or the registry refused the key: it's revoked, from another workspace, or lacks the access the command needs. |
caas run and caas sandboxes exec exit with the command's own exit code when it's between 1 and 125, and with 1 for any other failure. Errors are printed to standard error as caas: <message>. When the workspace is out of funds, the error also links to the console page where an owner adds them.
Sizes
--size sets a sandbox's vCPU, memory and disk. The default is m.
| Size | --size | vCPU | Memory | Disk |
|---|---|---|---|---|
| XS | xs | 1/16 | 256 MiB | 2 GB |
| S | s | 1/4 | 1 GiB | 4 GB |
| M | m | 1/2 | 4 GiB | 8 GB |
| L | l | 1 | 6 GiB | 12 GB |
| XL | xl | 2 | 8 GiB | 16 GB |
| 2XL | 2xl | 4 | 12 GiB | 20 GB |
| Custom | custom | 1 to 4 | At least 3 GiB per vCPU, at most 12 GiB | 2 to 20 GB |
For a custom size, add --vcpu N --memory GIB --disk GB, all whole numbers:
caas run --size custom --vcpu 2 --memory 6 --disk 12 -- node --versionA sandbox that runs your own image needs size M or larger. vCPU bills only while the sandbox computes; memory and disk bill while it runs. See pricing for the rates.
Run a command in a new sandbox
caas run creates a sandbox, runs one command in it, waits for the command to end, and prints its output:
caas run -- node --version
caas run --from . node task.js
caas run --name build-agent --size xl --from . node task.js
caas run --image worker:latest -- python task.py
caas run --from . --detach node long-task.js
caas run --ephemeral --egress-host api.example.com -- node --version
caas run --from . --expose 3000 -- node server.jsThe command runs as an executable with its arguments, not through a shell. To use shell features, run a shell:
caas run --from . -- sh -c 'node build.js && node test.js'Options can come anywhere before --, and everything after -- is the command. Put -- before a command whose arguments start with --.
Without --image, the sandbox uses the Default image: Alpine Linux with bash, coreutils, Node and Docker. It has no coding agents installed; install one in your command, or use your own image.
The command has a time limit of two hours, and runs once. When caas run is done, the sandbox keeps running until its idle stop. Delete it with caas sandboxes delete when you no longer need it.
| Option | What it does |
|---|---|
--from DIR | Upload your code into /workspace. See Upload your code. |
--image IMAGE | Run in your own image from the registry. See Push images to the registry. Can't be combined with --from. |
--name NAME | Name the sandbox: up to 63 lowercase letters, digits and hyphens, starting and ending with a letter or digit, unique in the workspace. |
--size SIZE | The sandbox's size. See Sizes. |
--egress-host HOST | Allow outbound requests to this exact host. Repeat it for each host, up to 32. Other hosts are blocked unless you change the sandbox's egress policy. A command that starts with npx also gets registry.npmjs.org. |
--expose PORT | Serve this port at the sandbox's own URL: 1024 to 65535, except 8788. See Sandbox URLs. |
--public | With --expose: let anyone with the link open the URL, without an access token. |
--idle-stop MINUTES | Stop the sandbox after this many minutes with no command, file transfer, MCP request or URL request: 5 to 240. The default is 15. |
--wake-on-request | Let a command, a file transfer, an MCP request or a URL request start the sandbox again after you stopped it yourself. A sandbox that stopped while idle starts again on a request either way. |
--ephemeral | Keep nothing between restarts: the sandbox starts fresh each time, and the sandbox takes no automatic or nightly snapshots. Can't be combined with --from. |
--detach | Return as soon as the sandbox is created, without waiting for the command. |
With --detach, the CLI prints the new sandbox and the ID of its first command, initial-agent-command. Check on the command later:
caas sandboxes command <sandbox-id> initial-agent-commandUpload your code
--from DIR uploads the committed Git tree of the repository at DIR, usually ., and unpacks it into /workspace when the sandbox first starts. You can use it with caas run and with caas mcp deploy --stdio.
DIRmust be the root of a Git repository with at least one commit.Commit your changes first. The CLI refuses a repository with uncommitted changes or untracked files. Files that Git ignores are never uploaded.
The CLI refuses to upload a repository that tracks a sensitive-looking file:
.envfiles,.dev.vars,.npmrc,id_rsa,credentials, or any.pemor.keyfile.The compressed upload can be at most 250 MiB.
A sandbox started from an upload keeps its state, so you can't combine
--fromwith--ephemeral. caas.sh keeps the upload for seven days; after that, your files live on in the sandbox's own snapshots.
Manage sandboxes
caas sandboxes commands take the sandbox's ID, not its name. caas sandboxes list shows both.
List and inspect
caas sandboxes list
caas sandboxes inspect <sandbox-id>
caas sandboxes events <sandbox-id>| Command | What it does |
|---|---|
caas sandboxes list | Lists every sandbox and MCP server that isn't deleted: its ID, name, kind (agent or mcp) and record state (active once it's created). inspect shows whether it's running. |
caas sandboxes inspect ID | Shows the sandbox's details: its status, settings, size, URL, and usage, including what it costs per hour now and what it has cost today. |
caas sandboxes events ID | Lists the sandbox's events, such as its starts and stops. |
Start, stop and delete
caas sandboxes stop <sandbox-id>
caas sandboxes start <sandbox-id>
caas sandboxes delete <sandbox-id>A sandbox that keeps state takes a snapshot as it stops, and starts again with its /workspace.
Run commands in a sandbox
caas sandboxes exec <sandbox-id> -- node --version
caas sandboxes exec <sandbox-id> -- sh -c 'cd /workspace && ls -la'
caas sandboxes exec <sandbox-id> --timeout-ms 1800000 --detach -- node long-task.js
caas sandboxes command <sandbox-id> <command-id>
caas sandboxes cancel-command <sandbox-id> <command-id>| Command | What it does |
|---|---|
caas sandboxes exec ID -- COMMAND [ARGS...] | Runs a command in the sandbox, waits for it, prints its output and exits with its exit code. |
caas sandboxes command ID COMMAND_ID | Shows a command's state, exit code and output. |
caas sandboxes cancel-command ID COMMAND_ID | Stops a running command. |
exec takes these options before --:
| Option | What it does |
|---|---|
--timeout-ms MS | The command's time limit in milliseconds: 1000 (1 second) to 7200000 (2 hours). The default is 600000 (10 minutes). |
--detach | Print the command's ID and return without waiting. |
As with caas run, the command runs without a shell. A command sent to a sandbox that stopped while idle starts it again.
Snapshots
A sandbox that keeps state takes a snapshot of /workspace every hour, when it stops, and every night, at 02:00 in the workspace's time zone unless you move it. You can also take your own.
caas sandboxes snapshot <sandbox-id> --name before-upgrade
caas sandboxes snapshots <sandbox-id>
caas sandboxes stop <sandbox-id>
caas sandboxes restore <sandbox-id> --snapshot <snapshot-id>
caas sandboxes delete-snapshot <sandbox-id> <snapshot-id>
caas sandboxes schedule <sandbox-id> --at 03:30 --time-zone Europe/Berlin
caas sandboxes schedule <sandbox-id> --off| Command | What it does |
|---|---|
caas sandboxes snapshot ID [--name NAME] | Takes a snapshot of a running sandbox. Without --name, it's named manual. Names follow the same rules as sandbox names. |
caas sandboxes snapshots ID | Lists the snapshots: ID, name, kind, when each was taken, its size and which one is current. Then the bytes stored and the nightly schedule. |
caas sandboxes restore ID --snapshot SNAPSHOT_ID | Restores a snapshot onto a stopped or failed sandbox and starts it. Stop the sandbox first. |
caas sandboxes delete-snapshot ID SNAPSHOT_ID | Deletes a snapshot. |
caas sandboxes schedule ID --at HH:MM [--time-zone ZONE] | Moves the nightly snapshot to this 24-hour time, in an IANA time zone such as Europe/Berlin. |
caas sandboxes schedule ID --off | Turns the nightly snapshot off. |
Snapshots you take stay until you delete them. caas.sh keeps the newest 7 nightly snapshots. See Sandboxes for how snapshots work.
Sandbox URLs
A sandbox can serve one HTTP port at its own address, https://<label>.caa.sh, where the label is an opaque name that reveals neither your workspace nor the sandbox's ID. The URL needs an access token unless you make it public.
caas sandboxes expose <sandbox-id> 8080
caas sandboxes url-token <sandbox-id> --ttl 600
caas sandboxes expose <sandbox-id> 8080 --public
caas sandboxes expose <sandbox-id> --off| Command | What it does |
|---|---|
caas sandboxes expose ID PORT [--public] | Serves PORT (1024 to 65535, except 8788) at the sandbox's URL, or changes the port. With --public, anyone with the link can open it. |
caas sandboxes expose ID --off | Turns the URL off and revokes every access token for it. |
caas sandboxes url-token ID [--ttl SECONDS] | Prints an access token for the URL, its expiry, and a curl command that uses it. --ttl is 60 to 86400 seconds; the default is 3600. |
Send the token as an Authorization: Bearer header. caas sandboxes inspect shows the URL. A request to the URL starts a sandbox that stopped while idle, and keeps it from stopping.
Logs and outbound requests
caas sandboxes logs <sandbox-id>
caas sandboxes log-archives <sandbox-id>
caas sandboxes log-archive <sandbox-id> <archive-id> > runtime.jsonl
caas sandboxes egress <sandbox-id>| Command | What it does |
|---|---|
caas sandboxes logs ID | Prints the sandbox's recent runtime log. |
caas sandboxes log-archives ID [--cursor ARCHIVE_ID] | Lists the log archives: each one's ID, time span, entries and size. Pass the printed Next cursor as --cursor for older ones. Archives are kept for 90 days. |
caas sandboxes log-archive ID ARCHIVE_ID | Prints one archive as JSON Lines. |
caas sandboxes egress ID [--cursor N] | Lists the outbound requests the sandbox tried to make, newest first. See below. |
Each line of caas sandboxes egress shows the time, method, host and path, whether the request was allowed or blocked, the rule that decided, the response status (- when the request failed), the bytes sent, and key added when a credential was added to it. Query strings, headers and bodies are never kept. caas.sh keeps the newest 1,000 allowed and 1,000 blocked requests for 7 days. Pass the printed Next cursor as --cursor for older ones.
Deploy MCP servers
caas mcp deploy puts an MCP server online at its own endpoint, https://mcp.caa.sh/<endpoint-id>. Choose exactly one source:
caas mcp deploy --stdio "npx -y @modelcontextprotocol/server-filesystem /workspace"
caas mcp deploy --stdio "node server.js" --from .
caas mcp deploy --repo github.com/acme/server --ref main --command "npm start"
caas mcp deploy --image server:1.2.3
caas mcp deploy --image server:1.2.3 --transport http --port 3000 --command "node http.js"| Option | What it does |
|---|---|
--stdio "COMMAND" | Runs a server that speaks MCP over standard input and output. Add --from DIR to upload your code first. |
--repo URL | Clones an HTTPS Git repository (https:// is added if you leave it out) and runs --command, which defaults to npm start. |
--ref REF | With --repo: the branch, tag or commit to deploy. |
--image IMAGE | Runs your own image from the registry. Without --command, the image's own entrypoint and command run. |
--command "COMMAND" | With --repo or --image: the command that starts the server. With --image, it replaces the image's entrypoint and command. |
--transport TRANSPORT | With --image: stdio (the default) or http. |
--port PORT | With --transport http: the port your server listens on, serving Streamable HTTP at /mcp. 1024 to 65535, except 8788. |
--stdio and --command take a quoted command line. The CLI splits it into words like a shell does, with quotes and backslashes, but doesn't run it through a shell. A command can have up to 32 words.
These options work as they do for caas run: --name, --size (with --vcpu, --memory and --disk), --egress-host, --expose, --public, --idle-stop, --wake-on-request and --ephemeral. A stdio server on your own image needs Node in the image. When a server from --repo or --from first starts and has a package.json, its production dependencies are installed.
The CLI prints the new server's details, including its endpoint (endpointUrl) and a first client token (clientToken) that can call every tool and doesn't expire. The token is shown only once. Clients send a token as an Authorization: Bearer header. A retry with the same --idempotency-key doesn't print the token again; create a new one with caas mcp tokens create.
Deploy from a file
caas mcp deploy -f FILE (or --file FILE) deploys a server declared in a YAML or JSON file, the same format the console's Deploy from a server file page takes (under MCP servers → Deploy server):
server: search-mcp
source:
stdio: npx search-mcp
size: s
state:
persistent: true
snapshots: nightly at 02:00
idle: stop after 30m
tokens:
- name: laptop-claude
tools: [search.query, search.fetch]
- name: ci-pipeline
tools: [search.query]
expires: 30d
egress: [api.search.example.com]caas mcp deploy -f search-mcp.yamlThe CLI checks the whole file before it uploads or creates anything, creates the server and its tokens in one request, and prints the endpoint and each token's tools, expiry and secret once. The file declares the whole server, so only --from (with a stdio source and persistent: true), --wake-on-request, --idempotency-key and --json can be combined with -f. See MCP servers for every field.
Client tokens
caas mcp tokens list <sandbox-id>
caas mcp tokens create <sandbox-id> --name "Claude Desktop"
caas mcp tokens create <sandbox-id> --name ci --expires-days 30 --allow-tool search.query
caas mcp tokens revoke <sandbox-id> <token-id>| Command | What it does |
|---|---|
caas mcp tokens list ID | Lists the server's client tokens: ID, name, whether each is active, revoked or expired, the tools it may call, and its calls and errors. |
caas mcp tokens create ID --name LABEL | Creates a token and prints its secret once. |
caas mcp tokens revoke ID TOKEN_ID | Revokes a token. The server keeps running. |
create takes these options:
| Option | What it does |
|---|---|
--name LABEL | Required. A label for the client that uses the token. |
--expires-days DAYS | When the token expires: 1 to 365 days. The default is 90. |
--allow-tool NAME | Let the token call only this tool. Repeat it for each tool. Without it, the token can call every tool. |
Push images to the registry
Your workspace has its own namespace in the caas.sh registry, registry.caas.sh/<tenant-id>/. Log Docker in with your saved key, then build and push a linux/amd64 image:
caas registry login
docker build --platform linux/amd64 -t registry.caas.sh/<tenant-id>/server:1.2.3 .
docker push registry.caas.sh/<tenant-id>/server:1.2.3
caas mcp deploy --image server:1.2.3caas registry login runs docker login registry.caas.sh, with your tenant ID as the username and your API key as the password. New keys can push and pull.
Wherever a command takes --image, you can write the image as NAME[:TAG] or NAME@sha256:DIGEST, optionally under registry.caas.sh/ or registry.caas.sh/<tenant-id>/. The CLI looks a tag up in the registry (latest when you give none) and always deploys its digest. Images from other registries or other workspaces are refused: push them to your namespace first. See Images and the registry.
Run workflows
A workflow is a YAML or JSON file of steps. Each step runs in a sandbox of its own, and every finished step is a checkpoint you can resume from:
workflow: hello
inputs:
name: world
steps:
- id: greet
name: Write greeting
run: echo "Hello, ${{ inputs.name }}" > greeting.txt
outputs: [greeting.txt]
- id: show
name: Show greeting
run: cat greeting.txt
inputs: [greet]caas workflows run hello.yaml --input name=caas --follow
caas workflows list
caas workflows show <run-id>
caas workflows pause <run-id>
caas workflows resume <run-id>
caas workflows resume <run-id> --from cp-1 --follow
caas workflows cancel <run-id>| Command | What it does |
|---|---|
caas workflows run FILE | Checks the file and its inputs, pins each image tag to its digest, starts the run, and prints its ID and a link to it in the console. |
caas workflows list | Lists the runs: name and number, status, progress, cost and ID. |
caas workflows show RUN_ID | Shows a run's steps: each one's state, machine and checkpoint, a failed step's exit code and log, and a running step's newest output. If the run can be resumed, it says how. |
caas workflows pause RUN_ID | Lets the steps that are running finish, and starts nothing more. |
caas workflows resume RUN_ID | Lifts a pause, or runs again the steps that didn't finish in a run that ended. |
caas workflows cancel RUN_ID | Ends the run. |
| Option | What it does |
|---|---|
--input NAME=VALUE | With run: sets one of the file's inputs. Repeat it for each input. Inputs the file declares without a default are required. |
--follow | With run, show and resume: print each step as its state changes, and a running step's new output, until the run ends. The CLI exits with 1 unless the run succeeded. |
--from CHECKPOINT | With resume: replay the run from that checkpoint, such as cp-2, with the same inputs. |
A workspace can have up to 10 runs queued, running or paused at once. A run's checkpoints are kept for 7 days after it ends; until then, you can resume it. See Workflows for the file format.
Credentials and outbound access
caas.sh keeps your API keys and tokens out of your sandboxes. You connect each one as a credential of the workspace, and egress rules tell caas.sh which outbound requests to add it to. Inside a sandbox whose rules add it, the credential's name is a variable that holds only a placeholder.
Only an owner's key can connect, reconnect or remove credentials, add or remove apps, and add or remove egress rules. See Credentials and outbound access for how it all fits together.
Credentials
caas credentials connect ANTHROPIC_API_KEY --api-key < anthropic-key.txt
caas credentials connect GITHUB_TOKEN --github
caas credentials connect CODEX --codex
caas credentials list
caas credentials reconnect ANTHROPIC_API_KEY < new-anthropic-key.txt
caas credentials remove ANTHROPIC_API_KEY| Command | What it does |
|---|---|
caas credentials connect NAME METHOD | Connects a credential. See the methods below. |
caas credentials list | Lists the credentials: name, method, status, scopes and number of rules, and how to reconnect any that need it. |
caas credentials reconnect NAME | For an API key, reads the new value from standard input. For a sign-in, starts a new one. |
caas credentials remove NAME | Deletes the credential, its stored value and its egress rules. |
NAME is capital letters, digits and _, such as GITHUB_TOKEN, and can't start with CAAS_. connect takes exactly one method:
| Method | What it does |
|---|---|
--api-key | Reads the key from standard input. The CLI never takes a key as an option. |
--github | Signs in to GitHub through caas.sh's own GitHub App. |
--github-app APP | Installs your own GitHub App, added with caas credentials apps add. |
--oauth APP | Signs in through your own OAuth app, added with caas credentials apps add. Add --scope SCOPE for each scope to ask for; without it, the sign-in asks for every scope the app lists. |
--codex | Connects a ChatGPT account for Codex: the CLI prints a code and OpenAI's page to enter it on. |
A sign-in prints a page to open. It returns to the console's Credentials page, which finishes it while you're signed in there as the owner who started it. The CLI then waits until the credential is ready; --detach returns at once instead, on connect and reconnect.
Apps for sign-ins
Before you connect an --oauth or --github-app credential, add the app it signs in through. The app's secret is read from standard input:
caas credentials apps add google --type oauth2 --preset google \
--client-id 1234.apps.googleusercontent.com \
--scope https://www.googleapis.com/auth/drive.readonly < client-secret.txt
caas credentials connect GOOGLE_DRIVE --oauth google
caas credentials apps add acme-bot --type github-app --client-id Iv1.0123abcd --slug acme-bot < private-key.pem
caas credentials connect GITHUB_APP_TOKEN --github-app acme-bot
caas credentials apps list
caas credentials apps remove acme-bot| Option | What it does |
|---|---|
--type TYPE | oauth2 or github-app. |
--preset PRESET | With oauth2: google, gitlab or linear, which fills in the provider's endpoints. |
--authorize-url URL, --token-url URL | With oauth2 and no preset: the provider's endpoints, https:// URLs on a public host. |
--token-auth METHOD | With oauth2 and no preset: how the token endpoint takes the client secret, post (the default) or basic. |
--client-id ID | The app's client ID. For a GitHub App, its Client ID. |
--scope SCOPE | With oauth2: each scope the app's credentials may ask for. At least one is required. |
--slug SLUG | With github-app: the app's slug, as in github.com/apps/<slug>. |
The app ID is up to 32 lowercase letters, digits and hyphens. Set the app's redirect URI (for a GitHub App, its callback and setup URL) to https://api.caas.sh/v1/credential-interactions/callback.
Egress rules
An egress rule adds a credential to HTTPS requests for a host, on every path:
caas egress rules add --preset anthropic --credential ANTHROPIC_API_KEY
caas egress rules add --preset github --credential GITHUB_TOKEN --sandbox <sandbox-id>
caas egress rules add --credential NPM_TOKEN --host registry.npmjs.org --header authorization --scheme bearer
caas egress rules list
caas egress rules remove <rule-id>| Option | What it does |
|---|---|
--credential NAME | Required. The credential to add. |
--preset PRESET | github (api.github.com by bearer token, and github.com by basic auth for Git), or anthropic, openai or google (the provider's API key in the header its SDKs send). A model provider preset also gives the sandbox the provider's usual key variable, such as ANTHROPIC_API_KEY, holding a placeholder. |
--host HOST | Without a preset: the host. *.example.com covers example.com and every name under it. |
--header NAME | Without a preset: the request header to set, such as authorization. |
--scheme SCHEME | Without a preset: bearer, basic or raw (the value as is). |
--username USER | With --scheme basic: the username. Required for basic. |
--sandbox ID | Apply the rule to one sandbox only. Without it, the rule applies to every sandbox. |
A sandbox can have up to 16 rules. A running sandbox picks up changed rules the next time it starts; a credential's new value applies at once. A rule only adds the credential: the sandbox's egress policy must still allow the host. A Codex credential isn't added by egress rules.
Egress policy
Each sandbox has an ordered list of hosts it may and may not reach. The first match wins, and the list always ends by denying everything else. A new sandbox's policy allows its --egress-host hosts.
caas egress policy show <sandbox-id>
caas egress policy set <sandbox-id> --deny uploads.example.com --allow '*.example.com' --allow pypi.orgcaas egress policy set ID replaces the policy with the --allow HOST and --deny HOST options, in the order you give them, and applies it to a running sandbox at once. Owners and operators can change it.
Billing
caas billing needs a key with Billing access, which only an owner can create.
caas billing balance
caas billing add-funds 25
caas billing auto-recharge show
caas billing auto-recharge set --below 10 --recharge-to 50
caas billing auto-recharge set --off
caas billing usage
caas billing usage --month 2026-09
caas billing usage --csv > caas-usage.csv| Command | What it does |
|---|---|
caas billing balance | Prints the balance, the auto-recharge setting and recent top-ups with their receipts. |
caas billing add-funds AMOUNT | Adds funds: $5 to $2,000, written as 25, 25.50, $25.50 or 1,000. It charges the card on file, or prints a Stripe Checkout link to pay and save a card. |
caas billing auto-recharge show | Prints the auto-recharge setting. |
caas billing auto-recharge set | Turns auto-recharge on, changing only the amounts you give. With --off, turns it off. |
caas billing usage | Prints a month's spend: the total so far, the projection and today while the month is current, the amount for each meter, and the spend alert. |
| Option | What it does |
|---|---|
--below AMOUNT | With auto-recharge set: recharge when the balance falls below this, $5 to $1,000. It's $10 until you change it. |
--recharge-to AMOUNT | With auto-recharge set: charge the card back up to this, at least $5 above --below and at most $2,000. It's $50 until you change it. |
--off | With auto-recharge set: turn auto-recharge off. You get an email when the balance falls below the amount instead. |
--month YYYY-MM | With usage: the month to show. The default is this month. |
--csv | With usage: print the month as CSV, one row per UTC day and meter, with the columns day,meter,quantity,unit,rate_usd,amount_usd. The amounts add up exactly to the month's total. Can't be combined with --json. |
Auto-recharge starts off, so adding funds never charges your card again on its own. Sandboxes run only while the balance is above $0. See Billing and usage.
Workspace settings and the audit log
caas settings
caas settings --time-zone Europe/Berlin
caas audit
caas audit --action sandbox --since 2026-10-01
caas audit --action sandbox.stop --outcome failure --limit 20caas settings prints the workspace's time zone, its one setting. --time-zone ZONE sets it, an IANA name such as Europe/Berlin; new sandboxes take their nightly snapshot at 02:00 in it.
caas audit lists who changed what in the workspace, newest first: the time, who did it, the action, its target, the outcome and the request ID. Records are kept for 365 days.
| Option | What it does |
|---|---|
--action ACTION | An action, such as sandbox.stop or api_key.create, or a group: sandbox, command, mcp_token, secret, egress, api_key, member, invite, tenant, billing or workflow. |
--actor ID | A user or API key ID, or operator or system. |
--target ID | The ID of what was changed. |
--outcome OUTCOME | success or failure. |
--since TIME, --until TIME | ISO 8601 times, such as 2026-10-01 or 2026-10-01T12:00:00Z. |
--limit N | Records per page, 1 to 100. |
--cursor CURSOR | The next page: the value the previous page printed. |
An API key never sees records about API keys, members or invites, and sees billing records only with Billing access. In what a key reads, users show as their user ID rather than their email.