Trust model
NanoClaw operates with different trust levels for different entities:| Entity | Trust Level | Rationale |
|---|---|---|
| Main group | Trusted | Private self-chat, admin control |
| Non-main groups | Untrusted | Other users may be malicious |
| Container agents | Sandboxed | Isolated execution environment |
| Incoming messages | User input | Potential prompt injection |
Security boundaries
Container isolation (primary boundary)
Agents execute in containers (lightweight Linux VMs), providing:- Process isolation - Container processes cannot affect the host
- Filesystem isolation - Only explicitly mounted directories are visible
- Non-root execution - Runs as unprivileged
nodeuser (uid 1000) - Ephemeral containers - Fresh environment per invocation (
--rm)
The container runtime is abstracted through
src/container-runtime.ts, making it easy to swap runtimes. Docker is the default, but you can switch to Apple Container on macOS for a lighter-weight native runtime.Mount security
External allowlist Mount permissions are stored at~/.config/nanoclaw/mount-allowlist.json, which is:
- Outside the project root
- Never mounted into containers
- Cannot be modified by agents
- Symlink resolution before validation (prevents traversal attacks)
- Container path validation (rejects
..and absolute paths) nonMainReadOnlyoption forces read-only for non-main groups
src/mount-security.ts for the validation implementation.
Read-only project root
The main group’s project root is mounted read-only. Writable paths the agent needs (group folder, IPC, .claude/) are mounted separately. This prevents the agent from modifying host application code (src/, dist/, package.json, etc.) which would bypass the sandbox entirely on next restart.
From src/container-runner.ts:
Session isolation
Each group has isolated Claude sessions atdata/sessions/{group}/.claude/:
- Groups cannot see other groups’ conversation history
- Session data includes full message history and file contents read
- Prevents cross-group information disclosure
src/container-runner.ts:
IPC authorization
Messages and task operations are verified against group identity. The IPC system uses per-group namespaces indata/ipc/{group}/ to prevent privilege escalation.
| Operation | Main Group | Non-Main Group |
|---|---|---|
| Send message to own chat | ✓ | ✓ |
| Send message to other chats | ✓ | ✗ |
| Schedule task for self | ✓ | ✓ |
| Schedule task for others | ✓ | ✗ |
| Update own tasks | ✓ | ✓ |
| Update other groups’ tasks | ✓ | ✗ |
| View all tasks | ✓ | Own only |
| Manage other groups | ✓ | ✗ |
src/ipc.ts:
Sender allowlist
The sender allowlist (~/.config/nanoclaw/sender-allowlist.json) filters who can interact with the agent on a per-chat basis. Like the mount allowlist, it lives outside the project root and cannot be modified by agents.
File format (SenderAllowlistConfig):
- On every message cycle, the file is read from disk (hot-reloaded, no restart needed)
- For each incoming message, the system checks
chats[chatJid]first, then falls back todefault - If the sender is not in the
allowlist:triggermode: the message is stored in the database but cannot activate the agentdropmode: the message is silently discarded before reaching the database
- If
logDeniedistrue, denied attempts are logged at debug level
{ allow: "*", mode: "trigger" } — all senders permitted. Invalid per-chat entries are skipped with a warning; valid entries are still applied.
From src/sender-allowlist.ts:
The sender allowlist complements container isolation. Containers protect against what an agent can do; the allowlist controls who can invoke an agent. Both are enforced on the host, outside the agent’s reach.
Credential handling
- OneCLI Gateway (v1.2.22+)
- Credential Proxy (legacy)
NanoClaw delegates all credential management to the OneCLI gateway. The host process never reads API keys — secrets are registered with OneCLI and injected into container traffic by the gateway.How it works:
- The
@onecli-sh/sdkpackage’sapplyContainerConfig()configures each container’s network to route through the gateway - The gateway intercepts HTTPS traffic to
api.anthropic.comand injects the registered secret - Each non-main group receives an
agentIdentifier(derived from its folder name) for per-group credential scoping ONECLI_URL(defaulthttp://localhost:10254) configures the gateway address
src/container-runner.ts):If the OneCLI gateway is unreachable at container start, the container launches with no credentials. The agent will fail on API calls, and a warning is logged. Re-run after ensuring OneCLI is running (
curl http://127.0.0.1:10254/api/health).- Channel sessions (e.g.,
store/auth/for WhatsApp) - host only - Mount allowlist - external, never mounted
- Real API keys or OAuth tokens - injected by secret injection layer, never in containers
- Any credentials matching blocked patterns
Privilege comparison
| Capability | Main Group | Non-Main Group |
|---|---|---|
| Project root access | /workspace/project (ro) | None |
| Group folder | /workspace/group (rw) | /workspace/group (rw) |
| Global memory | Via project mount | /workspace/global (ro, if exists) |
| Additional mounts | Configurable | Read-only unless allowed |
| Network access | Unrestricted | Unrestricted |
| MCP tools | Allowlisted | Allowlisted |
Security architecture diagram
Best practices
Review mount allowlist regularly
Review mount allowlist regularly
Check
~/.config/nanoclaw/mount-allowlist.json to ensure only necessary directories are mounted. Remove entries you no longer need.Use read-only mounts for sensitive data
Use read-only mounts for sensitive data
When mounting directories containing sensitive data, use the
readonly option in containerConfig.additionalMounts to prevent modifications.Keep secrets out of mounted directories
Keep secrets out of mounted directories
Never place API keys, passwords, or other secrets in directories that are mounted to non-main groups.
Monitor container logs
Monitor container logs
Check
groups/{name}/logs/container-*.log files to review what agents are doing. Enable verbose logging with LOG_LEVEL=debug for detailed output. Note that error logs only include input metadata (prompt length and session ID) rather than full prompt content.Related pages
- IPC system - Inter-process communication and authorization
- Container runtime - Container execution details
- Troubleshooting - Common security-related issues