NanoClaw’s security model is built on OS-level isolation rather than application-level permission checks. In v2, a new permissions module adds user roles, sender scope enforcement, channel approval, and delivery authorization.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
NanoClaw operates with different trust levels:| Entity | Trust Level | Rationale |
|---|---|---|
| Owner | Fully trusted | System administrator |
| Admins | Trusted | Can approve senders (global or scoped) |
| Known users | Permitted | Members of agent groups |
| Unknown senders | Untrusted | Policy-controlled per messaging group |
| Container agents | Sandboxed | Isolated execution environment |
Security boundaries
Container isolation (primary boundary)
Agents execute in containers, 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 and database finalization
Mount security
External allowlist at~/.config/nanoclaw/mount-allowlist.json:
- Outside the project root, never mounted into containers
- Cannot be modified by agents
- Symlink resolution before validation (prevents traversal)
- Container path validation (rejects
.., absolute paths, colons) - RW gating — requires both mount request AND allowed root to permit read-write
- Missing allowlist file blocks all additional mounts (not cached — create without restart)
- Parse errors are permanently cached for the process lifetime
Permissions module
The permissions module (src/modules/permissions/) registers hooks into the core router:
Sender resolver — extracts namespaced user ID from message content and upserts the users row on first sight:
unknown_sender_policy per messaging group:
| Policy | Behavior |
|---|---|
public | Skip access check entirely |
strict | Unknown senders silently dropped |
request_approval | Approval card sent to admin |
sender_scope='known'requires the user to be an owner, admin, or group member even on public channels
- Escalates to owner for approval
- Approve: creates wiring with defaults, admits sender, replays message
- Deny: sets
denied_at, future mentions silently dropped
Session isolation
Each session has isolated databases:data/v2-sessions/{agent_group_id}/{session_id}/inbound.dbdata/v2-sessions/{agent_group_id}/{session_id}/outbound.db
Delivery authorization
The delivery system enforces per-agent permissions:- Messages to the origin chat are always permitted
- Cross-channel delivery requires an explicit
agent_destinationsrow - System messages (scheduling, approvals) are routed through registered delivery action handlers
- File attachments are read from
outbox/{messageId}/ - 3 retry attempts per message, then permanently failed
Credential handling
NanoClaw delegates all credential management to the OneCLI Agent Vault:- The
@onecli-sh/sdkpackage’sapplyContainerConfig()configures each container’s network - The vault intercepts HTTPS traffic and injects registered secrets
- Each agent group receives a unique
agentIdentifierfor per-group credential scoping ONECLI_URL(defaulthttp://localhost:10254) configures the vault address
- Real API keys or OAuth tokens — injected by vault, never in containers
- Mount allowlist — external, never mounted
.envfile — configuration only (no credentials)
Privilege comparison
| Capability | Owner | Admin (scoped) | Member | Unknown (public) | Unknown (strict) |
|---|---|---|---|---|---|
| All operations | ✓ | — | — | — | — |
| Approve senders | ✓ | Within scope | — | — | — |
| Approve channels | ✓ | — | — | — | — |
| Interact with agents | ✓ | ✓ | ✓ | ✓ | Dropped |
| Cross-agent messaging | ✓ | ✓ | ✓ | — | — |
Security architecture diagram
Best practices
Use request_approval for public groups
Use request_approval for public groups
Set
unknown_sender_policy='request_approval' to require admin approval for new senders. This prevents unauthorized access while allowing legitimate users to be admitted.Scope admin roles
Scope admin roles
Create per-agent-group admins instead of global admins. Scoped admins can only approve senders for their assigned group.
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 sender_scope=known for sensitive wirings
Use sender_scope=known for sensitive wirings
Even on public channels,
sender_scope='known' restricts interaction to group members, admins, and owner.Monitor delivery authorization
Monitor delivery authorization
Related pages
- Container runtime — container execution details
- Troubleshooting — common security-related issues