Volt Docs

Security Model

Volt implements defense-in-depth using Linux-native security primitives. Every workload runs under multiple isolation layers — Landlock LSM for filesystem access control, seccomp for syscall filtering, Linux capabilities for privilege restriction, and kernel namespaces for resource isolation. No third-party security agents. No daemon-level trust. Just the kernel.

Defense in Depth

┌─────────────────────────────────────────────────────────────────┐
│                      Workload Process                          │
└──────────────────────────┬──────────────────────────────────────┘
                           │
          ┌────────────────┼────────────────┐
          │                │                │
   ┌──────▼──────┐  ┌─────▼──────┐  ┌──────▼──────┐
   │  Landlock   │  │  Seccomp  │  │ Capabilities│
   │  LSM rules  │  │  BPF filter│  │  drop ALL   │
   │  per-path   │  │  per-call  │  │  grant few  │
   └──────┬──────┘  └─────┬──────┘  └──────┬──────┘
          │                │                │
   ┌──────▼────────────────▼────────────────▼──────┐
   │               Kernel Namespaces                │
   │     PID · Mount · Net · User · UTS · IPC      │
   └───────────────────────┬───────────────────────┘
                           │
   ┌───────────────────────▼───────────────────────┐
   │              cgroups v2                       │
   │     CPU · Memory · I/O · PIDs limits          │
   └───────────────────────┬───────────────────────┘
                           │
   ┌───────────────────────▼───────────────────────┐
   │              Linux Kernel                      │
   │    systemd-nspawn · KVM · nftables            │
   └───────────────────────────────────────────────┘

Each layer is independent. Compromising one does not disable the others. A workload that escapes its namespace still faces Landlock restrictions, seccomp filters, and dropped capabilities.

Landlock LSM — Filesystem Access Control

Volt uses Landlock LSM as its primary mandatory access control framework. Landlock is a stackable Linux Security Module available since kernel 5.13 that allows unprivileged processes to restrict their own filesystem access — no root configuration required.

Why Landlock?

Unlike kernel-module-based MACs, Landlock is built into the Linux kernel, requires no policy daemon, and can be applied per-workload without system-wide configuration. It aligns with Volt's philosophy: use what the kernel provides, add nothing extra.

How Volt Uses Landlock

Every Voltainer container and Voltvisor VM gets a Landlock ruleset applied at launch. Profiles are defined in /etc/volt/profiles/:

/etc/volt/profiles/ ├── webserver.landlock ← Read /var/www, write /tmp only ├── database.landlock ← Read/write /var/lib/postgres only ├── default.landlock ← Restrictive baseline for all workloads └── custom-app.landlock ← User-defined profile
# Apply a Landlock profile to a container
sudo volt container create myapp --landlock webserver

# Inspect active Landlock rules
sudo volt security inspect myapp --landlock

# Create a custom Landlock profile
sudo volt security profile create my-profile \
  --allow-read /app,/usr/lib \
  --allow-write /tmp,/var/log/app \
  --deny-execute /tmp

Landlock Rulesets

Access RightDescriptionDefault
LANDLOCK_ACCESS_FS_READ_FILERead file contentsAllowed (select paths)
LANDLOCK_ACCESS_FS_WRITE_FILEWrite to filesDenied (except /tmp)
LANDLOCK_ACCESS_FS_EXECUTEExecute filesAllowed (select paths)
LANDLOCK_ACCESS_FS_READ_DIRList directory contentsAllowed (select paths)
LANDLOCK_ACCESS_FS_MAKE_REGCreate regular filesDenied (except /tmp)

Seccomp — Syscall Filtering

Volt applies seccomp-BPF (Berkeley Packet Filter) profiles to every workload, restricting which system calls the process can invoke. This reduces the kernel attack surface available to compromised workloads.

Built-in Profiles

ProfileSyscalls BlockedUse Case
strict.json ~200 blocked, ~60 allowed Stateless web services, static content
default-plus-networking.json ~150 blocked, ~110 allowed Network services, databases
permissive.json ~50 blocked (dangerous only) Development, debugging
# Apply a seccomp profile at creation
sudo volt container create myapp --seccomp strict

# Inspect active seccomp filters
sudo volt security inspect myapp --seccomp

# Audit mode — log violations without killing
sudo volt container create myapp --seccomp strict --seccomp-audit

