If you discover a security vulnerability in nanobot, please report it by:
- DO NOT open a public GitHub issue
- Create a private security advisory on GitHub or contact the repository maintainers (xubinrencs@gmail.com)
- Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We aim to respond to security reports within 48 hours.
CRITICAL: Never commit API keys to version control.
# ✅ Best: Use environment variable references in config (never writes the key to disk)
# In ~/.nanobot/config.json:
# "apiKey": "${ANTHROPIC_API_KEY}"
# Then supply the key at runtime via env var or Docker secret.
# ✅ Good: Store in config file with restricted permissions
chmod 600 ~/.nanobot/config.json
# ❌ Bad: Hardcoding keys in code or committing themRecommendations:
- Prefer environment variable references (
${VAR}) in config — the config file stores the${VAR}placeholder, and the plaintext value only exists in memory at runtime. See Configuration: Environment Variables for Secrets for details. - When plaintext keys are stored in
~/.nanobot/config.json, set file permissions to0600(chmod 600) - Consider using an OS keyring/credential manager for production deployments
- Rotate API keys regularly
- Use separate API keys for development and production
IMPORTANT: Always configure allowFrom lists for production use.
{
"channels": {
"telegram": {
"enabled": true,
"token": "YOUR_BOT_TOKEN",
"allowFrom": ["123456789", "987654321"]
},
"whatsapp": {
"enabled": true,
"allowFrom": ["1234567890"]
}
}
}Security Notes:
- In
v0.1.4.post3and earlier, an emptyallowFromallowed all users. Sincev0.1.4.post4, emptyallowFromdenies all access by default — set["*"]to explicitly allow everyone. - Get your Telegram user ID from
@userinfobot - Use WhatsApp sender IDs as full phone numbers with country code and no leading
+ - Review access logs regularly for unauthorized access attempts
The exec tool can execute shell commands. While dangerous command patterns are blocked, you should:
- ✅ Enable the exec sandbox (
"tools.exec.sandbox": "bwrap"on Linux,"seatbelt"on macOS) for kernel-level isolation - ✅ Review all tool usage in agent logs
- ✅ Understand what commands the agent is running
- ✅ Use a dedicated user account with limited privileges
- ✅ Never run nanobot as root
- ❌ Don't disable security checks
- ❌ Don't run on systems with sensitive data without careful review
Exec sandbox (bwrap on Linux, seatbelt on macOS):
Set "tools.exec.sandbox" to wrap every shell command in an OS sandbox. Both backends restrict filesystem access:
- Workspace directory → read-write (agent works normally)
- Media directory → read-only (can read uploaded attachments)
- System directories (
/usr,/bin,/lib) → read-only (commands still work) - The workspace's parent, which holds
~/.nanobot/config.jsonin the default layout → denied, except for explicitly exposed roots - Unlisted paths, including
~/.sshin the default layout → denied
| Backend | Value | Platform | Requires |
|---|---|---|---|
| bubblewrap | "bwrap" |
Linux | bwrap (apt install bubblewrap). Pre-installed in the official Docker image. |
| Seatbelt | "seatbelt" |
macOS | sandbox-exec(1), shipped with macOS. |
Windows has no backend: nanobot logs a warning and runs the command unsandboxed.
The backends protect the workspace's parent differently. bwrap masks it with a tmpfs and re-exposes the workspace and allowed binds. Seatbelt has no mount namespace: it denies the parent, re-allows traversal metadata, and exposes the workspace and allowed roots. Keep configuration and credentials outside the workspace and extra binds; choosing an overly broad workspace or explicitly exposing secret-bearing paths defeats that separation.
Seatbelt does not expose the host's shared /tmp, /var/folders, /Library, or /etc trees. It allows system code, device reads and selected system configuration/certificate paths. HOME and TMPDIR point to the workspace. Tools must use that scratch location; on macOS use an explicit template such as mktemp "$TMPDIR/job.XXXXXX", since bare mktemp may prefer the host's system temp directory. Tools that require other installations or caches need narrow sandboxRoBinds / sandboxRwBinds. Read-only binds revoke workspace writes beneath them; explicit read-write binds take precedence, matching bwrap's operator-controlled policy. Seatbelt also prevents renaming or removing ancestor directories of media and read-only roots, so moving a writable parent cannot bypass a read-only rule; unrelated children of those ancestors remain writable where otherwise allowed. An explicit read-write bind covering an entire read-only root overrides that root's protection, but a writable descendant does not unlock its ancestors. This is filesystem containment, not a VM or separate user identity.
Neither backend restricts network access.
Enabling the sandbox also automatically activates restrictToWorkspace for file tools.
Blocked patterns:
rm -rf /- Root filesystem deletion- Fork bombs
- Filesystem formatting (
mkfs.*) - Raw disk writes
- Other destructive operations
File operations have path traversal protection, but:
- ✅ Enable
restrictToWorkspaceor the bwrap sandbox to confine file access - ✅ Run nanobot with a dedicated user account
- ✅ Use filesystem permissions to protect sensitive directories
- ✅ Regularly audit file operations in logs
- ❌ Don't give unrestricted access to sensitive files
API Calls:
- All external API calls use HTTPS by default
- Timeouts are configured to prevent hanging requests
- The OpenAI-compatible API server must set
api.api_keywhen binding to0.0.0.0or::; otherwise startup fails to prevent unauthenticated network access - Consider using a firewall to restrict outbound connections if needed
WhatsApp:
- Keep the neonize session database under
~/.nanobot/whatsapp-authsecure (mode 0700). - Use
nanobot channels login whatsapp --forceto remove and recreate the local session database when rotating linked devices.
Critical: Keep dependencies updated!
# Check for vulnerable dependencies
pip install pip-audit
pip-audit
# Update to latest secure versions
pip install --upgrade nanobot-aiImportant Notes:
- Keep
litellmupdated to the latest version for security fixes - Run
pip-auditregularly after enabling the channels used in production; their manifest-declared dependencies are installed into the same environment - Subscribe to security advisories for nanobot and its dependencies
For production use:
-
Isolate the Environment
# Run in a container or VM docker run --rm -it python:3.11 pip install nanobot-ai -
Use a Dedicated User
sudo useradd -m -s /bin/bash nanobot sudo -u nanobot nanobot gateway
-
Set Proper Permissions
chmod 700 ~/.nanobot chmod 600 ~/.nanobot/config.json chmod 700 ~/.nanobot/whatsapp-auth
-
Enable Logging
# Configure log monitoring tail -f ~/.nanobot/logs/nanobot.log
-
Use Rate Limiting
- Configure rate limits on your API providers
- Monitor usage for anomalies
- Set spending limits on LLM APIs
-
Regular Updates
# Check for updates weekly pip install --upgrade nanobot-ai
Development:
- Use separate API keys
- Test with non-sensitive data
- Enable verbose logging
- Use a test Telegram bot
Production:
- Use dedicated API keys with spending limits
- Restrict file system access
- Enable audit logging
- Regular security reviews
- Monitor for unusual activity
- Logs may contain sensitive information - secure log files appropriately
- LLM providers see your prompts - review their privacy policies
- Chat history is stored locally - protect the
~/.nanobotdirectory - API keys are in plain text - use OS keyring for production
If you suspect a security breach:
- Immediately revoke compromised API keys
- Review logs for unauthorized access
grep "Access denied" ~/.nanobot/logs/nanobot.log
- Check for unexpected file modifications
- Rotate all credentials
- Update to latest version
- Report the incident to maintainers
✅ Input Validation
- Path traversal protection on file operations
- Dangerous command pattern detection
- Input length limits on HTTP requests
✅ Authentication
- Allow-list based access control — in
v0.1.4.post3and earlier emptyallowFromallowed all; sincev0.1.4.post4it denies all (["*"]explicitly allows all) - Failed authentication attempt logging
✅ Resource Protection
- Command execution timeouts (60s default)
- Output truncation (10KB limit)
- HTTP request timeouts (10-30s)
✅ Secure Communication
- HTTPS for all external API calls
- TLS for Telegram API
- WhatsApp session secrets stay in the local session database
- No Rate Limiting - Users can send unlimited messages (add your own if needed)
- Plain Text Config - API keys stored in plain text in
config.json(prefer${VAR}env references when possible, or use keyring for production) - No Session Management - No automatic session expiry
- Limited Command Filtering - Only blocks obvious dangerous patterns (enable the bwrap sandbox for kernel-level isolation on Linux)
- No Audit Trail - Limited security event logging (enhance as needed)
Before deploying nanobot:
- API keys stored securely (not in code)
- Config file permissions set to 0600
-
allowFromlists configured for all channels - Running as non-root user
- Exec sandbox enabled (
"tools.exec.sandbox": "bwrap") on Linux deployments - File system permissions properly restricted
- Dependencies updated to latest secure versions
- Logs monitored for security events
- Rate limits configured on API providers
- Backup and disaster recovery plan in place
- Security review of custom skills/tools
Last Updated: 2026-07-21
For the latest security updates and announcements, check:
- GitHub Security Advisories: https://github.com/HKUDS/nanobot/security/advisories
- Release Notes: https://github.com/HKUDS/nanobot/releases
See LICENSE file for details.