Isolation model
The container that runs Claude holds no tokens and no credentials, and it cannot reach GitLab, Slack, SharePoint, or any other service directly. When a project connects a service, that service gets its own worker container, and only the worker mounts its credentials, read-only. Claude reasons and writes code, but a credential never passes through it. See Credentials for the details.
No tokens, no shortcuts
Section titled “No tokens, no shortcuts”Every container Speedwave renders, the Claude container, the hub, and each worker, gets the same hardening: every Linux capability dropped, privilege escalation blocked, a read-only root filesystem, and /tmp mounted so nothing written there can execute. A CPU and memory cap is a resource limit, not a security boundary: it stops a runaway process, nothing more.
Claude never talks to a service directly. It talks to the hub, the hub forwards to the right worker, and only that worker holds the credential the call needs: a compromised worker exposes one service, a compromised hub exposes nothing. The office worker, which converts Word, Excel, PowerPoint, and PDF files, goes further: no credentials, no route to the gateway, so even a compromised document parser cannot reach the internet.
flowchart LR
Claude["Claude container<br/>(no tokens)"] -->|HTTP| Hub["Hub<br/>(zero tokens)"]
Hub -->|HTTP| Slack["Slack worker"]
Hub -->|HTTP| GH["GitHub worker"]
Slack -->|"reads"| ST[("Slack credentials, read-only")]
GH -->|"reads"| GT[("GitHub credentials, read-only")]
It can’t build your Gradle or .NET project
Section titled “It can’t build your Gradle or .NET project”The Claude container ships only node with npm and python3 with pip, plus git and a shell. It has no route to your host toolchain: no JDK, no Gradle, no Go, no .NET, no host container engine. Speedwave built a worker for whitelisted host build commands, then removed it: letting Claude trigger host execution weakened the isolation this container exists to provide.
Links you click are checked too
Section titled “Links you click are checked too”The chat UI never navigates in-app when you click a link Claude wrote. It hands the URL to open_url, which opens it in your default browser instead, after rejecting URLs over 8192 characters and checking SSRF rules: only http/https, no loopback, private, or link-local addresses. A manipulated link can’t reach a service on your network. The same validation protects plugin OAuth URLs; see Writing a plugin for that case.
Projects don’t share a network
Section titled “Projects don’t share a network”Isolation applies per project too. Each project gets its own container network and tokens directory, so a worker in one project cannot reach another project’s network or credentials, and logging in to a service for one project doesn’t authenticate it for another. See Container topology for what each project creates.
This sits on two more layers: individually hardened containers, and a lightweight VM (Lima on macOS, WSL2 on Windows) separating all of them from the host at the kernel level. An attacker who compromised Claude would land in an empty-handed container with the VM still between them and your machine. See How it works for the picture.