zeroclaw/docs/agnostic-security.md

9.7 KiB

Agnostic Security: Zero Impact on Portability

⚠️ Status: Proposal / Roadmap

This document describes proposed approaches and may include hypothetical commands or config. For current runtime behavior, see config-reference.md, operations-runbook.md, and troubleshooting.md.

Core Question: Will security features break...

  1. Fast cross-compilation builds?
  2. Pluggable architecture (swap anything)?
  3. Hardware agnosticism (ARM, x86, RISC-V)?
  4. Small hardware support (<5MB RAM, $10 boards)?

Answer: NO to all — Security is designed as optional feature flags with platform-specific conditional compilation.


1. Build Speed: Feature-Gated Security

Cargo.toml: Security Features Behind Features

[features]
default = ["basic-security"]

# Basic security (always on, zero overhead)
basic-security = []

# Platform-specific sandboxing (opt-in per platform)
sandbox-landlock = []   # Linux only
sandbox-firejail = []  # Linux only
sandbox-bubblewrap = []# macOS/Linux
sandbox-docker = []    # All platforms (heavy)

# Full security suite (for production builds)
security-full = [
    "basic-security",
    "sandbox-landlock",
    "resource-monitoring",
    "audit-logging",
]

# Resource & audit monitoring
resource-monitoring = []
audit-logging = []

# Development builds (fastest, no extra deps)
dev = []

Build Commands (Choose Your Profile)

# Ultra-fast dev build (no security extras)
cargo build --profile dev

# Release build with basic security (default)
cargo build --release
# → Includes: allowlist, path blocking, injection protection
# → Excludes: Landlock, Firejail, audit logging

# Production build with full security
cargo build --release --features security-full
# → Includes: Everything

# Platform-specific sandbox only
cargo build --release --features sandbox-landlock  # Linux
cargo build --release --features sandbox-docker    # All platforms

Conditional Compilation: Zero Overhead When Disabled

// src/security/mod.rs

#[cfg(feature = "sandbox-landlock")]
mod landlock;
#[cfg(feature = "sandbox-landlock")]
pub use landlock::LandlockSandbox;

#[cfg(feature = "sandbox-firejail")]
mod firejail;
#[cfg(feature = "sandbox-firejail")]
pub use firejail::FirejailSandbox;

// Always-include basic security (no feature flag)
pub mod policy;  // allowlist, path blocking, injection protection

Result: When features are disabled, the code isn't even compiled — zero binary bloat.


2. Pluggable Architecture: Security Is a Trait Too

Security Backend Trait (Swappable Like Everything Else)

// src/security/traits.rs

#[async_trait]
pub trait Sandbox: Send + Sync {
    /// Wrap a command with sandbox protection
    fn wrap_command(&self, cmd: &mut std::process::Command) -> std::io::Result<()>;

    /// Check if sandbox is available on this platform
    fn is_available(&self) -> bool;

    /// Human-readable name
    fn name(&self) -> &str;
}

// No-op sandbox (always available)
pub struct NoopSandbox;

impl Sandbox for NoopSandbox {
    fn wrap_command(&self, _cmd: &mut std::process::Command) -> std::io::Result<()> {
        Ok(())  // Pass through unchanged
    }

    fn is_available(&self) -> bool { true }
    fn name(&self) -> &str { "none" }
}

Factory Pattern: Auto-Select Based on Features

// src/security/factory.rs

pub fn create_sandbox() -> Box<dyn Sandbox> {
    #[cfg(feature = "sandbox-landlock")]
    {
        if LandlockSandbox::is_available() {
            return Box::new(LandlockSandbox::new());
        }
    }

    #[cfg(feature = "sandbox-firejail")]
    {
        if FirejailSandbox::is_available() {
            return Box::new(FirejailSandbox::new());
        }
    }

    #[cfg(feature = "sandbox-bubblewrap")]
    {
        if BubblewrapSandbox::is_available() {
            return Box::new(BubblewrapSandbox::new());
        }
    }

    #[cfg(feature = "sandbox-docker")]
    {
        if DockerSandbox::is_available() {
            return Box::new(DockerSandbox::new());
        }
    }

    // Fallback: always available
    Box::new(NoopSandbox)
}

Just like providers, channels, and memory — security is pluggable!


3. Hardware Agnosticism: Same Binary, Different Platforms

Cross-Platform Behavior Matrix

Platform Builds On Runtime Behavior
Linux ARM (Raspberry Pi) Yes Landlock → None (graceful)
Linux x86_64 Yes Landlock → Firejail → None
macOS ARM (M1/M2) Yes Bubblewrap → None
macOS x86_64 Yes Bubblewrap → None
Windows ARM Yes None (app-layer)
Windows x86_64 Yes None (app-layer)
RISC-V Linux Yes Landlock → None

