Nanobot
Nanobot’s wider channel surface sharpens its ownership boundary
Nanobot has an open report that provider keys can leak through process-global environment mutation. At the same time, Telegram gateway headers are becoming configurable and session search is intentionally widening across one owner’s persisted conversations.
HKUDS/nanobot issue #4784 is the inspected primary source: “Security: Provider API keys leaked between providers via global os.environ mutation.” The related records below were inspected as supporting context rather than independent confirmation.
The facts
- HKUDS/nanobot issue #4784 was created 2026-07-06T10:26:34Z and was open at inspection; its title is “Security: Provider API keys leaked between providers via global os.environ mutation.” - HKUDS/nanobot PR #4919 was created 2026-07-14T08:06:15Z and was open at inspection; its title is “feat(telegram): support custom Bot API base URL and extra headers.” - HKUDS/nanobot PR #5238 was created 2026-08-04T06:20:17Z and was open at inspection; its title is “refactor(session): remove request-scoped access grants.” - The repository reported 46618 stars, 771 open issues, default branch main, and last push 2026-08-04T14:04:22Z. - The latest tagged-release baseline checked was v0.3.0 published 2026-07-25T08:08:47Z.
What changed
HKUDS/nanobot issue #4784 reports: Summary OpenAICompatProvider._setup_env() writes provider API keys directly into the process-global os.environ dict. For gateway-type providers, os.environ[spec.env_key] = api_key **overwrites** any previous value. For non-gateway providers, os.environ.setdefault(spec.env_key, api_key) **leaves stale keys** from the first instantiated provider visible. In multi-provider configurations, keys can leak between provider instances. Affected Code nanobot/providers/openai_compat_provider.py:465-477 — _setup_env() mutates os.environ: Line 467: os.environ[spec.env_key] = api_key (overwrites for gateways) Line 471: os.environ.setdefault(spec.env_key, api_key) (first-write wins for non-gateways) Lines 475-477: env_extras also written to os.environ Root Cause Provider key management uses process-global os.environ as shared state. The setdefault pattern means the first provider to initialize "wins" for a given env key; the os.environ[key] = value pattern means the last gateway provider overwrites. Suggested Fix Use per-provider-instance state (self._api_key) rather than process-global env vars. If env vars are required by third-party SDKs, scope them with context variables or thread-local state that is set/restored around each provider call.
HKUDS/nanobot PR #4919 reports: Summary Implements #4702 — lets the Telegram channel target a self-hosted Bot API server or an enterprise gateway instead of the hardcoded https://api.telegram.org. Adds two optional fields to TelegramConfig: **api_base** — custom Bot API endpoint. Forwarded to both the send and polling HTTPXRequest pools as base_url. Leave unset to keep using the official API (default). **extra_headers** — extra HTTP headers appended to every Bot API request (e.g. an auth token for a corporate gateway). Mirrors the existing extra_headers field on the provider config for consistency. Why Some users sit behind regional or enterprise network setups where api.telegram.org is unreachable or must be routed through a private gateway. The channel already supports a SOCKS/HTTP proxy, but that doesn't cover self-hosted Telegram Bot API local servers or gateways that require custom request headers. python-telegram-bot's HTTPXRequest accepts both base_url and extra_headers natively, so this just wires the config through. Validation api_base is validated
HKUDS/nanobot PR #5238 reports: Summary remove the request-scoped Tool.available() layer introduced by #5211; Tool.enabled() remains the single construction-time switch delete the session-read grant and SessionAccessScope authorization abstraction let session tools search and read all persisted sessions owned by the personal assistant, while still excluding the current session keep selected-session mention normalization and runtime-context construction in the WebSocket channel instead of a tool runtime provider preserve existence/shape validation, bounded output, and filtering of hidden, tool, and private runtime messages Why nanobot is a personal assistant with one owner. Channel ingress (pairing, allowFrom, and WebUI bootstrap) decides whether a request may enter the agent loop; persisted conversations do not form a second per-channel or per-workspace authorization boundary. Encoding that policy in Tool made schemas request-dependent and coupled the tool abstraction to an ownership model the product does not have. Behavior This intentionally widens session history lookup: accepted requests can reference persisted sessions across channel and workspace
Why it matters
All three changes ask where authority lives: per-provider secrets, channel ingress, or the personal assistant owner. Process-global credentials are too broad even when session history is intentionally owner-wide. The operator test is whether persisted state, execution authority and the visible outcome describe the same event after retries, restarts or delegation.
Current
The primary record was open when captured on 2026-08-05. The release baseline was v0.3.0 published 2026-07-25T08:08:47Z. Repository metadata, pull requests, issues, release records, Google News discovery, Hacker News discovery, Lobsters, Metamesh and the rendered ClawCharts row were checked. ClawCharts selected the subject; it did not prove the claim.
Evidence
The primary URL is https://github.com/HKUDS/nanobot/issues/4784. Supporting records are https://github.com/HKUDS/nanobot/pull/4919 and https://github.com/HKUDS/nanobot/pull/5238. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts, reproductions and deployment observations remain attributed to their authors unless explicitly identified as independently rerun.
Source boundary
Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.
Operator take
Move provider credentials into instance state, treat custom Telegram headers as secrets, and document that accepted requests may search all owner-held sessions. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently after intervention.
Caveat
Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.
Source inspected; source state, environment and release boundary remain explicit.