security: comprehensive hardening for external deployment#3055
Closed
Skyfly2 wants to merge 62 commits into
Closed
security: comprehensive hardening for external deployment#3055Skyfly2 wants to merge 62 commits into
Skyfly2 wants to merge 62 commits into
Conversation
The identity preamble previously claimed 'You are nanobot, a helpful AI assistant' which conflicted with the personalized SOUL.md content (e.g. 'I am Weasel 🔧'). The LLM received two competing identity statements, causing confusion on welcome and potential name-prompting behaviour. Replace with a neutral preamble that explicitly tells the agent its name and personality live in SOUL.md, and to use that as the sole authority. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… set When the coordinator invokes the agent via docker exec, enable full DEBUG logging to a persistent file in the nanobot volume. Inspect with: docker exec <container> tail -f /root/.nanobot/agent.log stderr is also retained so the coordinator can capture it via demux. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add --api-key / NANOBOT_API_KEY option to the gateway command. When set, starts an aiohttp server on the configured port with a single route: POST /agent/run (requires Authorization: Bearer <key>). Requests route through the live agent loop and in-memory CronService, fixing the cron job scheduling bug caused by docker exec subprocesses writing to jobs.json without notifying the gateway's running scheduler. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs in on_cron_job:
1. Used `cron:{job.id}` as session key — a fresh isolated session with no
personality or history, causing the agent to not know who it is.
Now uses `{channel}:{chat_id}` (e.g. telegram_relay:7775855639) for
deliver jobs so the agent has full context.
2. Passed job.payload.message raw as user input — the agent treated
"go outside" as a command, not a reminder to deliver. Now framed as:
"[SCHEDULED REMINDER] ... Deliver this message to the user in your own
voice: {message}"
Also tightened CronTool descriptions to clarify:
- message should be the notification text ("Time to go outside!", not "go outside")
- every_seconds is for recurring tasks only, never one-time reminders
- one-time reminders always use `at` with a computed ISO datetime
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
logger was only imported inside the `if verbose:` block, causing a NameError when `verbose=False` and the HTTP API server tried to log its startup message. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: add twitter tools
… acting The previous guideline "State intent before tool calls" caused the model to narrate planned actions to the user without actually making the tool call. Replaced with a directive to call tools immediately and report results naturally after they return. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Authorization: Bearer <NANOBOT_API_KEY> header to: - Google Workspace tool HTTP calls (GoogleBaseTool._post) - X/Twitter tool HTTP calls (XBaseTool._post) - Telegram relay channel outbound messages (TelegramRelayChannel.send) The coordinator now validates this header on all internal endpoints. Falls back gracefully (no header) if the env var is not set. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add coordinator/client.py with auth_headers() and post() that automatically include Authorization: Bearer <NANOBOT_API_KEY> on every outbound coordinator call. - GoogleBaseTool._post and XBaseTool._post delegate to coordinator.client.post - TelegramRelayChannel constructs its persistent httpx.AsyncClient with auth_headers() as default headers — auth is baked in, retry loop unchanged New tools/channels calling the coordinator just use coordinator.client.post() or pass auth_headers() to their client — no need to think about the token. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents commit template file from being tracked. Co-authored-by: Joshua Famous <joshua.famous@gmail.com>
- Fix _build_personality_learning_guidance() to reference memory tools (update_bot_identity, update_user_profile, save_memory) instead of edit_file/read_file for SOUL.md and USER.md, eliminating conflict with coordinator-generated AGENTS.md instructions - Preserve <follow_ups> block from suppressed final content in process_direct() when MessageTool was used, so the coordinator can extract suggestions from the done SSE event Made-with: Cursor
fix: resolve setup mode tool conflicts and preserve follow-ups
feat: consistent session id
Merge upstream main branch into our fork, adopting: - Native provider registry (replacing litellm) - AgentRunner architecture with hooks, checkpoints, mid-turn injection - Dream memory consolidation system - AutoCompact session management - New tools: Grep, Glob, NotebookEdit, Sandbox - Channel auto-discovery registry - Command router with slash commands - Streaming support via hooks (on_stream, on_stream_end) Re-integrated fork-specific features on top of upstream: - Coordinator client (coordinator/client.py) - Usage tracking (providers/tracked.py) wrapping upstream's retry APIs - OAuth scope sync (scope_registry, sync_scoped_tools, _fetch_and_sync_scopes) - Google/X/GitHub API tools with coordinator proxy - Telegram relay and web relay channels - SSE streaming gateway endpoints (/agent/run/stream) - Custom gateway HTTP API (/agent/run, /agent/sync-scopes, /agent/consolidate-session, /agent/identity, /agent/execute-tool) - Web relay auto-enable from COORDINATOR_URL/BOT_ID env vars - process_direct enhanced with on_message, confirmation, AgentResponse - MessageTool._sent_contents tracking for SSE content capture - Memory tools (UpdateBotIdentity, UpdateUserProfile, SaveMemory) with coordinator identity notification - TelegramRelayConfig and WebRelayConfig in config schema Made-with: Cursor
The upstream AgentRunner handles tool execution internally, so the fork's inline bot_name_updated event emission was lost in the merge. Wire on_stream_event from process_direct() to UpdateBotIdentityTool so the event flows through the SSE stream to the coordinator and wizard during setup. Made-with: Cursor
Made-with: Cursor
- Add requires_confirmation property to Tool base class (default False) and override to True on ExecTool, WriteFileTool, EditFileTool - Update test_restart_command to expect AgentResponse instead of OutboundMessage from process_direct() - Fix test_message_tool_suppress to mock chat_with_retry (not chat) and use non-blank final response to avoid runner empty-retry Made-with: Cursor
feat: merge upstream HKUDS/nanobot v0.1.5
- Implement PendingAction confirmation flow in runner/loop for requires_confirmation tools (exec, write_file, edit_file) - Block dangerous tools from /agent/execute-tool direct invocation - Require NANOBOT_API_KEY for gateway mode; use constant-time comparison - Default exec tool to disabled; default restrict_to_workspace to true - Add --unshare-net to bwrap sandbox for network isolation - Minimize /dev mount in bwrap to /dev/null only - Bind gateway port to 127.0.0.1 in docker-compose - Remove SYS_ADMIN and seccomp/apparmor=unconfined from defaults - Fix SSRF: validate_resolved_url now denies on resolution failure - Return pinned resolved IPs from validate_url_target for DNS pinning - Update all callers for new validate_url_target signature - Redact user message content from API logs Made-with: Cursor
Contributor
|
Safety issues are indeed very important. |
Author
|
sorry, my agent accidentally opened this PR on this repo instead of my fork. a lesson to always check the commands i let my agents run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Comprehensive security hardening across nanobot to prepare for external deployment where untrusted users may attempt prompt injection, command execution, or network pivoting.
Critical
PendingActionconfirmation inAgentRunner._run_tool()— tools withrequires_confirmation=Truenow queue for user approval instead of executing immediately whenconfirmation_supported=Trueexec,write_file,edit_file,read_file, MCP tools) from direct invocation via/agent/execute-toolHigh
NANOBOT_API_KEYis now mandatory for gateway mode (exit 1 if unset)hmac.compare_digestfor API key comparisonExecToolConfig.enabledefaults toFalserestrict_to_workspacedefaults toTrue--unshare-netto bwrap for network isolation; minimize/devmountMedium
SYS_ADMIN+seccomp/apparmor=unconfineddefaults from docker-compose; bind gateway to127.0.0.1validate_resolved_urlnow denies on DNS resolution failure;validate_url_targetreturns pinned IPs for DNS rebinding protectionTest plan
NANOBOT_API_KEY/agent/execute-toolreturns 403 forexec,write_file, MCP toolsrequires_confirmationtools queue PendingAction whenconfirmation_supported=TrueMade with Cursor