Dangerous Syscalls Always Blocked

Regardless of profile, these syscalls are always filtered:

Linux Capabilities — Minimal Privilege

Volt drops all Linux capabilities by default and adds back only what each workload needs. This follows the principle of least privilege — a web server doesn't need CAP_SYS_ADMIN.

Default Capability Sets

Workload TypeCapabilities GrantedEverything Else
Web server NET_BIND_SERVICE Dropped
Database DAC_OVERRIDE, CHOWN, FOWNER Dropped
Network service NET_BIND_SERVICE, NET_RAW Dropped
Minimal (default) None All dropped
# Create with specific capabilities
sudo volt container create myapp \
  --cap-add NET_BIND_SERVICE \
  --cap-add CHOWN

# Inspect granted capabilities
sudo volt security inspect myapp --capabilities

# Drop all capabilities (already default, but explicit)
sudo volt container create myapp --cap-drop ALL
systemd-nspawn Integration

Capability restrictions are passed directly to systemd-nspawn via --capability= and --drop-capability= flags in the generated .nspawn configuration files.

Namespace Isolation

Every Voltainer container runs in its own set of Linux kernel namespaces, providing complete process, network, and filesystem isolation from the host and other containers.

Namespace Types

NamespaceIsolatesEffect
PID Process IDs Container sees only its own processes; PID 1 is the container init
Mount Filesystem mounts Container has its own mount tree; host mounts invisible
Network Network stack Container gets its own interfaces, IP addresses, routing table
User UID/GID mappings Root inside container maps to unprivileged user on host
UTS Hostname Container can set its own hostname without affecting host
IPC Inter-process communication Shared memory, semaphores, message queues isolated per container
# Inspect namespace configuration
sudo volt security inspect myapp --namespaces

# Verify PID isolation — container only sees its own processes
sudo volt container exec myapp -- ps aux

# User namespace mapping — root inside is nobody outside
sudo volt container exec myapp -- id
# uid=0(root) inside → uid=65534(nobody) on host

User Namespace UID Mapping

Volt uses systemd-nspawn's --private-users= to map UIDs inside the container to unprivileged ranges on the host:

  Container UIDs          Host UIDs
  ─────────────          ─────────
  0    (root)    →       65536  (unprivileged)
  1    (daemon)  →       65537
  1000 (user)    →       66536
  ...                    ...

  Even if a process escapes the container as "root",
  it's UID 65536 on the host — no privileges.

CAS Integrity — Stellarium Verification

Stellarium, Volt's content-addressed storage system, provides cryptographic integrity guarantees for all stored images and blobs. Every object is stored by its SHA256 hash — if the content changes, the address changes.

Integrity Guarantees

# Verify integrity of all CAS objects
sudo volt cas verify
# ✓ 1,247 objects verified, 0 corrupted

# Verify a specific image
sudo volt cas verify --ref myapp-v2

# Show hash chain for a reference
sudo volt cas inspect myapp-v2 --show-hashes
Supply Chain Security

Because CAS stores content by hash, you can verify that the exact image you audited is the exact image running in production. Hash the running rootfs and compare against the CAS ref — any difference means the image was modified.

Network Isolation — volt-net Bridge

Volt isolates container networking using volt-net bridge interfaces managed through nftables. Each workload gets its own virtual ethernet pair, and inter-container traffic is denied by default.

Network Architecture

┌────────────┐  ┌────────────┐  ┌────────────┐
│ Container A│  │ Container B│  │ Container C│
│ 10.42.0.2  │  │ 10.42.0.3  │  │ 10.42.1.2  │
└──────┬─────┘  └──────┬─────┘  └──────┬─────┘
   veth-a           veth-b          veth-c
       │                │               │
  ┌────▼────────────────▼───┐   ┌───────▼───────┐
  │    volt-net0 bridge     │   │ volt-net1    │
  │    10.42.0.0/24         │   │ 10.42.1.0/24  │
  └────────────┬────────────┘   └───────┬───────┘
               │                        │
  ┌────────────▼────────────────────────▼───────┐
  │              nftables firewall               │
  │    Per-workload ingress/egress rules        │
  │    Default: deny inter-bridge traffic       │
  └─────────────────────┬──────────────────────┘
                        │
                   Host network

Network Policies

