isolation.cloudDOCS

How secrets travel: sealed, encrypted, never in argv

A secret is encrypted at rest, sealed for one server with AES-GCM, materialized 0600 for the sandbox's lifetime, never in argv, URLs, bundles or logs.

Isolation handles secrets and API keys with one rule: a value is decrypted only by the one thing that needs it, for as long as it needs it, and never lands anywhere it could be copied from later. This page follows a secret from the moment you type it to the moment the session ends.

Where a secret enters

You add a credential on the Credentials page, from the CLI or from an MCP client. The one door that refuses a secret is chat: credential_create accepts an ssh public key from Slack or Teams and nothing else, because a key pasted into a channel stays in that channel's history forever. A subscription login never types a secret anywhere: credential_login_start hands back a URL and a code, and credential_login_complete stores the result.

Environment variables and secret files are a separate thing, described in environments, variables and secret files. They are for code inside the sandbox to read. Credentials are for hosts the sandbox must call but must never hold.

Encrypted at rest

Every value is written to Isolation's database under AES-GCM. The key is derived with HKDF-SHA256 from a dedicated root secret with a versioned label, so the credential key is distinct from every other key derived from that root and can be rotated by bumping the label. The value is write-only from then on. credentials_list returns labels, kinds and hosts, never a value, and that is why it is safe on every door. Gateway tokens are stored only as a SHA-256 hash, so a database dump cannot hand out live proxy access.

Sealed for one server

At launch, Isolation resolves the credentials the session needs and seals them into one envelope for the target server: AES-GCM with a 12-byte IV and a 16-byte tag, under a key derived by HKDF-SHA256 from that server's pairing secret. Only the server that ran isolation-server connect holds that secret, so only that server can open the envelope. A Cloud Server, which never pairs, is sealed to the master token its cloud-init delivered. isolation-server tries its pairing secret first, then the master token; the GCM tag picks the right one. See connected servers: install and pair for where the pairing secret comes from.

Materialized 0600, for the sandbox's lifetime

The server opens the envelope in memory. The only launch material it keeps on its own disk between restarts, so that a session can still save and sync after the server process restarts, is written sealed under a key the server holds in its own 0600 configuration; the file alone is nothing to whoever copies it. Secret files are written into the sandbox with mode 0600 before any view or user process runs. A deploy key for an ssh clone is written 0600, referenced through GIT_SSH_COMMAND, and deleted right after the clone. Your ssh public keys land in authorized_keys at 0600 in a 0700 directory, which is what sshd demands. All of it is gone when the session ends, and a snapshot restore re-fetches a fresh envelope instead of keeping anything on the host.

Never in argv, URLs, bundles or logs

PlaceWhat you find there
Process argumentsNothing. An HTTPS clone token is read by an askpass script from the command's environment, never from git clone https://token@....
Git remotesA host name, or Isolation's /git/<host>/<owner>/<repo> route. Never a token.
Workspace bundlesNothing. Every credential path under an agent's HOME is gitignored before it can exist, so the tree that persists to R2 carries no secret.
LogsNothing. The git route streams bodies without reading or logging them, and vault errors are stripped of any credential value before they are recorded.
The activity logWho did what, from which door. Never a value.

API keys and tokens never enter the sandbox at all

For anything reached over HTTPS, an AI provider, a git host, a custom API, Isolation goes one step further. The sandbox runs on placeholders: ANTHROPIC_API_KEY=isolation-vault and a base URL. Next to every sandbox with credentials runs an egress sidecar, the OpenSandbox Credential Vault, which holds the values in its own memory and replaces the authorization header on the way out, per host and path binding. The tools inside never notice. Inside a session, this is all you can see:

$ env | grep ANTHROPIC
ANTHROPIC_API_KEY=isolation-vault
ANTHROPIC_BASE_URL=https://app.isolation.cloud/anthropic/t/session

For AI credentials the sidecar injects a scoped isogw_ token, bound to this session and revoked at teardown, with a 30-day ceiling. Every agent's harness runs on the same placeholder as the terminal; the token itself lives only in the sidecar. Isolation's gateway swaps it for the real key upstream, so the real key never leaves Isolation's database. For git and custom credentials you can choose direct delivery, where the real token sits in the sidecar on the server host and goes straight to the upstream. Either way the sandbox, its filesystem, its snapshots and its env hold nothing worth stealing. The vault dies with the sandbox; suspend and resume keep it.

Nothing is discovered from the host

isolation-server never reads ~/.ssh, a git credential helper, a keychain or a CLI's login file on the machine it runs on. Everything a session uses arrives sealed at launch. A Connected Server on your laptop is exactly as blind as a Cloud Server, which is what makes the two interchangeable.

Questions

Can Isolation read my API key back to me?

No. Every stored value is write-only. The credentials list shows labels, hosts and kinds, never a value, on every door including the API.

Does the real API key ever enter the sandbox?

No. The sandbox runs on a placeholder. The egress sidecar next to it swaps in a session-scoped token on the way out, and the gateway swaps that for the real key.

Does the server look at my machine's credentials?

No. isolation-server discovers nothing on its host by design. Every secret a session uses arrives sealed at launch.