SafetyCard Request a review

nanobot

Ultra-lightweight self-hosted personal AI agent with tools, MCP and chat-app integrations

github.com/HKUDS/nanobot · 2026-10-03 · b0d2382

Defense-in-depth score

2.3 / 10

As shipped, nanobot gives the model an unsandboxed shell, unrestricted file access across the user's home directory, web access and the ability to message any configured chat, with no human approval for any of it. Its good controls (SSRF-safe web fetching, a bubblewrap/Seatbelt sandbox, workspace restriction, scrubbed subprocess environments, deny-by-default chat access with pairing) are either narrow or off by default. The dominant risk is prompt injection from web pages, email or chat turning into secret theft (config.json holds the API keys) and destructive commands with no one in the loop.

Safest setup

nanobot ships a few solid protections: SSRF-safe web fetching, deny-by-default chat access with pairing, and a scrubbed environment for shell commands. As shipped, its shell and file tools reach your whole home directory with no sandbox and no approval step, so the safest setup turns on the workspace restriction and sandbox nanobot includes and builds containment around the process.

SetupHowWhat it gives you
A dedicated OS accountRun nanobot as its own OS user whose home holds only nanobot's files, with provider keys that carry a spending limitYour SSH keys, cloud credentials and other personal files stay out of the agent's reach C1
Workspace restrictiontools.restrictToWorkspace: true in config.jsonFile tools stay inside the workspace and shell commands get nanobot's path checks and deny-list C3
The exec sandboxtools.exec.sandbox: "bwrap" on Linux or "seatbelt" on macOSShell commands write only to the workspace and never see the config directory C4
Shell only where neededtools.exec.enable: false for setups whose tasks need no shellThe model works through nanobot's narrower file and web tools alone C3
Skills you choseagents.defaults.disabledSkills: ["clawhub"], adding skills to the workspace yourselfNew skills come from you, not from a public registry the model picks C7
Owner-only chat accessKeep each channel's allowFrom unset for pairing, or list only your own user IDsOnly people you approved can give the agent instructions over chat C5
Run and command limitsKeep the default maxToolIterations of 200 or lower, and the default tools.exec.timeout of 60 secondsEach run ends after a fixed number of tool calls and each shell command after a minute C10
Its own container or VMRun nanobot in a container or VM whose network reaches only the model provider and the chat services you useAn outer boundary around CLI apps and MCP servers, and a narrow path for data to leave C4

Handling data

  • Tool-call arguments go to the INFO log unredacted and transcripts are stored unencrypted; store both like the keys in config.json.
  • SOUL.md, USER.md and MEMORY.md can be rolled back with /dream-restore; review AGENTS.md and workspace skills yourself, since they have no history.
  • Scheduled jobs the agent created keep running after /stop; check the job list when you end a run.

Key gaps (4)

  1. In the default full-access mode the agent's file and shell tools can read and rewrite ~/.nanobot/config.json, so it can widen its own access settings that the self-configuration tool deliberately blocks, and it acts with the user's whole account. C1 · Identity & least privilege
  2. Shell commands run on the host as the user with no sandbox by default; the bwrap/Seatbelt sandbox is opt-in. C4 · Code-execution isolation
  3. A hijacked agent can read secrets and exfiltrate them via web_fetch, exec or the message tool, and run destructive commands, all unattended. C5 · Untrusted input blast radius
  4. Python packages exposing a nanobot.tools entry point are loaded in-process automatically, and a bundled skill directs the model to install remote skills with npx --yes clawhub@latest. C7 · Third-party extensions

Criteria

C1 Identity & least privilege

0.15 / 1.00

nanobot runs every tool as the operating-system user who launched it. It does strip API keys and other variables from the shell tool's environment, which is a real narrowing, but in the default configuration the file and shell tools can read and write anywhere in the user's home directory, including SSH keys, cloud credential files and nanobot's own config.json with its provider keys and chat-bot tokens. Because file tools are unrestricted by default, the agent can also rewrite its own config.json (for example widening who may message it or re-enabling self-configuration), even though the built-in self-configuration tool deliberately blocks those fields. A hijacked agent therefore holds roughly the user's whole account.

C2 Approval gates

0.00 / 1.00

There is no human approval step for any tool call. Shell commands, file writes and deletes, outbound chat messages with file attachments, scheduled jobs and MCP tool calls all execute as soon as the model requests them. The WebUI's 'restricted' versus 'full access' mode changes path checks, not approval. Mistakes or hijacked actions such as deleting files or messaging third parties happen with no human in the loop and largely cannot be undone.