# Isolate a container — no network access
sudo volt container create myapp --network none

# Allow specific inter-container communication
sudo volt network policy create \
  --from web --to db --port 5432 --protocol tcp --action allow

# List active network policies
sudo volt network policy list

# Inspect firewall rules for a workload
sudo volt security inspect myapp --firewall

Resource Limits — cgroups v2

Volt uses cgroups v2 (unified hierarchy) to enforce hard resource limits on every workload. This prevents resource exhaustion attacks and noisy-neighbor problems.

Enforced Limits

ResourceControllerDefaultConfigurable
CPU cpu.max No limit (fair share) --cpu-limit 200%
Memory memory.max 512 MiB --memory 2G
Memory (swap) memory.swap.max 0 (no swap) --memory-swap 1G
I/O bandwidth io.max No limit --io-limit 50M
PIDs pids.max 256 --pids-limit 1024
# Create with resource limits
sudo volt container create myapp \
  --memory 1G \
  --cpu-limit 100% \
  --pids-limit 512

# Update limits on a running workload
sudo volt container update myapp --memory 2G

# Monitor resource usage
sudo volt ps --resources
sudo volt monitor myapp
OOM Protection

When a container exceeds its memory limit, the kernel's OOM killer terminates processes within that container's cgroup — not processes from other containers or the host. Isolation is maintained even during resource exhaustion.

Neutron Stardust — microVM Isolation

For workloads requiring hardware-level isolation beyond containers, Voltvisor uses Neutron Stardust as its microVMM. Neutron Stardust provides lightweight KVM-based virtual machines with minimal attack surface — a purpose-built VMM with only the devices and emulation needed for the workload.

microVM Security Properties

# Create a microVM with Neutron Stardust
sudo volt vm create secure-worker \
  --engine stardust \
  --memory 256M \
  --vcpus 1

# Ephemeral microVM — destroyed on stop
sudo volt vm create ephemeral-task \
  --engine stardust \
  --ephemeral

Security Best Practices

1. Use the Strictest Profile That Works

Start with --seccomp strict and --landlock default, then relax only what your application needs. Volt's audit mode helps identify required syscalls and paths:

# Run with audit mode to discover required syscalls
sudo volt container create myapp --seccomp strict --seccomp-audit
sudo volt logs myapp --filter seccomp
# Review violations, add only what's needed to a custom profile

2. Enable User Namespaces

Always use --private-users (enabled by default) so that root inside the container maps to an unprivileged user on the host. Never run containers with --private-users=no in production.

3. Restrict Network Access

Use --network none for workloads that don't need network access. For those that do, define explicit network policies rather than relying on defaults:

# Database container — only accessible from the web tier
sudo volt container create db --network none
sudo volt network policy create --from web --to db --port 5432 --action allow

4. Set Resource Limits on Everything

Always set --memory and --pids-limit. Unbounded workloads can starve the host and impact other containers:

sudo volt container create myapp \
  --memory 512M \
  --pids-limit 256 \
  --cpu-limit 100%

5. Verify CAS Integrity Regularly

Run volt cas verify on a schedule (cron or systemd timer) to detect storage corruption or tampering:

# Add to a systemd timer or cron
sudo volt cas verify --quiet || notify-admin "CAS integrity check failed"

6. Keep the Host Kernel Updated

Volt's security depends on kernel features (Landlock, seccomp, namespaces, cgroups v2). Kernel vulnerabilities can undermine all isolation layers. Keep the host kernel current and enable automatic security updates.

7. Audit Security Configuration

# Full security audit of a workload
sudo volt security audit myapp

# System-wide security overview
sudo volt security audit --all

# Check for common misconfigurations
sudo volt security check

Security Layer Summary

LayerMechanismProtects Against
FilesystemLandlock LSMUnauthorized file read/write/execute
Syscallsseccomp-BPFKernel exploit via dangerous syscalls
PrivilegesLinux capabilitiesPrivilege escalation
ProcessPID namespaceCross-container process visibility
FilesystemMount namespaceHost filesystem access
NetworkNetwork namespace + nftablesUnauthorized network access
IdentityUser namespaceRoot escape to host
Resourcescgroups v2Resource exhaustion / DoS
IntegrityStellarium CAS (SHA256)Image tampering / corruption
VM isolationNeutron Stardust / KVMKernel-level container escape