nip/docs/cas-security-architecture.md

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 555 back
  • 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:

  1. Merkle tree verification (cryptographic integrity)
  2. User namespaces (kernel-enforced isolation)
  3. 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