Skip to main content

Security Model

Security Overview

Runner Codes is designed with security as a primary concern. Running untrusted code generated by LLMs requires multiple layers of isolation.

Security Architecture

Security Isolation Layers

Isolation Layers

Layer 1: Hardware Virtualization (KVM)

Firecracker uses Linux KVM for hardware-level virtualization:

  • Separate kernel: Each VM runs its own Linux kernel
  • Memory isolation: VM memory is isolated from host and other VMs
  • CPU isolation: Virtual CPUs separate from host CPUs

KVM Hardware Isolation

Layer 2: Minimal Device Model

Firecracker implements only essential devices:

DevicePurposeSecurity Impact
virtio-blockStorageRead-only possible
virtio-netNetworkDisabled by default
virtio-vsockCommunicationHost-initiated only
SerialDebugOutput only
note

Fewer devices = smaller attack surface. Firecracker is only ~50,000 lines of Rust code.

Layer 3: Network Isolation

VMs have no network access by default:

Network Isolation

Benefits:

  • No data exfiltration via network
  • No downloading malware
  • No C2 communication
  • No lateral movement

Layer 4: Resource Limits

Each VM has enforced limits:

ResourceDefaultConfigurable
vCPUs1Yes
Memory512 MiBYes
Timeout10 secondsYes
DiskRead-write, ephemeralNo

Threat Model

Threats Mitigated

VM Escape

Threat: Malicious code escapes VM to host

Mitigation: Hardware virtualization via KVM provides strong isolation. Guest code cannot access host memory or processes.

Data Exfiltration

Threat: Code sends sensitive data to external servers

Mitigation: No network access. The only communication channel is vsock, which is controlled by the host agent.

Resource Exhaustion

Threat: Code consumes excessive resources

Mitigation:

  • CPU: Limited vCPUs (default 1)
  • Memory: Capped at 512 MiB
  • Time: Execution timeout (default 10s)
  • Disk: Ephemeral, destroyed after execution

Cryptocurrency Mining

Threat: Code mines cryptocurrency

Mitigation:

  • Timeout limits execution time
  • No network prevents pool connection
  • VM destroyed after execution

Lateral Movement

Threat: Code attacks other systems

Mitigation: No network access. Cannot reach other VMs or external systems.

Residual Risks

warning

These risks are not fully mitigated in the current PoC:

RiskImpactRecommendation
KVM vulnerabilitiesVM escapeKeep kernel updated
Firecracker vulnerabilitiesVM escapeKeep Firecracker updated
Side-channel attacksInformation leakDisable SMT, use jailer
Timing attacksInformation leakNormalize execution time

Production Hardening

Enable Jailer

The Firecracker jailer provides additional isolation:

Run Firecracker with jailer
jailer --id ${VM_ID} \
--exec-file /usr/bin/firecracker \
--uid 10000 \
--gid 10000 \
--chroot-base-dir /srv/jailer \
--daemonize

Features:

  • chroot: Filesystem isolation
  • uid/gid: Run as non-root
  • seccomp: System call filtering
  • cgroups: Resource control

Seccomp Profiles

Enable strict seccomp filtering:

Seccomp filter configuration
{
"default_action": "trap",
"filter_action": "allow",
"filters": [
{ "syscall": "read" },
{ "syscall": "write" },
{ "syscall": "exit" },
{ "syscall": "exit_group" }
]
}

Disable SMT

Simultaneous Multi-Threading (SMT) can enable side-channel attacks:

Disable SMT in VM configuration
{
"vcpu_count": 1,
"mem_size_mib": 512,
"smt": false
}

Read-Only Rootfs

For maximum isolation, use read-only rootfs:

Read-only rootfs configuration
{
"drive_id": "rootfs",
"path_on_host": "/srv/firecracker/rootfs.ext4",
"is_root_device": true,
"is_read_only": true
}
note

Read-only rootfs requires a writable tmpfs for /tmp. Configure in kernel boot args.

Input Validation

Code Validation

Before executing code, validate:

Job validation function
func validateJob(job Job) error {
// Check trace_id format
if !validTraceID(job.TraceID) {
return errors.New("invalid trace_id")
}

// Check language
validLangs := map[string]bool{
"python": true, "node": true, "go": true,
"rust": true, "bash": true,
}
if !validLangs[job.Lang] {
return errors.New("unsupported language")
}

// Check code size
if len(job.Code) > 1024*1024 { // 1MB limit
return errors.New("code too large")
}

// Check timeout
if job.Timeout <= 0 || job.Timeout > 300 {
return errors.New("invalid timeout")
}

return nil
}

Dangerous Pattern Detection

Optionally scan for dangerous patterns:

Dangerous pattern detection
var dangerousPatterns = []string{
`rm\s+-rf\s+/`, // rm -rf /
`dd\s+if=.*of=/dev`, // dd to devices
`:(){ :|:& };:`, // Fork bomb
`while.*true.*do`, // Infinite loops (bash)
}

func scanDangerousPatterns(code string) []string {
var matches []string
for _, pattern := range dangerousPatterns {
re := regexp.MustCompile(pattern)
if re.MatchString(code) {
matches = append(matches, pattern)
}
}
return matches
}
tip

Pattern detection is defense-in-depth. The VM isolation is the primary security control.

Logging and Monitoring

Security Events

Log these security-relevant events:

Security event structure
type SecurityEvent struct {
Timestamp time.Time `json:"timestamp"`
EventType string `json:"event_type"`
TraceID string `json:"trace_id"`
Details string `json:"details"`
}

// Events to log:
// - VM_START: VM started
// - VM_STOP: VM stopped (normal)
// - VM_TIMEOUT: Execution timeout
// - VM_OOM: Out of memory
// - VALIDATION_FAIL: Input validation failed
// - DANGEROUS_PATTERN: Dangerous code pattern detected

Metrics

Collect security metrics:

MetricDescription
vm_timeouts_totalExecutions killed by timeout
vm_oom_totalOut of memory events
validation_failures_totalInput validation failures
dangerous_patterns_totalDangerous patterns detected
vm_boot_time_secondsTime to boot VM
vm_execution_time_secondsCode execution time

Comparison with Alternatives

FeatureRunner CodesDockergVisorKata
IsolationHardware (KVM)NamespaceSyscall filterHardware
Attack surfaceVery smallLargeMediumSmall
Kernel sharedNoYesEmulatedNo
Network controlBuilt-inRequires configRequires configRequires config
Startup time~3s~100ms~100ms~1s
Memory overhead~5MB~1MB~10MB~50MB

Security Checklist

Deployment

  • Run on dedicated hosts (no other workloads)
  • Keep kernel updated
  • Keep Firecracker updated
  • Enable seccomp filtering
  • Disable SMT on host
  • Use jailer in production
  • Monitor security events
  • Set up alerting for timeouts/OOM

Configuration

  • Set appropriate timeout limits
  • Set appropriate memory limits
  • Disable network (default)
  • Use minimal rootfs images
  • Remove unnecessary packages from rootfs

Operations

  • Regular security audits
  • Incident response plan
  • Log retention policy
  • Access control for host

Resources