11# DeepCode Security Model
22
3- > Last updated: 2026-08-01 (shared app-server trust and config provenance )
3+ > Last updated: 2026-08-01 (shared app-server trust, provenance, and thin-client capabilities )
44
55This document is the ** single source of truth** for what DeepCode protects
66against, what it doesn't, and how each layer composes. If you're reviewing a
@@ -17,13 +17,23 @@ decreasing order of operator severity:
1717| 1 | Model exfiltrates DeepSeek API key (or other env secrets) via tool call | High | M3.5 sandbox + M5.1 env strip |
1818| 2 | Model writes arbitrary files outside the project (` /usr/bin ` , ` /etc ` ) | High | M3.5 sandbox + permissions |
1919| 3 | Plugin (third-party code) does either #1 or #2 | High | M5.1 subprocess + (M5.1-ext) OS sandbox |
20- | 4 | Hook script (third-party shell snippet) does either #1 or #2 | Medium | M3.5 sandbox wraps Bash; hooks bypass when invoked via /bin/sh directly |
20+ | 4 | Hook script (third-party shell snippet) does either #1 or #2 | Medium | Exact-definition review + source trust; hook commands remain host code |
2121| 5 | Hostile ` settings.json ` field (e.g. allowRead path) injects sandbox rule | Medium | escapeSbpl() |
2222| 6 | Untrusted project's AGENTS.md drives the agent into harmful action | Low | Trust store (` /trust ` ) |
2323| 7 | DNS exfiltration of secrets from sandboxed Bash | Partly mitigated | M3.5-ext DNS allowlist (netns.ts) — names only; raw-IP dials still pass |
2424
2525## Defence layers
2626
27+ ### Runtime placement — thin clients
28+
29+ The Tauri WebView, VS Code extension, and LSP process are protocol clients, not trusted runtimes.
30+ Provider credentials, model calls, tools, permissions, hooks, MCP, and plugins stay in the CLI host
31+ or app-server. The Tauri capability set is least-privilege: file/folder selection, default
32+ HTTP(S)/mailto/tel URL opening, updater operations, and application restart. It has no Tauri
33+ filesystem plugin, shell permission, generic process-exit permission, file-reveal permission, or CSP
34+ route to the provider API. Read-only file preview and session history use explicit Rust commands
35+ that reject the backend credential path; all workspace mutations use the versioned protocol.
36+
2737### Layer 0 — Trust store
2838
2939First time DeepCode opens a folder, you're asked ** "Do you trust this
@@ -124,15 +134,16 @@ not an oversight. (M5.2 will add per-clause analysis.)
124134
125135Plugins run in their own ` node ` subprocess with:
126136
127- - ** No host fs/net access** in plugin code — all capabilities (` fs_read ` ,
128- ` fs_write ` , ` bash ` , ` fetch ` ) flow via JSON-RPC over stdio back to the host,
129- which applies its own mode/permission/sandbox stack.
137+ - ** Gated host capabilities** — declared ` fs_read ` , ` fs_write ` , ` bash ` , and ` fetch ` requests flow via
138+ JSON-RPC over stdio back to the host, which applies mode, permission, hook, approval, and sandbox
139+ policy. This controls the supported plugin API; it is not yet an OS boundary against a malicious
140+ plugin using Node APIs directly.
130141- ** Token-protected RPC** — host generates an unguessable token per plugin
131142 spawn; every RPC from the plugin must include it.
132143- ** Env scrub** — ` DEEPSEEK_API_KEY ` and ` DEEPSEEK_AUTH_TOKEN ` are stripped
133144 from the child env. Plugins cannot read DeepSeek credentials.
134- - ** Hash pin** — plugin code is SHA-256 hashed at install time; mismatch on
135- load fails open ( drift detection) .
145+ - ** Whole-install hash pin** — every installed plugin file contributes to the SHA-256 trust hash;
146+ missing trust or any drift disables the plugin and reports a diagnostic .
136147
137148** Acknowledged gaps** :
138149
@@ -166,25 +177,25 @@ etc.) as **untrusted**. We:
166177
167178## Attack-vector test suite
168179
169- ` packages/core/src/sandbox/attacks.test.ts ` contains 17 tests :
180+ ` packages/core/src/sandbox/attacks.test.ts ` and the platform integration suites cover :
170181
171- - ** 6 unit -level** "hostile input → safe output" tests :
182+ - ** Unit -level** "hostile input → safe output" cases :
172183 - SBPL paren/quote escaping
173184 - SBPL backslash escaping
174185 - deny-after-allow ordering
175186 - no implicit network when allowedDomains is empty
176187 - no implicit file-write to /usr, /System, /Library
177- - ** 3 bwrap-arg safety** tests :
188+ - ** bwrap-argument safety** cases :
178189 - no --share-net even with a non-empty allowedDomains (connectivity comes from
179190 slirp4netns externally, never by sharing the host netns)
180191 - only cwd is bare --bind
181192 - always --unshare-{pid,ipc,uts}
182- - ** 4 excluded -command spoofing** tests :
193+ - ** Excluded -command spoofing** cases :
183194 - prefix-only match (` gitleaks ` ) does NOT bypass
184195 - exact match bypasses
185196 - leading-token match bypasses
186197 - pipeline-after-excluded bypasses (documented behavior; M5.2 hardens)
187- - ** 2 sandbox-exec e2e** (macOS, runIf the binary exists):
198+ - ** sandbox-exec e2e** (macOS, runIf the binary exists):
188199 - block write to ` /usr/local/bin/* `
189200 - profile is syntactically valid (smoke)
190201- ** bwrap e2e** (Linux CI, runIf ` bwrap ` exists — ` bwrap-integration.test.ts ` ):
0 commit comments