C3 Tool & action scoping

0.23 / 1.00

Tool input validation is uneven. The web fetch tool is well built: it blocks private, loopback and cloud-metadata addresses and re-checks every redirect. The file tools resolve symlinks and enforce workspace containment, and the shell tool has a deny-list and internal-URL check, but both of those only run when workspace restriction is turned on, and it is off by default. In the shipped configuration the shell tool takes arbitrary command strings with no filtering at all, and write, shell and network tools are all enabled.

C4 Code-execution isolation

0.42 / 1.00

By default shell commands run directly on the host as the user, with no isolation. nanobot ships an optional bubblewrap (Linux) or Seatbelt (macOS) wrapper that limits filesystem writes to the workspace and hides the config directory, and the Docker image includes bubblewrap, but it is off unless the operator sets tools.exec.sandbox. Even when enabled, the sandbox leaves network access open, does not cover CLI apps or MCP servers, and on Windows silently runs unsandboxed with only a log warning. The criterion is credited for the opt-in sandbox, capped because it is off by default.

C5 Untrusted input blast radius

0.25 / 1.00

nanobot reads lots of content its owner did not write: web pages and search results, inbound email and chat messages, files, MCP tool results and other sessions' history. Web results and session history are wrapped with an 'untrusted data' banner and the system prompt asks the model not to follow embedded instructions, but nothing in code limits what a hijacked agent can then do. In the same session it can read the config file holding API keys, send data out through web requests, shell commands or chat messages, and run destructive commands, all without approval. Inbound chat channels do deny unknown senders by default and use operator-approved pairing, which keeps strangers from instructing the agent directly.

C6 Memory, context & configuration integrity

0.05 / 1.00

Long-term memory (MEMORY.md), the persona files SOUL.md and USER.md, the project AGENTS.md and any 'always' workspace skills are injected into the system prompt on every turn. The model can write all of them with ordinary file tools, and a periodic 'Dream' job automatically consolidates conversation history into memory, so an injected instruction can persist and fire in later sessions. Memory is one store per workspace, shared across every channel and chat. There is a useful safety net: SOUL.md, USER.md and MEMORY.md are versioned in a local git store with /dream-log and /dream-restore, but AGENTS.md and skills are not.

C7 Third-party extensions

0.07 / 1.00

nanobot loads several kinds of third-party code. Agent Plugins are handled well: enabling one binds to a content fingerprint and any change disables it. Everything else is weaker. Python packages that declare a 'nanobot.tools' entry point are loaded automatically into the agent's own process, MCP servers are launched from whatever command the user configured (the built-in presets use unpinned @latest packages), and a bundled ClawHub skill tells the model to install skills from a public registry with 'npx --yes clawhub@latest', which the model can run through the ungated shell. A malicious extension runs with the user's full authority.

C8 Secrets & sensitive-data protection

0.20 / 1.00

API keys, chat-bot tokens and email passwords live in ~/.nanobot/config.json, either in plaintext or as ${VAR} references, and nanobot does not enforce restrictive file permissions on it. The shell tool gets a scrubbed environment so keys are not inherited by commands, and API key fields are hidden from object representations. However, in the default full-access mode the model can simply read config.json, tool-call arguments are logged at INFO level without redaction, and transcripts are stored unencrypted. Telemetry (Langfuse) is only active when its keys are set.

C9 Audit & traceability

0.50 / 1.00

Every conversation is saved as a JSONL session transcript that includes tool calls, tool results and timestamps, stored outside the agent's workspace in a 0700 directory, and the runner writes a recovery checkpoint listing pending tool calls before they execute. Tool calls are also written to the human-readable log. The record is not tamper-evident, carries no actor or approver attribution, sub-agent tool calls are only summarised, and in the default full-access mode the agent's own tools could edit the files.

C10 Limits & kill switch

0.45 / 1.00

Each agent run is capped at 200 tool iterations, shell commands time out after 60 seconds by default (the model can ask for up to 600), and MCP calls after 30 seconds. The /stop command cancels the session's tasks, sub-agents and background shell sessions and kills shell process groups. There is no wall-clock or cost limit, each sub-agent gets its own fresh 200-iteration budget, and scheduled jobs the agent created keep running after a stop.