How it works
Occlude runs in your cloud. Each session is a workspace with two sides: one for the person, one for the build. The person's side shows the files their task needs. The build's side has the whole repository. This page is the design; each part is marked with what is available today.
- 01Your cloudThe whole repository, every file present. It never leaves your cloud.
- 02The viewMade per session, from the task. The build sees every file; the person sees only what passes through.
- 03What the person seesVisible files whole, Read-only ones they cannot change. The same view through every door the session opens.
- 04The ledgerEvery read and every refused attempt, on the record.
Where it runs
Runs in your cloud.
Status: Planned
One installation per company: its own database, storage, network and pool of workspaces. Nothing of one company's is reachable from another's.
Paid installations go into your Kubernetes with a Helm chart. Trials and Observation Mode run the same thing, hosted by us, single-tenant. The repository, the builds and the running app stay inside that installation.
One session
One task, one workspace.
Status: AvailablePlanned
A session is one unit of work: a contractor's ticket, or one agent run. It starts from a grant: a purpose, a set of files and a time box. A grant that touches an Absent path waits for a named approver before anything starts.
Occlude resolves the grant into a manifest that gives every path in the repository one of the four states, signs it, and starts a workspace. The workspace refuses a manifest that is unsigned or expired. When the grant ends or is revoked, the workspace closes.
Two sides
The person's side and the build's side.
Status: Available
Inside the workspace, the person's processes and the build's processes run as different users, each with its own view of the filesystem. The person's shell, editor and language server see Visible and Read-only files, plus generated declarations wherever their code imports an Occluded module. The compiler, test runner and dev server see the real repository, minus Absent paths.
The person starts a build by name: npm run dev, npm test. It runs on the build's side. The person cannot attach a debugger to it or see its processes. Its output comes back sanitised: a failure inside an Occluded module shows as a protected module, next to the line in the person's own file that called it.
Four states
What each state answers.
Status: Available
Every file operation from the person's side is answered by one table. Nothing else decides.
| Operation | Visible | Read-only | Occluded | Absent |
|---|---|---|---|---|
| In the file tree | Listed | Listed | Not listed | Not listed |
| Open and read | Yes | Yes | No such file | No such file |
| Write, rename, delete | Yes | Refused, logged | No such file | No such file |
| Hover and go-to-definition | Full | Full | Signature only | Nothing |
| Available to the build | Yes | Yes | Yes | Never mounted |
| On an attempt | Nothing to log | Logged | Logged, silently | Held for a named approver |
Occluded answers exactly like a file that does not exist, never "permission denied", because "permission denied" confirms the file is there.
Never in the view
What the person's side never shows.
Status: Available
Some paths are dangerous whatever the task, so every profile starts with them handled:
- Git history. It holds every version of every Occluded file. Git runs on the build's side, by name.
- Build output, coverage and source maps. Bundles carry Occluded code. The preview is served from the build's side.
- Package manifests and lockfiles are Read-only for contractors: whoever edits
scriptsdecides what the build runs. - Credentials,
.envfiles and data seeds are Absent. - Dependencies are Read-only: the language server needs their types, and nobody needs to edit them.
Doors
Every door, the same view.
Status: AvailablePlanned
A door is any client attached to the person's side: the browser workspace, VS Code over SSH, an agent such as Claude Code, Codex or Cursor over MCP, or the agent that runs inside Occlude. All of them speak one protocol to the same workspace, so a file refused through one door is refused through every door, and the record is the same apart from the door's name.
Local mode, where a developer runs Occlude's bridge on their own machine, is outside this claim: whoever owns the machine owns the workspace. It is labelled unenforced everywhere, and an admin can forbid it per repository.
The record
Every attempt, on the record.
Status: AvailablePlanned
Every refused attempt is recorded with the rule that refused it, the process that asked, the path, the operation and the time. The record is append-only. An alert fires only on an actual attempt at an Occluded or Absent path, never on a guess, so it is worth reading.
At audit time, one export per session: the profile it ran under, every file touched, every refusal and which rule refused it. The export verifies itself.
Isolation
The isolation ladder.
Status: Planned
The compiler must read Occluded files, so they are in the workspace's memory. The person's processes cannot read it: they run as a different user and cannot attach a debugger or open the build's memory. In the end the kernel holds that line, so the claim depends on the rung:
- runc, today. Separate users, a syscall filter, no debugger across the two sides, on the host's shared kernel. A kernel bug could cross that line, so the claim is compartmented, not exfiltration-proof.
- gVisor, before any session sold as a hardened boundary. A user-space kernel stands between the workspace and the host, so a kernel bug has far less to reach.
- Firecracker, for teams that ask for it. Hardware virtualisation per session.
Credentials and data seeds are why Absent exists: they are never in the workspace's memory, on any rung.
Questions this page doesn't answer?
Bring them to the call. Twenty minutes, with the founder, and we'll walk through your repository's version of this page.
Or write to contact@occludehq.com