Docs
Security model
Defence in depth is the honest posture. Occlusion reduces what is reachable, isolation blocks memory inspection, denied egress blocks the exit, and the record makes attempts attributable. No single layer is the guarantee.
What it defends
| Route | Control |
|---|---|
| Browsing the code | The editor, hover and go-to-definition see visible files and declaration stubs only. Signatures are shown on purpose |
| The terminal | find, grep -r or cat on an Occluded path gets No such file or directory, as for a file that never existed |
| Scripts and tests | On the person's side, an Occluded file does not exist. On the build's side, output is sanitised and the run is recorded |
| Another process's memory | The build runs as a different user, with no debugging across the two sides. See below |
| The network | Outbound traffic denied by default, a registry allowlist, and scanning at commit |
| Prompt injection of an agent | Occlusion, the grant's scope, and a precise out-of-scope alert |
| Crashes and debuggers | Occluded frames collapse; stepping across the boundary is filtered |
| Git history and build output | .git is Absent from the person's side; build output is Occluded and downloads are filtered |
| Secrets the build needs | Attached on the way out, so the job never holds the value |
| The client bundle in the preview | Compiled client code is readable by whoever runs it. The profile counts the Occluded files the bundle reaches, and the admin acknowledges them or makes them Absent |
The memory question, stated plainly
The compiler must read Occluded files, so they are in the build's memory. Reading another process's memory needs permission to attach to it, on Linux and on gVisor alike. The person's processes run as a different user from the build's, attaching is denied, and the build's processes are not visible to them. So the person's shell, editor and language server cannot read the compiler's memory.
The kernel enforces that line. On a standard container the workspace shares the host's kernel, and a kernel bug could cross it. gVisor puts a user-space kernel between the workspace and the host, with far less to attack. That is what the hardened runtime is for.
The other route is code the person gets the build to run: a test runs on the build's side and can read what the build reads. Its output is sanitised and the run is recorded in full. That residual is structural, and stated in writing with each customer.
We accept three consequences, and say them out loud:
- The hardened runtime on gVisor is required for anything sold as a hardened boundary. Until it ships, the claim is compartmented and governed, never exfiltration-proof.
- No single layer is the guarantee. Occlusion, isolation, denied egress and the record each cover a different failure.
- Absent paths exist so the worst material is never in memory at all. Credentials and data seeds are not Occluded. They are Absent.
What we do not claim
- That a contractor cannot remember or re-derive what they legitimately saw, including from signatures.
- Protection against a collusive insider who holds full access.
- A boundary no kernel bug can cross. We claim a hardened, monitored, logged one.
- That local mode is secure against its own machine's owner. Local mode can be forbidden per repository.
- That an agent cannot write bad code. We claim it cannot merge it past its checks unreviewed.
- Zero-trust, in any material, before the hardened runtime ships.
- That a declaration stub satisfies export-control law. That question is open; see export-controlled teams.
The detail
We go through the threat model vector by vector, with the control and the residual for each, on a call with your security team.