Sandboxing & Security
Moxxy implements a multi-layer security model to isolate agent operations and protect the host system. There is no single container configuration file; security is enforced through multiple complementary layers.
Multi-Layer Security Model
┌─────────────────────────────────────────────────────────┐
│ Sandbox Layers │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. Workspace Isolation (PathPolicy) │
│ └── ~/.moxxy/agents/{id}/workspace/ │
│ │
│ 2. OS-Level Sandbox │
│ ├── macOS: sandbox-exec (seatbelt profiles) │
│ └── Linux: bubblewrap (namespaces + seccomp) │
│ │
│ 3. Command Allowlists (shell.exec) │
│ └── Per-agent approved commands in database │
│ │
│ 4. Domain-Gated Networking (http.request) │
│ └── Per-agent domain allowlist │
│ │
│ 5. WASI Plugins (wasmtime 29) │
│ └── Ed25519 signed manifests │
│ │
└─────────────────────────────────────────────────────────┘Layer 1: Workspace Isolation (PathPolicy)
Every agent's file operations are confined to its workspace directory at ~/.moxxy/agents/{id}/workspace/.
How It Works
- All filesystem primitives (
fs.read,fs.write,fs.list,fs.remove) are checked against the agent's workspace path - Canonical path resolution prevents symlink escapes
- Traversal detection blocks
..path components that would escape the workspace - A read-only mount of the core directory provides access to built-in resources
- Explicit path allowances can be configured for access to directories outside the workspace
Example
Agent abc-123 workspace:
~/.moxxy/agents/abc-123/workspace/
├── project/
│ ├── src/
│ └── README.md
└── data/
Allowed: fs.read("project/src/main.rs") → resolves inside workspace
Blocked: fs.read("../../vault.key") → traversal detected, denied
Blocked: fs.read("/etc/passwd") → outside workspace, deniedLayer 2: OS-Level Sandbox
Moxxy uses native operating system sandboxing to restrict what agent processes can do at the system level.
macOS: sandbox-exec (Seatbelt Profiles)
On macOS, agent processes run under sandbox-exec with seatbelt profiles that restrict system calls, file access, and network operations.
Linux: Bubblewrap (bwrap)
On Linux, agent processes run inside bubblewrap containers with:
- Linux namespaces for filesystem and process isolation
- seccomp filters to restrict available system calls
Sandbox Profiles
Three profiles control the level of restriction:
| Profile | Description | Network | Filesystem |
|---|---|---|---|
| strict | Minimal access, no network | Denied | Workspace only |
| standard | Default profile, workspace-scoped, domain-gated networking | Domain allowlist | Workspace only |
| none | Explicit opt-out of OS-level sandboxing | Unrestricted | Unrestricted |
Sandbox profiles are configured at the gateway level, not per-agent configuration files.
Layer 3: Command Allowlists
The shell.exec primitive restricts which commands an agent can execute.
How It Works
- Each agent has a command allowlist stored in the database
- Only commands on the allowlist can be executed via
shell.exec - The default posture is deny all -- commands must be explicitly approved
- Manage allowlists via primitives:
allowlist.add,allowlist.remove,allowlist.list
Managing Allowlists
# List allowed commands for an agent
# (via allowlist.list primitive or API)
# Add a command to the allowlist
# (via allowlist.add primitive or API)
# Remove a command from the allowlist
# (via allowlist.remove primitive or API)
# Deny a specific command
# (via allowlist.deny primitive)
# Undo a deny
# (via allowlist.undeny primitive)Layer 4: Domain-Gated Networking
The http.request primitive enforces a per-agent domain allowlist for outbound HTTP requests.
How It Works
- Each agent has a list of allowed domains
http.requestcalls are checked against this list before execution- Requests to domains not on the allowlist are denied
- Manage domain allowlists via the same allowlist primitives
Example
An agent with domains ["api.github.com", "api.openai.com"] allowed:
http.request("https://api.github.com/repos") → Allowed
http.request("https://api.openai.com/v1/chat") → Allowed
http.request("https://evil.example.com/steal") → DeniedLayer 5: WASI Plugins
Moxxy supports WebAssembly System Interface (WASI) plugins for sandboxed plugin execution.
Runtime
- wasmtime 29 runtime for executing WASI modules
- Capability-based permissions model
- Plugins can only access explicitly granted resources
Signed Manifests
- Plugin manifests are signed with Ed25519 keys
- Signatures are validated before plugin execution
- Unsigned or tampered plugins are rejected
Security Considerations
Defense in Depth
The multi-layer approach means that even if one layer is bypassed, other layers continue to protect the system:
- PathPolicy prevents filesystem escapes at the application level
- OS sandbox prevents system-level escapes
- Command allowlists prevent execution of unauthorized binaries
- Domain allowlists prevent unauthorized network access
- WASI sandboxing isolates plugin execution
Recommendations
- Use the standard sandbox profile for production agents
- Keep command allowlists minimal -- only approve commands the agent actually needs
- Restrict domain allowlists to specific API endpoints
- Audit allowlists periodically
- Use the strict profile for agents that do not need network access
- Only use the none profile for trusted development environments
Troubleshooting
Command Denied
Error: Command 'curl' not in allowlistThe agent tried to execute a command not on its allowlist. Add it with allowlist.add if appropriate.
Domain Denied
Error: Domain 'example.com' not in domain allowlistThe agent tried to make an HTTP request to an unapproved domain. Add it to the agent's domain allowlist if appropriate.
Sandbox Initialization Failed
Error: Failed to initialize sandbox- On macOS, verify
sandbox-execis available (built into macOS) - On Linux, verify bubblewrap (
bwrap) is installed:which bwrap - Check that the agent workspace directory exists and has correct permissions
Path Traversal Blocked
Error: Path traversal detectedThe agent attempted to access a file outside its workspace. This is blocked by design. If the agent needs access to an external directory, configure an explicit path allowance.