How It Works: Runtime Detection

// src/security/detect.rs

impl SandboxingStrategy {
    /// Choose best available sandbox AT RUNTIME
    pub fn detect() -> SandboxingStrategy {
        #[cfg(target_os = "linux")]
        {
            // Try Landlock first (kernel feature detection)
            if Self::probe_landlock() {
                return SandboxingStrategy::Landlock;
            }

            // Try Firejail (user-space tool detection)
            if Self::probe_firejail() {
                return SandboxingStrategy::Firejail;
            }
        }

        #[cfg(target_os = "macos")]
        {
            if Self::probe_bubblewrap() {
                return SandboxingStrategy::Bubblewrap;
            }
        }

        // Always available fallback
        SandboxingStrategy::ApplicationLayer
    }
}

Same binary runs everywhere — it just adapts its protection level based on what's available.


4. Small Hardware: Memory Impact Analysis

Binary Size Impact (Estimated)

Feature Code Size RAM Overhead Status
Base ZeroClaw 3.4MB <5MB Current
+ Landlock +50KB +100KB Linux 5.13+
+ Firejail wrapper +20KB +0KB (external) Linux + firejail
+ Memory monitoring +30KB +50KB All platforms
+ Audit logging +40KB +200KB (buffered) All platforms
Full security +140KB +350KB Still <6MB total

$10 Hardware Compatibility

Hardware RAM ZeroClaw (base) ZeroClaw (full security) Status
Raspberry Pi Zero 512MB 2% 2.5% Works
Orange Pi Zero 512MB 2% 2.5% Works
NanoPi NEO 256MB 4% 5% Works
C.H.I.P. 512MB 2% 2.5% Works
Rock64 1GB 1% 1.2% Works

Even with full security, ZeroClaw uses <5% of RAM on $10 boards.


5. Agnostic Swaps: Everything Remains Pluggable

ZeroClaw's Core Promise: Swap Anything

// Providers (already pluggable)
Box<dyn Provider>

// Channels (already pluggable)
Box<dyn Channel>

// Memory (already pluggable)
Box<dyn MemoryBackend>

// Tunnels (already pluggable)
Box<dyn Tunnel>

// NOW ALSO: Security (newly pluggable)
Box<dyn Sandbox>
Box<dyn Auditor>
Box<dyn ResourceMonitor>

Swap Security Backends via Config

# Use no sandbox (fastest, app-layer only)
[security.sandbox]
backend = "none"

# Use Landlock (Linux kernel LSM, native)
[security.sandbox]
backend = "landlock"

# Use Firejail (user-space, needs firejail installed)
[security.sandbox]
backend = "firejail"

# Use Docker (heaviest, most isolated)
[security.sandbox]
backend = "docker"

Just like swapping OpenAI for Gemini, or SQLite for PostgreSQL.


6. Dependency Impact: Minimal New Deps

Current Dependencies (for context)

reqwest, tokio, serde, anyhow, uuid, chrono, rusqlite,
axum, tracing, opentelemetry, ...

Security Feature Dependencies

Feature New Dependencies Platform
Landlock landlock crate (pure Rust) Linux only
Firejail None (external binary) Linux only
Bubblewrap None (external binary) macOS/Linux
Docker bollard crate (Docker API) All platforms
Memory monitoring None (std::alloc) All platforms
Audit logging None (already have hmac/sha2) All platforms

Result: Most features add zero new Rust dependencies — they either:

  1. Use pure-Rust crates (landlock)
  2. Wrap external binaries (Firejail, Bubblewrap)
  3. Use existing deps (hmac, sha2 already in Cargo.toml)

Summary: Core Value Propositions Preserved

Value Prop Before After (with security) Status
<5MB RAM <5MB <6MB (worst case) Preserved
<10ms startup <10ms <15ms (detection) Preserved
3.4MB binary 3.4MB 3.5MB (with all features) Preserved
ARM + x86 + RISC-V All All Preserved
$10 hardware Works Works Preserved
Pluggable everything Yes Yes (security too) Enhanced
Cross-platform Yes Yes Preserved

The Key: Feature Flags + Conditional Compilation

# Developer build (fastest, no extra features)
cargo build --profile dev

# Standard release (your current build)
cargo build --release

# Production with full security
cargo build --release --features security-full

# Target specific hardware
cargo build --release --target aarch64-unknown-linux-gnu  # Raspberry Pi
cargo build --release --target riscv64gc-unknown-linux-gnu # RISC-V
cargo build --release --target armv7-unknown-linux-gnueabihf  # ARMv7

Every target, every platform, every use case — still fast, still small, still agnostic.