NanoClaw’s security model is built on true isolation at the OS level rather than application-level permission checks. Agents run in actual Linux containers and can only access what’s explicitly mounted. In v2, a new permissions system adds user roles, sender scope enforcement, and channel approval flows.Documentation Index
Fetch the complete documentation index at: https://docs.nanoclaw.dev/llms.txt
Use this file to discover all available pages before exploring further.
Trust model
| Entity | Trust Level | Rationale |
|---|---|---|
| Owner | Fully trusted | System administrator, all privileges |
| Admins | Trusted | Can approve senders and manage groups (global or scoped) |
| Known users | Permitted | Members of specific agent groups |
| Unknown senders | Untrusted | Policy-controlled per messaging group |
| Container agents | Sandboxed | Isolated execution environment |
| Incoming messages | User input | Potential prompt injection |
Security boundaries
1. 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) - Signal forwarding —
tinias PID 1 ensures clean shutdown
Bash access is safe because commands run inside the container, not on your host. The container’s filesystem is isolated from the host.
2. Mount security
External allowlist
Mount permissions stored at~/.config/nanoclaw/mount-allowlist.json, which is:
- Outside project root
- Never mounted into containers
- Cannot be modified by agents
Protections
- Symlink resolution before validation (prevents traversal attacks)
- Container path validation (rejects
..and absolute paths) - Container path colon rejection (prevents Docker
-voption injection) - RW gating — read-write access requires both mount request AND allowed root to permit it; otherwise forced read-only
3. Permissions system
The v2 permissions module provides a three-level access control model:User roles
| Role | Scope | Capabilities |
|---|---|---|
| Owner | Always global | All operations, approves channels and senders |
| Admin | Global or per-agent-group | Approves senders within scope |
| Member | Per-agent-group | Can interact with agents in their group |
Unknown sender policy
Each messaging group has anunknown_sender_policy:
| Policy | Behavior |
|---|---|
public | Skip access check entirely — anyone can interact |
strict | Unknown senders are silently dropped |
request_approval | Unknown senders trigger an approval card to the admin |
Sender scope
Per-wiring enforcement viasender_scope:
all— any user can trigger the agent through this wiringknown— requires the user to be an owner, admin, or group member
Channel approval flow
When a message arrives on an unwired channel (no agent wirings exist):- The channel-request gate sends an approval card to the owner
- Approve — creates a wiring with default settings, admits the triggering sender, replays the original event
- Deny — sets
denied_aton the messaging group; future mentions drop silently
Sender approval flow
When an unknown sender messages on arequest_approval channel:
- An approval card is sent to the designated approver (admin or owner)
- Approve — adds sender to
agent_group_members, replays the original message - Deny — deletes the pending row (future messages from this sender re-trigger)
4. Session isolation
Each session has isolated databases atdata/v2-sessions/{agent_group_id}/{session_id}/:
inbound.dbandoutbound.dbper session- Sessions cannot see other sessions’ data
- Cross-session information disclosure is prevented by mount isolation
5. Credential handling
NanoClaw uses the OneCLI Agent Vault for centralized secret management. API keys are never stored in.env or exposed to containers — the vault intercepts outbound API traffic from containers and injects credentials at request time.
- Secrets are registered once via
onecli secrets create - Each non-main agent group gets its own OneCLI agent identifier for per-group credential scoping
- The
@onecli-sh/sdkpackage’sapplyContainerConfig()configures container networking - If the vault is unreachable, the container starts with no credentials and logs a warning
6. Delivery authorization
The delivery system enforces per-agent permissions:- Source agent must be authorized to deliver to the target channel
- Messages to the origin chat (where the conversation started) are always permitted
- Cross-channel delivery requires an explicit
agent_destinationsrow - The
ask_questionmessage type creates interactivepending_questionscards
7. Diagnostics and telemetry
NanoClaw includes opt-in diagnostics that run during/setup and /update-nanoclaw skill workflows only. There is no runtime telemetry in the application itself.
Diagnostics are entirely skill-driven — they exist as markdown instructions read by Claude, not as application code. No data is ever sent without explicit user approval.
Privilege comparison
| Capability | Owner | Admin | Member | Unknown |
|---|---|---|---|---|
| All operations | ✓ | — | — | — |
| Approve senders | ✓ | Scoped | — | — |
| Interact with agents | ✓ | ✓ | ✓ | Policy-dependent |
| Cross-agent messaging | ✓ | ✓ | ✓ | — |
Attack scenarios
Prompt injection
Attack: user sends a malicious prompt to hijack agent behavior Mitigation:- Agent only has access to its own session’s databases
- Cannot deliver to unauthorized channels (delivery authorization)
- Cannot access credential files (not mounted)
- Cannot modify mount allowlist (external, never mounted)
Container escape attempt
Attack: agent tries to break out of container via kernel exploit Mitigation:- Container runtime provides kernel-level isolation
- Non-root execution limits attack surface
tinias PID 1 ensures proper signal handling- Host filesystem only accessible via explicit mounts
Unknown sender exploitation
Attack: unknown user floods a public channel to exhaust resources Mitigation:strictpolicy drops unknown senders silentlyrequest_approvalrequires admin action before processing- Per-wiring
sender_scope=knownrestricts to group members even on public channels
Best practices
- Use
request_approvalfor public groups — prevents unauthorized access while allowing legitimate users - Review mount allowlist — before allowing new mounts, verify they don’t contain secrets
- Use
sender_scope=knownfor sensitive wirings — restricts to authorized users even on public channels - Set up admin roles — delegate sender approval without giving full owner access
- Monitor delivery logs — check for unauthorized delivery attempts
- Update regularly — security fixes may be released in upstream NanoClaw updates