5.0 KiB
CAS Security Architecture
The Problem with chmod-based Protection
User-Mode Reality Check
In user-space (~/.local/share/nexus/cas/), chmod 555 is security theater, not security:
- User owns the inode → User can
chmod 700, modify,chmod 555back - No privilege separation → Cannot protect user from themselves with POSIX permissions
- xattr immutable flag → Requires root/CAP_LINUX_IMMUTABLE (not available to regular users)
Verdict: chmod 555 is a "Do Not Touch" sign written in pencil. It prevents accidental deletion but provides zero security against intentional tampering.
The Real Security Model
1. Merkle Tree Verification (Primary Defense)
The CAS Merkle tree is the source of truth, not filesystem permissions.
Filesystem = "Dirty" Physical Layer (untrusted)
Merkle Tree = "Sacred" Logical Layer (trusted)
Strategy:
- Lazy Verification: Verify hash before executing/grafting critical binaries
- Tainted Flag: Hash mismatch → refuse to run OR auto-heal (re-download/re-link)
- Continuous Integrity: Periodic background verification of CAS contents
Implementation:
proc verifyAndExecute*(cas: CasManager, hash: string): Result[void, CasError] =
# 1. Retrieve chunk
let data = cas.retrieveChunk(hash)
# 2. Verify hash matches
let calculatedHash = calculateXxh3(data)
if calculatedHash != hash:
# Hash mismatch - chunk is tainted
return err(CasError(
code: IntegrityViolation,
msg: "Chunk integrity violation - auto-healing",
objectHash: hash
))
# 3. Execute only if verified
return ok()
2. User Namespaces (Runtime Isolation)
For execution environments, use Linux User Namespaces to enforce read-only access:
# Create mount namespace with read-only CAS
unshare --mount --map-root-user bash -c '
mount --bind -o ro ~/.local/share/nexus/cas ~/.local/share/nexus/cas
exec /path/to/application
'
Benefits:
- Kernel-enforced read-only view (not bypassable by process)
- Even if app is compromised, cannot write to CAS
- Works without root privileges (user namespaces)
Implementation Strategy:
proc launchWithProtection*(cas: CasManager, executable: string): Result[Process, CasError] =
# 1. Create user namespace with read-only bind mount
# 2. Execute application inside namespace
# 3. Application sees CAS as truly read-only
3. System-Mode Protection (Root-Owned CAS)
For system-wide installations (/var/lib/nexus/cas/):
- Root owns files:
chown root:root,chmod 644/755 - Users in pkg-users group: Read-only access
- Daemon handles writes: Only privileged daemon can modify CAS
- Here chmod actually works: Users cannot change permissions they don't own
Hybrid Architecture
Storage Layer (Disk)
- Keep chmod 555 as UX guardrail (prevents accidental
rm) - Acknowledge it's not security - just convenience
- Real security comes from verification
Execution Layer (Runtime)
- User Namespaces: Bind-mount CAS as read-only for process tree
- Merkle Verification: Verify hashes before execution
- Auto-Healing: Re-download/re-link on integrity violation
System Mode
- Root ownership: Traditional POSIX permissions work here
- Daemon-mediated writes: Only privileged process modifies CAS
- User read-only access: Standard Unix security model
Implementation Priorities
Phase 1: Merkle Verification (CRITICAL)
✅ Already implemented: xxh3-128 hashing 🔧 TODO: Pre-execution verification 🔧 TODO: Auto-healing on integrity violation 🔧 TODO: Background integrity scanning
Phase 2: User Namespace Isolation (HIGH)
🔧 TODO: Launcher wrapper with mount namespaces 🔧 TODO: Read-only bind mount for CAS during execution 🔧 TODO: Integration with nippels namespace system
Phase 3: System Mode (MEDIUM)
🔧 TODO: Root-owned CAS for system installations 🔧 TODO: Privileged daemon for write operations 🔧 TODO: User group management
Security Guarantees
| Attack Vector | User Mode Defense | System Mode Defense |
|---|---|---|
| Accidental deletion | chmod 555 (UX) | root ownership |
| Intentional tampering | Merkle verification | root ownership + Merkle |
| Compromised app | User namespaces | User namespaces + root ownership |
| Supply chain attack | Signature verification | Signature verification |
| Bit rot / corruption | Merkle verification | Merkle verification |
Conclusion
Don't rely on chmod for security in user-mode. Use:
- Merkle tree verification (cryptographic integrity)
- User namespaces (kernel-enforced isolation)
- Root ownership (system-mode only)
The current chmod implementation remains as a UX feature (prevents accidents), but security comes from cryptographic verification and architectural isolation.
Document Version: 1.0 Last Updated: November 20, 2025 Status: Architecture Decision Record Credit: Analysis by Voxis Forge