You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
capsec implements 6 of 8 Saltzer & Schroeder design principles. The two it partially meets — complete mediation (#3) and least common mechanism (#7) — share the same root cause: Rust's standard library grants ambient authority by default. Any function can call std::fs::read() without asking permission. capsec can't remove that ability — only a compiler or language change can.
This issue outlines three progressively ambitious approaches to closing that gap.
A dylint or rustc_private lint that flags std::fs/std::net/std::env/std::process calls in functions that don't have Has<P> bounds. Teams that enable #[deny(capsec::ambient_authority)] get compile-time enforcement.
This is not complete mediation in Saltzer & Schroeder's sense — the check is opt-in. But it's the practical maximum within Rust's current architecture.
Status: RFC filed as #43 with three sub-options (raw rustc_private, dylint, clippy.toml fallback).
Impact: Gets capsec to ~7/8 principles. Ships without any upstream Rust changes.
Option 2: Rust RFC — authority tokens in std
The ambient-authority crate (Dan Gohman, Bytecode Alliance) already proposed the pattern: ambient-authority functions take an AmbientAuthority token parameter.
// Current std (ambient authority — any code can call this)let data = std::fs::read("secret.txt")?;// Proposed (capability-gated — requires explicit authority)let data = std::fs::read("secret.txt",ambient_authority())?;
If std adopted this convention, complete mediation would be built into the language. The key arguments:
Why this is realistic:
The Bytecode Alliance already wants this for WASI/Wasmtime — cap-std proves the API design works at scale
Rust RFC #1631 (pure functions / effect system) was closed with consensus: "pursue capability approaches" rather than a pure fn keyword
The keyword-generics initiative is discussing effect-like systems — authority tokens fit naturally
An edition boundary (Rust 2027?) could introduce the new APIs without breaking existing code — the old APIs would be deprecated, not removed
Cargo Scan (ESOP 2026) empirical data shows 3,434/10,000 top crates are already effect-free — most code wouldn't need any authority tokens at all
What capsec brings to the RFC:
Cap<P> / Has<P> is a working prototype of what authority-gated std APIs would look like
13 Lean 4 soundness theorems formally verify the permission lattice — machine-checked proof that the design is sound
90+ test adversarial security suite documenting every evasion vector — shows exactly what the current approach can and can't catch
Resource/pure crate classification (already implemented) demonstrates that the ecosystem can be partitioned
Production-tested across a real workspace with CI integration, pre-commit hooks, and SARIF output
What the RFC would propose:
Add an AmbientAuthority zero-sized token type to std (or core)
Add _with_authority variants of std::fs, std::net, std::env, std::process functions that require the token
In a future edition, deprecate the ambient variants in favor of the authority-gated variants
Provide ambient_authority() as the bootstrap function (equivalent to capsec's CapRoot::root())
Let the ecosystem build finer-grained capability systems (like capsec's Cap<P>) on top of the coarse AmbientAuthority foundation
Impact: Gets Rust to 8/8 Saltzer & Schroeder principles. Every Rust program would have a single auditable point where ambient authority enters the system.
Option 3: Compiler flag for capability-restricted compilation
A cargo/rustc feature that restricts which std modules are linkable based on declared capabilities:
This would work like #![no_std] but finer-grained — #![no_std_fs], #![no_std_net], etc. A crate marked pure simply cannot link against std::fs at all, enforced by the compiler.
Why this is harder:
Requires changes to Rust's module resolution and linking
std is currently monolithic — you get all of it or none of it (no_std)
Splitting std into capability-gated modules is a massive undertaking
Would need coordination with the libs team, compiler team, and cargo team
Why it might happen anyway:
The no_std ecosystem already demonstrates demand for partial std access
WASI's capability model requires exactly this kind of module-level gating
The modular std discussion has been ongoing since 2018 (see std-aware cargo RFC)
Impact: Complete mediation enforced by the compiler. The dream state — but requires Rust project buy-in and years of work.
Context
capsec implements 6 of 8 Saltzer & Schroeder design principles. The two it partially meets — complete mediation (#3) and least common mechanism (#7) — share the same root cause: Rust's standard library grants ambient authority by default. Any function can call
std::fs::read()without asking permission. capsec can't remove that ability — only a compiler or language change can.This issue outlines three progressively ambitious approaches to closing that gap.
Option 1: Lint plugin (buildable now)
Issue: #43
A
dylintorrustc_privatelint that flagsstd::fs/std::net/std::env/std::processcalls in functions that don't haveHas<P>bounds. Teams that enable#[deny(capsec::ambient_authority)]get compile-time enforcement.This is not complete mediation in Saltzer & Schroeder's sense — the check is opt-in. But it's the practical maximum within Rust's current architecture.
Status: RFC filed as #43 with three sub-options (raw
rustc_private, dylint,clippy.tomlfallback).Impact: Gets capsec to ~7/8 principles. Ships without any upstream Rust changes.
Option 2: Rust RFC — authority tokens in
stdThe
ambient-authoritycrate (Dan Gohman, Bytecode Alliance) already proposed the pattern: ambient-authority functions take anAmbientAuthoritytoken parameter.If
stdadopted this convention, complete mediation would be built into the language. The key arguments:Why this is realistic:
cap-stdproves the API design works at scalepure fnkeywordWhat capsec brings to the RFC:
Cap<P>/Has<P>is a working prototype of what authority-gatedstdAPIs would look likeWhat the RFC would propose:
AmbientAuthorityzero-sized token type tostd(orcore)_with_authorityvariants ofstd::fs,std::net,std::env,std::processfunctions that require the tokenambient_authority()as the bootstrap function (equivalent to capsec'sCapRoot::root())Cap<P>) on top of the coarseAmbientAuthorityfoundationImpact: Gets Rust to 8/8 Saltzer & Schroeder principles. Every Rust program would have a single auditable point where ambient authority enters the system.
Option 3: Compiler flag for capability-restricted compilation
A
cargo/rustcfeature that restricts whichstdmodules are linkable based on declared capabilities:This would work like
#![no_std]but finer-grained —#![no_std_fs],#![no_std_net], etc. A crate markedpuresimply cannot link againststd::fsat all, enforced by the compiler.Why this is harder:
stdis currently monolithic — you get all of it or none of it (no_std)stdinto capability-gated modules is a massive undertakingWhy it might happen anyway:
no_stdecosystem already demonstrates demand for partialstdaccessstddiscussion has been ongoing since 2018 (see std-aware cargo RFC)Impact: Complete mediation enforced by the compiler. The dream state — but requires Rust project buy-in and years of work.
Recommended sequence
AmbientAuthoritytokens instd— cite the lint plugin's adoption data as evidence of demandstdworkReferences
proofs/Capsec/Soundness.lean— 13 machine-verified theoremscrates/capsec-tests/tests/— 90+ tests documenting evasion vectors