Security Legends: Engineering Practices for Locara
What this is: A research note distilling principles from systems with legendary security reputations, with concrete application to Locara (Tauri/Rust + WebView, capability-based sandboxing for third-party apps). Inspiration for the security model + the discipline behind it.
Status: Reference document. Pair with notes/security-audit.md for current findings, and the runtime ADRs for what’s implemented.
Most relevant to Locara: This is the bible for design decisions. Where one of these legends would shake their head at our code, that’s a defect, not a stylistic preference.
1. qmail (D. J. Bernstein)
Primary source: DJB, “Some thoughts on security after ten years of qmail 1.0” (2007), cr.yp.to/qmail/qmailsec-20071101.pdf. Also the original qmail.org security guarantee ($500 bounty, never paid out for ~a decade).
Key principles:
- Eliminate bugs by eliminating code. Most of qmail is “trivial code that didn’t get a chance to have bugs.” DJB explicitly argues that security has more to do with amount of trusted code than with how carefully it’s written. Quote: “I should have written much less code.”
- Eliminate trusted code paths. Distinguish “trusted” (its bugs can violate the policy) from “untrusted” (its bugs can’t). qmail’s mail-parsing code runs unprivileged and chrooted; only
qmail-queue(tiny, ~700 LOC) holds a privileged file handle. - Distrust all input. Every component re-parses/re-validates rather than trusting upstream cleaning. Network-facing code never holds privilege.
- No partial parsing of complex grammars. qmail uses simple file formats (one message per file, dot-encoded) instead of in-band escaping.
Concretely done: 7 isolated UIDs, each component running as the least-privileged one; replacement of sendmail’s monolith with ~10 small programs piped together; rejection of features (e.g. no .forward chaining) that expand attack surface.
Apply to Locara:
- The Tauri Rust core is your
qmail-queue— keep it tiny, audit every line. Every capability check belongs there, not in plugins or the webview. - Manifest parsing, plugin metadata, model-name strings — re-validate at every privilege boundary, even from “your own” frontend. The webview is hostile; treat IPC like network input.
- Resist feature creep in the privileged broker. Features like “let plugins call other plugins” or “let plugins read each other’s storage” are sendmail-style monoliths waiting to happen.
- Theater warning: input “sanitization” via blocklists is qmail’s antithesis. Use simple, parseable formats and reject ambiguous input.
2. OpenBSD (Theo de Raadt et al.)
Primary sources: man.openbsd.org/pledge.2, man.openbsd.org/unveil.2; Theo’s talks “Pledge: A new mitigation mechanism” (Hackfest 2015) and “Mitigations and other real security features” (BSDCan); the OpenBSD Innovations page openbsd.org/innovations.html.
Key principles:
- Secure by default, not by configuration. Out-of-the-box install has minimal services; everything ships disabled. Defaults are the security boundary because most users never change them.
- Mitigations as exploit-economics. W^X, ASLR, stack protector (ProPolice, born at OpenBSD), RETGUARD, kernel-relink-on-boot (KARL), pinsyscalls, MAP_STACK. Each one alone is bypassable; stacked, they raise per-exploit cost from days to months.
- Promise-based privilege reduction at runtime.
pledge(2)lets a process declare a list of allowed syscall classes (“stdio rpath inet”); any syscall outside the set kills the process.unveil(2)does the same for filesystem paths (pre-declare which paths are visible; the rest don’t exist for that process). Critically, this is per-process self-restriction — the program tells the kernel “from now on, I won’t need X.” - Code-review culture. Tree-wide audits (“the audit”); no commits without review; aggressive removal of dead code.
Apply to Locara:
- Plugins should be the kernel’s view of an OpenBSD process: each gets a
pledge-like declared capability set in its manifest, enforced at the Tauri-IPC boundary. The manifest is the kernel-enforced contract. - Adopt
unveil’s mental model for filesystem access: a plugin sees only/plugins/<id>/data/, period. Not a “deny if path startsWith /Users/…” check; an enumerated visibility list in the broker. - Stack mitigations: Rust memory safety + sandboxed filesystem + denied network egress + per-plugin OS-level sandbox-exec/seccomp profile. None alone is sufficient.
- Theater warning: a permission UI that defaults to “allow all” is the opposite of secure-by-default. Default-deny everything; force the manifest to enumerate.
3. seL4 microkernel
Primary sources: Klein et al., “seL4: Formal Verification of an OS Kernel” (SOSP 2009); Murray et al., “seL4: from General Purpose to a Proof of Information Flow Enforcement” (S&P 2013); sel4.systems/About/seL4-whitepaper.pdf.
Key principles:
- Formal proof of functional correctness against a spec. ~10,000 LOC of C kernel proven (in Isabelle/HOL) to refine an abstract spec. Plus integrity, confidentiality, and (for ARM) translation-correctness proofs.
- Capability-based access control as the kernel’s only security primitive. Every operation requires presenting an unforgeable capability (an opaque reference + rights). No ambient authority — there is no “user ID” that grants implicit access.
- Minimality enables verification. seL4 is small because large = unverifiable. The proof depends on the kernel doing very little.
What the proof buys: zero buffer-overflow, zero NULL-deref, zero use-after-free in the kernel itself, against the modeled assumptions (compiler correctness, hardware behavior, sequential execution model). What it does not buy: protection against bad userspace policy, side channels not in the model, or hardware bugs (Meltdown-class).
Apply to Locara:
- Even without formal proofs, adopt the capability-as-only-auth model: Tauri commands take an opaque, unforgeable handle (e.g., a session-bound token) rather than a string identifier the plugin chose. No “give me the file at this path” — instead “give me the file the user picked, here’s the token.”
- Keep the privileged broker code small enough that a single engineer can hold it in their head.
- Theater warning: “we use capabilities” without removing ambient authority is meaningless. If a plugin can also call
fs.read("/etc/passwd")because it’s a Node API still in scope, the capability layer is a fig leaf.
4. SQLite testing rigor
Primary source: sqlite.org/testing.html (the canonical methodology page).
Key practices:
- MC/DC (Modified Condition/Decision Coverage), the DO-178B avionics standard. Every boolean sub-expression must be shown to independently affect the outcome. SQLite is the only widely-deployed DB to claim this.
- TH3 (Test Harness #3): proprietary 100% MC/DC test suite, run on every release across ~20 compilers and many platforms.
- ~590× test code to source code ratio (last published figure). Tests include three independent harnesses (TCL-based, TH3, SLT) so a bug in one harness doesn’t hide bugs.
- Fuzz: dbsqlfuzz, LibFuzzer, AFL, OSS-Fuzz, anomaly testing (out-of-memory, I/O errors, disk-full, crash-and-recover injected at every malloc and every syscall).
- Boundary value tests, regression tests for every reported bug, valgrind/MSan/UBSan/ASan clean.
Why CVEs are near-zero: deeply tested + zero dependencies + small codebase + extreme conservatism about new features. SQLite’s secret isn’t one technique; it’s uniform paranoia at every level.
Apply to Locara:
- For the privileged broker (capability checks, IPC dispatch, manifest parser): aim for property-based + fuzz testing, not just unit tests. Rust’s
cargo-fuzz+proptestare the right tools. - Inject anomaly faults — what happens when allocation fails mid-IPC? When a plugin crashes mid-call holding a capability handle? When the user revokes permission while a tool call is in flight? Test the permission-revocation race explicitly.
- 100% line coverage is not 100% MC/DC. For critical capability code, the gap matters.
- Theater warning: high test count != high coverage of decision logic. Counting tests is a vanity metric.
5. Chrome’s site isolation + sandboxing
Primary sources: chromium.org/Home/chromium-security/site-isolation/; Reis et al., “Site Isolation: Process Separation for Web Sites within the Browser” (USENIX Security 2019); the Chrome sandbox design doc chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox.md; Mojo IPC docs.
Key principles:
- Defense in depth via independent layers, each assuming the others fail. Renderer is sandboxed (seccomp-bpf on Linux, AppContainer on Windows, sandbox_init on macOS) and origin-isolated (Site Isolation puts each origin in its own process post-Spectre) and IPC is mojo-typed with broker-mediated access and V8 runs untrusted JS with a typed boundary. Each layer is bypassable; all four together is rare.
- The renderer is the enemy. Any code parsing untrusted bytes (HTML, JS, images, fonts, video) lives in the lowest-privilege process. The browser process never touches untrusted bytes if it can avoid it.
- Brokered access, not direct syscalls. Sandboxed processes can’t open files; they ask the browser process via Mojo IPC, which validates and decides.
- Spectre as a forcing function for process boundaries. Post-2018, “same-origin policy in one process” was deemed broken; site isolation made the OS process the security boundary.
Apply to Locara:
- The webview is Chrome’s renderer. It parses untrusted-by-default content (LLM output, user-pasted text, plugin-rendered UI). Treat every IPC message from it as adversarial, even if your own code wrote it — same as Chrome treats messages from its own renderer.
- Plugins should run in separate processes from the broker if the platform allows (Tauri sidecars, OS sandbox-exec / WSB / firejail). One sandbox layer (Wasmtime, Deno permissions, etc.) is not Chrome-grade.
- Mojo lesson: every IPC message has a typed schema with an explicit security review. Don’t accept arbitrary JSON from plugins; use a typed RPC schema where every field has a parser and the parser is fuzzed.
- LLM tool-use IPC is your Mojo. Validate every parameter at the broker; never trust the model’s “the user said it’s fine.”
- Theater warning: “the browser sandbox protects us” — only if you’re not exposing privileged Tauri commands to arbitrary
https:origins. Every exposed command is a hole through the sandbox.
6. Capability-based security theory
Primary sources: Norm Hardy, “The Confused Deputy” (1988); Mark Miller, “Robust Composition: Towards a Unified Approach to Access Control and Concurrency Control” (PhD thesis, JHU 2006); Shapiro et al., “EROS: A Fast Capability System” (SOSP 1999); Genode OS Foundations book (genode.org/documentation/genode-foundations); Miller, Tulloh, Shapiro, “The Structure of Authority: Why Security Is Not a Separable Concern” (2004).
Key principles:
- No ambient authority. There is no global “I am user X, therefore I can read X’s files.” All authority is held as designated capabilities passed explicitly. The classic counterexample is the Confused Deputy: a compiler with both the user’s permissions and the system’s permissions can be tricked by the user into overwriting the system’s billing file. Ambient authority + intermediary = pivot.
- POLA (Principle of Least Authority). Each subject gets the minimum set of capabilities needed for its current task, not its lifetime. Object-capability discipline makes POLA the default by making authority explicit and passable.
- Designation = authorization. The act of being given a capability is the permission. There is no separate ACL check. This kills entire bug classes (path traversal, TOCTOU on permission lookup).
Apply to Locara:
- This is the bedrock principle for Locara’s plugin model. A plugin saying
read_file("config.json")is wrong; the right shape is the user picks a file, the broker gives the plugin aFileHandlecapability bound to that file, and the plugin can only operate on what it was given. No path strings cross the boundary. - Likewise for models, embeddings, network: plugins receive
ModelHandle,EmbeddingIndexHandle,NetworkScopecapabilities. Their manifest declares types it needs; the user grants instances. - Confused-deputy check for Locara: if Plugin A can ask the broker to invoke Plugin B on its behalf, and B inherits the user’s authority rather than A’s, you have built a confused deputy. Calls between plugins must carry the caller’s capability set, not the user’s.
- Theater warning: many “capability systems” are actually permission flags (booleans), not capabilities (unforgeable references). Boolean
network: trueis ambient authority for the whole internet;NetworkScope { hosts: [api.x.com] }granted at install time is closer to a capability, but only if it’s an unforgeable handle the plugin holds, not a string the broker rechecks each call.
7. Rust’s security wins
Primary sources: Matt Miller (Microsoft), “Trends, challenges, and shifts in software vulnerability mitigation” (BlueHat IL 2019) — the “~70% of CVEs are memory safety issues” stat; Google Project Zero, “0day In-the-Wild” tracker; Android Security Bulletin trend posts (security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html — “no memory safety vulnerabilities in Rust code in Android”); Chromium’s “Memory safety” page.
Key facts:
- ~70% of Microsoft’s annually patched CVEs over 12 years were memory-safety bugs. Same approximate figure from Chromium and Android.
- Android 13 was the first Android release where the majority of new code was memory-safe; the number of memory-safety CVEs in Android dropped from 223 (2019) to 85 (2022) — a >2× reduction. Google reported zero memory-safety vulnerabilities in Rust code in Android over the two years tracked.
- What Rust eliminates: use-after-free, double-free, out-of-bounds reads/writes, data races (in safe code), uninitialized memory reads, type confusion. What it doesn’t: logic bugs, TOCTOU, unsafe-block bugs, FFI bugs, supply-chain attacks, dependency vulns, panics-as-DoS.
Apply to Locara:
- Tauri’s Rust core wipes out the dominant CVE class in the privileged process. This is real, not theoretical — Project Zero’s iOS/Chrome 0day analyses are dominated by C/C++ memory bugs.
- But your unsafe blocks and FFI to system libraries are still C-grade risk. Audit them with the same paranoia as a C codebase. Consider crates like
mirifor unsafe code review. - The webview frontend is still JavaScript on a C++ engine (WebKit/WebView2). The renderer-process attack surface didn’t go away; you just moved memory bugs out of your code.
- Theater warning: “we’re written in Rust” is not a security claim by itself. It eliminates one (huge) bug class. Logic bugs in capability checks, prompt injection, supply chain, and design flaws are unaffected.
8. macOS app sandbox + entitlements + TCC
Primary sources: Apple’s App Sandbox Design Guide (developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/); Hardened Runtime docs; Patrick Wardle’s The Art of Mac Malware and Objective-See blog; CVE history of TCC bypasses (e.g., CVE-2020-9934, CVE-2021-30970 “powerdir”, many more).
What’s actually enforced:
- App Sandbox (kernel-enforced via Sandbox.kext / sandboxd, MAC framework): file access restricted to container, IPC restricted, syscall-level mediation. Mandatory for Mac App Store apps; opt-in elsewhere.
- Entitlements: signed claims about what the app may do (
com.apple.security.network.client, etc.). Verified byamfid/taskgatedat launch. Forging requires bypassing code signing. - Hardened Runtime: prevents code injection, library hijacking, restricted segment writes; required for notarization.
What’s “best effort”:
- TCC (Transparency, Consent, Control) — the user-prompted access to Camera, Mic, Photos, Documents, Desktop, Downloads, Full Disk Access. Enforced in userspace by
tccd, with a database in~/Library/Application Support/com.apple.TCC/TCC.db. Many historical bypasses (synthetic clicks, dyld hijacks pre-Hardened Runtime, file-overwrite races, dangling references after uninstall, etc.). TCC is an interlock to prevent silent access, not a strong sandbox. - Notarization is malware-scanning, not security review. Apple does not audit your code for vulnerabilities or capability abuse.
- Code signing identifies the publisher; it grants no capability. A signed binary with
network.cliententitlement is exactly as dangerous as the developer makes it.
Apply to Locara:
- Entitlements ↔ Locara’s plugin manifest. They should be declared at install time, displayed to the user, kernel-enforced at runtime, and changing them requires re-installation/re-consent.
- TCC ↔ runtime user prompts (“this plugin wants access to your contacts”). Useful as a second layer, but never the only enforcement. Per Apple’s own TCC bypass history, prompt-driven gating is fragile.
- Theater warning: code signing is identity, not capability. Notarization is malware scan, not audit. A plugin signed by a trusted dev still gets exactly the manifest’s capabilities and no more — and if your manifest is wide, the signature gives the user false confidence.
9. Plan 9-style namespace isolation
Primary sources: Pike, Presotto, Dorward, Flandrena, Thompson, Trickey, Winterbottom, “Plan 9 from Bell Labs” (USENIX 1995); “The Use of Name Spaces in Plan 9” (1992); Linux mount namespaces / Linux containers as the inheritor; man namespaces(7).
Key principles:
- Per-process namespaces. Every process has its own view of the filesystem (and devices, and network, in Plan 9 because everything is a file). A process can see only what its parent mounted into its namespace. No global root.
- Resources as files, accessed through the namespace. Network, GUI, processes — all appear as file trees. The capability to use a resource = the capability to see its file in your namespace.
bindandmountare the composition primitives. Build a process’s world by union-mounting just what it needs.
Apply to Locara:
- This is the mental model for plugin isolation. A plugin doesn’t “ask permission to read /Users/…/Documents”; the broker constructs the plugin’s world such that only
/plugin-dataand granted file handles exist. There is no path that resolves to anything else, period — likeunveil(2)taken to the limit. - For local model files, embeddings DBs, and tool binaries: each plugin’s namespace contains only the model handles it was granted. Even file-enumeration leaks information; restrict it.
- Theater warning: a chroot is not a security boundary by itself (well-known escapes via fd-passing, /proc, etc.). Combine with user-namespace + seccomp + capability-drop. Plan 9 had it easy: it was designed for this. Retrofitting onto macOS/Windows requires multiple OS primitives stacked.
10. Recent agent-platform breaches (ambient auth, prompt injection)
Public-record incidents (citeable):
- GitHub MCP “Toxic Agent Flow” (Invariant Labs, May 2025): a malicious public issue’s text (prompt injection) caused an agent with the official GitHub MCP server to exfiltrate the contents of private repos to a public PR. Root cause: the agent had ambient authority across all repos the user’s PAT covered; the MCP server doesn’t enforce per-call scoping. Source:
invariantlabs.ai/blog/mcp-github-vulnerability. - “EchoLeak” / Microsoft 365 Copilot (Aim Security, June 2025, CVE-2025-32711): a single crafted email caused Copilot to exfiltrate tenant data with no user interaction — the model treated email body as instructions. Source: Microsoft MSRC advisory; Aim Labs disclosure.
- ChatGPT plugin OAuth flaws (Salt Labs, March 2024): account-takeover via OAuth redirect handling in the plugin install flow; victim installs attacker’s plugin without consent; attacker plugin then has the victim’s account scope. Source:
salt.security/blog/chatgpt-plugins-flaws. - Anthropic Claude Desktop / MCP server vulnerabilities (multiple researchers, 2024–2025): command-injection in third-party MCP servers (e.g., the SQLite MCP server), prompt-injection-driven file exfiltration via filesystem MCP servers configured with overly broad roots. Documented across Embrace The Red, Simon Willison’s blog, and HiddenLayer reports.
- “Rules File Backdoor” (Pillar Security, March 2025): invisible Unicode in Cursor/Copilot rules files acted as persistent prompt injection that influenced generated code. Same class as MCP
tools/listpoisoning.
Common pattern: in every case, the agent had ambient authority (a token, a filesystem root, an API key) far broader than any single task required. A prompt injection or social-engineering vector then exercised that ambient authority. There is no exploit chain here — just one capability boundary missing.
Cross-domain prompt injection: Greshake et al., “Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection” (AISec 2023, arXiv:2302.12173) — the foundational paper. Untrusted input read by a tool (web page, email, file) becomes instructions to the model. The defense is not prompt engineering; it is treating model output as untrusted and gating tool calls on capabilities the user granted, not the model requested.
Apply to Locara:
- Every lesson above (qmail, OpenBSD, capabilities) was independently re-learned in 2024–25 by the agent ecosystem at user expense. Locara’s edge is starting with these lessons.
- The agent loop is the new “renderer process”: it parses untrusted bytes (model output) into actions. Treat tool-call requests from the model identically to IPC from a Chrome renderer — typed schema, capability check, broker decides.
- Per-tool-call capability scoping, not per-session. A model that needs to read one file should hold a one-file capability for that call only, not a directory root for the conversation.
- Theater warning: “the model has been trained to refuse malicious instructions” — RLHF is not a security boundary. Neither is “we filter user input for prompt injection.” If your security posture depends on the model behaving, you have no security posture.
Cross-cutting “looks-like-security-but-isn’t” list
- Code signing is identity, not capability. (Apple, Microsoft.)
- TLS protects the wire, not the endpoint. The endpoint can still betray you.
- Notarization / store review is malware scanning, not security audit.
- Permission UIs that default to “allow” are click-through theater; OpenBSD’s lesson is secure by default.
- Allowlists by string match (URLs, paths, command names) are bypass-prone; use unforgeable handles.
- “We use a sandbox” without naming the kernel primitive (seccomp, sandbox-exec, AppContainer, namespaces) is marketing.
- Boolean permissions (
network: true) are ambient authority renamed. - Prompt-engineering defenses against prompt injection are not a security boundary.
- High test count is not high coverage; SQLite’s MC/DC is the bar, not unit-test count.
- “Written in Rust” kills memory bugs, not logic bugs or design flaws.
- In-process isolation (Wasm-in-process, V8 isolates) is a softer boundary than OS-process isolation; Spectre forced Chrome to learn this.
Suggested Locara distillation (the one-pager)
- Tiny privileged broker, written in Rust, audited line-by-line (qmail).
- Default-deny manifest with kernel-enforced capability scopes per plugin (OpenBSD
pledge+ macOS entitlements + ocap theory). - Unforgeable handles, never strings, across the IPC boundary (seL4, Plan 9, ocap).
- Per-tool-call capability scoping for AI agent loops, not per-session (lesson from MCP/Copilot breaches).
- OS-process isolation per plugin where possible, with seccomp/sandbox-exec/AppContainer profiles (Chrome).
- Typed IPC schema with fuzzed parsers; anomaly testing for capability code (SQLite, Mojo).
- Treat the webview and the model as adversarial renderers; broker validates everything.
- Plan 9 namespacing for plugin worlds: only what was granted exists for that plugin.
- Honesty in the threat model: code signing, notarization, and prompt filters are not security boundaries.
References (canonical primary sources)
- DJB, qmail thoughts,
cr.yp.to/qmail/qmailsec-20071101.pdf - OpenBSD
pledge(2),unveil(2)manpages;openbsd.org/innovations.html - Klein et al., SOSP 2009 (seL4 verification);
sel4.systems/About/seL4-whitepaper.pdf sqlite.org/testing.html- Reis et al., USENIX Security 2019 (Site Isolation);
chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox.md - Hardy, Confused Deputy, 1988; Miller PhD thesis 2006; Shapiro EROS SOSP 1999
- Matt Miller, BlueHat IL 2019 (70% memory safety);
security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html - Apple App Sandbox Design Guide; Wardle, Art of Mac Malware
- Pike et al., Plan 9, USENIX 1995; Use of Name Spaces in Plan 9, 1992
- Greshake et al., AISec 2023 (arXiv:2302.12173);
invariantlabs.ai/blog/mcp-github-vulnerability; Microsoft MSRC CVE-2025-32711; Salt Labs ChatGPT plugins disclosure 2024