feat(truman_fs): FUSE-based filesystem visibility with Rust daemon#5
Open
conroywhitney wants to merge 17 commits into
Open
feat(truman_fs): FUSE-based filesystem visibility with Rust daemon#5conroywhitney wants to merge 17 commits into
conroywhitney wants to merge 17 commits into
Conversation
Spec-driven development for the FUSE visibility layer: - proposal.md: why FUSE, platform scope (macOS first) - specs/whitelist: 7 requirements for ETS-backed path whitelist - specs/fuse-visibility: 7 requirements for 404 principle - design.md: 6 key decisions (FUSE, ETS, Rust NIF, etc.) - tasks.md: 35 implementation tasks across 7 groups Also updates project.md with full Reify context and adopts "playground" terminology per established principle. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
TDD implementation of core whitelist functionality: - new/1 creates ETS-backed whitelist with initial paths - allowed?/2 checks path with prefix matching - Child paths automatically allowed under whitelisted directories - Rejects paths that share prefix but aren't true children 5 tests, all passing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
TDD implementation of add/remove operations: - add/2 inserts path into ETS (idempotent) - remove/2 deletes path from ETS (idempotent) 9 tests, all passing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
TDD implementation: - add_all/2 adds multiple paths atomically - remove_all/2 removes multiple paths atomically - list/1 returns all whitelisted paths Reordered functions to satisfy Credo (callees after callers). 14 tests, all passing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Closed
55e282b to
feb4f63
Compare
Architecture decisions: - Port over NIF for crash isolation - JSON over ETF for audit-first logging (human-readable logs) - macFUSE 5.1.3+ with FSKit backend (userspace, no kext on macOS 26) - Auditor in critical path (log first, parse second) Added: - native/truman_fused: Rust FUSE daemon skeleton with fuser + serde_json - protocol.rs: JSON message types with tests - Updated READMEs with architecture diagrams and API docs - Updated design.md with Decisions 4-7
truman_fsPort path validation logic from TrumanShell's Sandbox module,
renamed to Playground to match TrumanFS terminology ("playground,
not sandbox").
Uses Elixir's built-in Path.safe_relative/2 to protect against:
- Directory traversal attacks (../ sequences)
- Absolute paths outside playground
- Prefix confusion (/playground2 vs /playground)
Includes comprehensive tests covering:
- Basic path validation
- Traversal attacks
- Symlink handling
- Unicode paths
- Edge cases (empty, root, current directory)
All path operations should go through this module to ensure
consistent security behavior across the codebase.
SECURITY: Fixes path traversal vulnerability in allowed?/2. Before: normalize_path/1 only trimmed trailing slashes After: normalize_path/1 uses Path.expand() to resolve .. sequences - Whitelist now delegates boundary checks to Playground module - Updated moduledoc to document actual O(n) complexity - Added comprehensive security tests for path traversal attacks - Tests cover: basic traversal, nested traversal, unicode paths Attack vector that is now blocked: Whitelist: /home/user/projects Attack: /home/user/projects/../secrets/file.txt Result: Rejected (was: Allowed)
- new/1 and add_all/2 now use single :ets.insert/2 call (atomic) - remove_all/2 still sequential (ETS limitation, documented) - Added delete/1 for ETS table cleanup (prevents leaks in tests) - Updated docs to note atomicity guarantees
Update main.rs doc comments to correctly describe JSON protocol. Added note explaining audit-first logging rationale.
Comprehensive protocol.rs update: - Add base64 encoding for binary data fields (Vec<u8>) - Request::Write.data is now base64-encoded in JSON - Response::Ok.data is now base64-encoded in JSON - Ensures human-readable audit logs - Add MAX_MESSAGE_SIZE bounds check in recv() - 16 MiB limit prevents memory exhaustion - Protects against MongoBleed-style attacks (CVE-2025-14847) - Add comprehensive inline documentation - Wire format diagram - Design rationale (audit-first logging) - Doc comments on all types and fields - Update dependencies - Add base64 = "0.22" for binary encoding - Keep fuser = "0.15" (0.16 has macOS build regression) - Commit Cargo.lock for reproducible builds Tests added for base64 roundtrip serialization.
- Remove hello/0 boilerplate function and test - Add async: true to test files for parallel execution - Update TrumanFs moduledoc with actual module descriptions
- Mark completed tasks from this PR: - Whitelist: delete/1, path traversal fix, Playground module - Protocol: base64, bounds check, inline docs - Documentation: module docs, README - Add future work notes from LLM review: - fuser 0.16 upgrade pending (macOS fix in PR) - FUSE integration tests (blocked on daemon impl) - GenServer wrapper consideration - O(n) optimization ideas - Persistent config notes - Fix ETF → JSON in section 5.2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TrumanFS provides whitelist-based filesystem visibility control via FUSE. Files outside the whitelist literally don't exist (404 principle - ENOENT, not EACCES).
What's included
TrumanFs.Whitelist module - ETS-backed whitelist with O(1) lookups
new/1,add/2,remove/2,add_all/2,remove_all/2,list/1,allowed?/2/projectsallows/projects/app/lib/main.exRust FUSE daemon (
native/truman_fused)fusercrate for FUSE operationsArchitecture decisions documented
Architecture
What's next
TrumanFs.Protocol)TrumanFs.Port)Test plan
mix test- Whitelist module tests passcargo test- Rust protocol tests pass🤖 Generated with Claude Code