nip/docs/cas-security-architecture.md

146 lines
5.0 KiB
Markdown

# 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:**
```nim
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:
```bash
# 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:**
```nim
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