-
Notifications
You must be signed in to change notification settings - Fork 1
Description
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 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-stdproves the API design works at scale - Rust RFC #1631 (pure functions / effect system) was closed with consensus: "pursue capability approaches" rather than a
pure fnkeyword - 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-gatedstdAPIs 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
AmbientAuthorityzero-sized token type tostd(orcore) - Add
_with_authorityvariants ofstd::fs,std::net,std::env,std::processfunctions 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'sCapRoot::root()) - Let the ecosystem build finer-grained capability systems (like capsec's
Cap<P>) on top of the coarseAmbientAuthorityfoundation
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:
# Cargo.toml
[package.metadata.capsec]
classification = "pure" # compiler rejects std::fs/net/env/process importsThis 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
stdis currently monolithic — you get all of it or none of it (no_std)- Splitting
stdinto 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_stdecosystem already demonstrates demand for partialstdaccess - WASI's capability model requires exactly this kind of module-level gating
- The modular
stddiscussion 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
- Now: Ship the lint plugin (Option 1 / RFC: Rustc lint plugin for ambient authority detection #43) — proves the concept, provides immediate value
- Next: Write a pre-RFC blog post citing capsec's Lean proofs, adversarial suite, and Cargo Scan data — build community support
- Then: Submit a formal Rust RFC (Option 2) proposing
AmbientAuthoritytokens instd— cite the lint plugin's adoption data as evidence of demand - Long-term: If the RFC is accepted, Option 3 becomes a natural follow-on as part of modular
stdwork
References
- Saltzer & Schroeder (1975), The Protection of Information in Computer Systems — Design Principles build: add capsec to CI #3 (Complete Mediation) and feat: implement Has<A> + Has<B> for tuple Cap<(A, B)> via macro-generated concrete impls #7 (Least Common Mechanism)
- ambient-authority crate — Dan Gohman's authority token pattern
- cap-std — Bytecode Alliance's capability-oriented std replacement
- Rust RFC #1631 — Pure functions / effect system discussion (closed: "pursue capability approaches")
- Cargo Scan (ESOP 2026) — 3,434/10,000 top crates are effect-free
- std-aware cargo RFC #2647 — modular std discussion
- capsec Lean 4 proofs:
proofs/Capsec/Soundness.lean— 13 machine-verified theorems - capsec adversarial suite:
crates/capsec-tests/tests/— 90+ tests documenting evasion vectors - Lint plugin RFC: RFC: Rustc lint plugin for ambient authority detection #43