Isolation by Design
Isolation by Design
Section titled “Isolation by Design”Perstack is designed to run inside isolated environments. The runtime itself doesn’t enforce security boundaries — your infrastructure does.
For the rationale behind this approach, see Sandbox Integration.
Layers of isolation
Section titled “Layers of isolation”| Layer | Provider | Perstack’s role |
|---|---|---|
| Infrastructure | Your platform (Docker, ECS, Workers) | Designed to run in any sandboxed environment |
| Workspace | Perstack | Confined file access to a single directory |
| Skills | Perstack | Minimal privilege for MCP servers |
| Network | Your platform | Event-based output — no direct outbound access |
Infrastructure isolation
Section titled “Infrastructure isolation”Run Experts in isolated environments:
# Dockerdocker run --rm \ --read-only \ --network none \ -e ANTHROPIC_API_KEY \ -v $(pwd)/workspace:/workspace \ my-expertKey controls:
--read-only: Prevent writes outside workspace--network none: No network access (except for LLM API)- Resource limits (
--memory,--cpus)
For cloud platforms (ECS, Cloud Run, Workers), use platform-native isolation features.
Workspace isolation
Section titled “Workspace isolation”Experts can only access files within the workspace directory:
/workspace ← Expert's file access boundary├── perstack/ ← Runtime-managed (checkpoints, events)├── input/ ← Your input files└── output/ ← Expert's outputThe workspace is the only shared boundary between your system and the Expert. Control what goes in, verify what comes out.
How it works
Section titled “How it works”All file operations in @perstack/base use path validation:
- Path resolution: Relative paths resolved against current working directory
- Symlink resolution:
fs.realpath()resolves symlinks to their actual target - Boundary check: Resolved path must start with workspace path
- Reserved paths:
/perstackdirectory is always denied (runtime-managed)
What it protects against
Section titled “What it protects against”| Attack | Protection |
|---|---|
Path traversal (../../../etc/passwd) | Resolved path checked against workspace |
Symlink escape (symlink → /etc) | realpath() resolves before boundary check |
Absolute path injection (/etc/passwd) | Must resolve within workspace |
Limitations
Section titled “Limitations”TOCTOU (Time-of-check to time-of-use): A symlink could theoretically be modified between validation and actual file operation. In practice, this requires:
- Attacker-controlled code running in the same environment
- Precise timing to modify symlink between check and use
Mitigation: Run Experts in isolated containers with read-only root filesystem. The workspace directory should be the only writable location.
Best practices
Section titled “Best practices”# Docker: read-only root, writable workspace onlydocker run --rm \ --read-only \ --tmpfs /tmp \ -v $(pwd)/workspace:/workspace \ my-expertFor maximum security, combine workspace isolation with infrastructure isolation.
Skill isolation
Section titled “Skill isolation”MCP servers run with minimal privilege:
[experts."analyzer".skills."data"]type = "mcpStdioSkill"command = "npx"packageName = "@example/data-mcp"requiredEnv = ["DATABASE_URL"] # Only these env vars passedpick = ["query"] # Only these tools allowed- Environment: Only
requiredEnvvariables are passed - Tools: Use
pick/omitto restrict available tools - Lifecycle: Servers start with the Expert, stop when done
Network boundaries
Section titled “Network boundaries”Docker runtime (built-in isolation)
Section titled “Docker runtime (built-in isolation)”When using --runtime docker, Perstack provides built-in network isolation via Squid proxy:
[experts."secure-expert".skills."web-search"]type = "mcpStdioSkill"command = "npx"packageName = "exa-mcp-server"allowedDomains = ["api.exa.ai"]How it works:
- All outbound traffic routes through a Squid proxy container
- Only HTTPS (port 443) is allowed
- Only domains in the allowlist are permitted
- Provider API domains are auto-included (e.g.,
api.anthropic.com)
Allowlist sources:
| Source | Description |
|---|---|
Skill allowedDomains | Per-skill network access |
| Provider API | Auto-included based on provider |
Network access is controlled at the skill level because all network operations are performed through MCP skills. The Expert itself does not directly access the network.
Debugging network issues:
Use --verbose to see real-time proxy activity:
npx perstack start my-expert "query" --runtime docker --verboseThis shows:
- ✅
Proxy ✓ api.anthropic.com:443— Request allowed - 🚫
Proxy ✗ blocked.com:443 (Domain not in allowlist)— Request blocked
When network requests fail unexpectedly, verbose mode helps distinguish between:
- Domain not in allowlist (blocked by proxy)
- Network connectivity issues
- Target server errors
Local runtime (infrastructure-controlled)
Section titled “Local runtime (infrastructure-controlled)”With the local runtime, Perstack outputs events to stdout. Your infrastructure decides what crosses the network boundary:
┌─────────────────────────────────────────────────────────┐│ Isolated Environment ││ ┌─────────────────────────────────────────────────┐ ││ │ Perstack Runtime │ ││ │ - Expert execution │ ││ │ - Tool calls │ ││ │ - Events → stdout │ ││ └─────────────────────────────────────────────────┘ │└──────────────────────────┬──────────────────────────────┘ │ stdout (JSON events) ▼┌─────────────────────────────────────────────────────────┐│ Your Infrastructure ││ - Parse events ││ - Decide what to forward ││ - Control external access │└─────────────────────────────────────────────────────────┘The agent cannot initiate outbound connections — you control the boundary.
Checklist
Section titled “Checklist”Before deploying to production:
- Infrastructure isolation configured (container, serverless, or VM)
- Workspace mounted with appropriate permissions
- Skills use
requiredEnvandpick/omit - Network access restricted to LLM API only
- Event output integrated with your monitoring
What’s next
Section titled “What’s next”- Skill Management — how the runtime manages skills
- Deployment — deploying to production
- Observing — monitoring and auditing
- Sandbox Integration — why sandbox-first