Isolation Levels
tenement provides multiple isolation levels for different security needs.
The Spectrum
Section titled “The Spectrum”| Isolation | Tool | Overhead | Startup | Use Case |
|---|---|---|---|---|
| process | bare | ~0 | <10ms | Same trust boundary, debugging |
| namespace | unshare | ~0 | <10ms | Default - trusted code, /proc isolated |
| sandbox | gVisor | ~20MB | <100ms | Untrusted/multi-tenant code |
| firecracker | microVM | ~128MB | ~125ms | Compliance, custom kernel |
1. Bare Process (No Isolation)
Section titled “1. Bare Process (No Isolation)”[service.debug]command = "./app"isolation = "process"Runs as a bare process with no isolation. All processes see the same /proc, environment, etc.
When to use:
- Trusted code only
- Debugging
- Same security boundary as the host
Overhead: None (bare metal speed)
2. Namespace Isolation (Default)
Section titled “2. Namespace Isolation (Default)”[service.api]command = "./app"isolation = "namespace"Uses Linux namespaces (PID + Mount) to give each process its own /proc and isolated mount namespace. Environment variables are hidden between services.
What’s isolated:
/proc- Process tree hidden/sys- System interface hidden- Mount namespace - Filesystem views separated
What’s shared:
- Network (unless configured otherwise)
- System calls directly to kernel
Overhead: ~0 (kernel built-in since 2008)
Startup: <10ms
Requirements: Linux only
When to use:
- Multi-tenant deployments (trusted code)
- Microservices on one host
- You want isolation without performance cost
- Default recommendation for most users
Example: Multi-tenant with Namespace Isolation
Section titled “Example: Multi-tenant with Namespace Isolation”[service.api]command = "uv run python app.py"health = "/health"isolation = "namespace"
[service.api.env]DATABASE_PATH = "{data_dir}/{id}/app.db"Each tenant process:
- Sees only its own
/proc - Can’t spy on sibling processes
- Can’t access sibling environment variables
- Runs at native speed
3. Sandbox Isolation (gVisor)
Section titled “3. Sandbox Isolation (gVisor)”[service.untrusted]command = "./user-plugin"isolation = "sandbox"Uses gVisor (runsc) to filter system calls. Untrusted code runs in a syscall sandbox.
What’s blocked:
- Kernel module loading
- Raw socket access
- Dangerous syscalls (ptrace, etc.)
- Direct hardware access
Overhead: ~20MB memory per instance
Startup: <100ms (slightly slower, but cold-start)
Requirements:
- Linux
- gVisor installed (
apt install runscor similar) - Compile with
--features sandbox
When to use:
- User-supplied plugins/code
- Third-party integrations you don’t trust
- Multi-tenant + untrusted code
- Compliance requirements
Example: Sandbox for User Code
Section titled “Example: Sandbox for User Code”[service.api]command = "./api"isolation = "namespace"
[service.plugin]command = "./user-plugin"isolation = "sandbox" # Untrustedmemory_limit_mb = 128 # Extra constrainedcpu_shares = 50 # Limited CPUAPI runs in namespace isolation (trusted, fast). User plugins run in gVisor sandbox (untrusted, safe).
4. Firecracker Isolation (Future)
Section titled “4. Firecracker Isolation (Future)”MicroVM isolation with Firecracker. ~128MB overhead, compliance-grade isolation.
Planned for future releases.
Decision Flowchart
Section titled “Decision Flowchart” Start │ ▼ ┌───────────────────────┐ │ Is the code trusted? │ │ (your own code, not │ │ user-uploaded) │ └──────────┬────────────┘ │ ┌────────┴────────┐ │ │ Yes No │ │ ▼ ▼ ┌───────────┐ ┌───────────────┐ │ Need /proc│ │ Use SANDBOX │ │ isolation?│ │ (gVisor) │ └─────┬─────┘ └───────────────┘ │ ┌─────┴─────┐ │ │ Yes No │ │ ▼ ▼┌──────────┐ ┌──────────┐│NAMESPACE │ │ PROCESS ││ (default)│ │(no isol.)│└──────────┘ └──────────┘Quick decision:
- Trusted code + multi-tenant →
namespace(default) - Trusted code + debugging →
process - Untrusted code →
sandbox - Compliance/custom kernel →
firecrackerorqemu
Choosing the Right Level
Section titled “Choosing the Right Level”Multi-tenant SaaS (Trusted Code)
Section titled “Multi-tenant SaaS (Trusted Code)”→ Use namespace isolation
- Cheap, fast, good isolation
- Each tenant can’t see others
[service.api]isolation = "namespace"User-Supplied Code
Section titled “User-Supplied Code”→ Use sandbox isolation
- Extra security for untrusted code
- 20MB overhead is worth it
[service.user_code]isolation = "sandbox"memory_limit_mb = 256cpu_shares = 100Mixed Workload
Section titled “Mixed Workload”→ Use both
- Trusted services: namespace
- Untrusted services: sandbox
[service.api]isolation = "namespace" # Your code
[service.user_plugins]isolation = "sandbox" # Their codeDevelopment/Debugging
Section titled “Development/Debugging”→ Use bare process
- Easiest to debug
- Don’t need isolation locally
[service.debug]isolation = "process"Security Considerations
Section titled “Security Considerations”Namespace Isolation
Section titled “Namespace Isolation”- What it protects against: Process inspection, environment snooping
- What it doesn’t protect: OS-level exploits, kernel bugs
- Best for: Trusted code separation (multi-tenant with your own apps)
Sandbox Isolation
Section titled “Sandbox Isolation”- What it protects against: Most user-space exploits, kernel-facing attacks
- What it doesn’t protect: Bugs in gVisor itself, hardware exploits
- Best for: Untrusted code, plugins, third-party services
Defense in Depth
Section titled “Defense in Depth”Combine with resource limits:
[service.untrusted]isolation = "sandbox"memory_limit_mb = 128 # Can't eat all RAMcpu_shares = 50 # Can't hog CPUPerformance Comparison
Section titled “Performance Comparison”Rough numbers on a modern Linux machine:
| Operation | Process | Namespace | Sandbox | Notes |
|---|---|---|---|---|
| Spawn | 5ms | 8ms | 50ms | Sandbox is slower |
| First request | 1ms | 1ms | 2ms | Cold start penalty minimal |
| Request throughput | 100k/s | 100k/s | 50k/s | Sandbox adds ~50% overhead |
| Memory | 10MB | 10MB | 30MB | Sandbox adds ~20MB |
For most workloads, namespace isolation is the sweet spot: nearly native performance with good security.
Next Steps
Section titled “Next Steps”- Configuration Reference - Set isolation in config
- Production Deployment - Deploy with TLS and systemd