Best Practices for nanobot Config: Secure Setup and Optimization Guide

The most secure way to configure nanobot is to store API keys in environment variables referenced via ${VAR} syntax in ~/.nanobot/config.json, enable workspace restrictions, and use named model presets for consistent agent behavior across the HKUDS/nanobot deployment.

Configuring nanobot properly ensures your AI agents operate securely and efficiently. The HKUDS/nanobot repository uses a Pydantic-based configuration system centered in nanobot.config.schema.Config that loads from ~/.nanobot/config.json (or a custom path set via nanobot.config.loader.set_config_path) and supports environment variable substitution for sensitive values.

Understanding the Configuration Architecture

The nanobot configuration system consists of two core components in nanobot/config/. The nanobot.config.schema module defines the Config class using Pydantic validation, while nanobot.config.loader handles file I/O, environment variable resolution, and persistence.

When nanobot starts, it calls load_config() from nanobot/config/loader.py, which reads the JSON file and validates it against the schema. The loader also resolves ${VAR_NAME} placeholders using resolve_config_env_vars() before the configuration object is instantiated.

Securing Credentials with Environment Variables

Never commit API keys to version control. Instead, use environment variable substitution syntax in your JSON configuration.

Set your secrets in your shell:

export OPENAI_API_KEY="sk-xxxxxxxxxxxx"
export GROQ_API_KEY="gsk-xxxxxxxxxxxx"
export MYPROXY_KEY="custom-key-here"

Then reference them in ~/.nanobot/config.json:

{
  "providers": {
    "openai": { "api_key": "${OPENAI_API_KEY}" },
    "groq": { "api_key": "${GROQ_API_KEY}" },
    "custom": {
      "myproxy": {
        "api_key": "${MYPROXY_KEY}",
        "api_base": "https://proxy.example.com/v1"
      }
    }
  }
}

The loader safely resolves these at runtime via resolve_config_env_vars() defined in nanobot/config/loader.py, keeping credentials out of your configuration files.

Configuring Agents and Model Presets

The agents.defaults section in nanobot/config/schema.py (lines 19-53) controls global agent behavior through the AgentDefaults model.

Recommended settings:

  • Workspace isolation: Set agents.defaults.workspace to ~/.nanobot/workspace or a dedicated project directory to contain all file operations.
  • Model presets: Define reusable configurations under model_presets and reference them via agents.defaults.model_preset instead of hardcoding model names.
  • Iteration limits: Keep max_tool_iterations at the default 200 unless your workflows specifically require higher limits.
  • Dream memory: Enable dream.enabled only if you need periodic memory consolidation, as it increases resource usage.

Example configuration:

{
  "agents": {
    "defaults": {
      "workspace": "~/.nanobot/workspace",
      "model_preset": "fast",
      "max_tool_iterations": 200,
      "dream": { "enabled": false }
    }
  },
  "model_presets": {
    "fast": {
      "model": "gpt-4o-mini",
      "provider": "openai",
      "max_tokens": 4096,
      "temperature": 0.2
    }
  }
}

Provider Management and Auto-Detection

The ProvidersConfig class in nanobot/config/schema.py (lines 26-78) manages LLM credentials. Use the auto provider detection feature unless you require a specific endpoint; the system maps model names to providers automatically via Config._match_provider in nanobot/providers/registry.py.

When adding custom providers, place them under providers.custom with unique names to avoid clashes with built-in providers like openai or groq.

Tool Security and MCP Server Configuration

The ToolsConfig section (lines 67-100 in nanobot/config/schema.py) controls file system access and network security.

Critical security practices:

  • Workspace restriction: Set tools.restrict_to_workspace = true to prevent agents from accessing files outside the designated workspace.
  • Local service access: When exposing the WebUI to the internet, set tools.webui_allow_local_service_access = false unless you explicitly trust local services.
  • SSRF protection: Populate tools.ssrf_whitelist with internal CIDR blocks (e.g., ["100.64.0.0/10"] for Tailscale) only if you need to allow server-side request forgery for trusted internal services.

For MCP servers (Model Context Protocol), list each server under tools.mcp_servers with its type (stdio, SSE, or HTTP), command or url, and optional environment variables. Restrict exposed tools using enabled_tools: use ["*"] for all tools or ["specific_tool"] for a whitelist.

API and Gateway Hardening

The ApiConfig and GatewayConfig classes (lines 17-26 and 36-44 in nanobot/config/schema.py) control network exposure.

  • Bind address: Always bind the API to 127.0.0.1 unless deliberately exposing it externally. If binding to 0.0.0.0, you must set a non-empty api.api_key.
  • Gateway isolation: For production deployments, consider running the gateway on a separate host and update gateway.port accordingly.

Transcription and Resource Limits

Enable transcription globally via transcription.enabled = true and select a provider (groq, assemblyai, etc.) that matches your latency requirements. Set max_duration_sec and max_upload_mb to limit resource consumption for audio processing.

Validation and Deployment Workflow

Use the CLI workflow to manage configuration changes safely:

  1. Edit: Run nanobot config edit or manually modify ~/.nanobot/config.json.
  2. Validate: Execute nanobot config validate to trigger Pydantic validation via load_config().
  3. Apply: Restart the gateway or reload via the API endpoint /reload to apply changes.

Programmatically modify configurations using the Python API:

from nanobot.config.loader import load_config, save_config, resolve_config_env_vars

cfg = load_config()                     # loads ~/.nanobot/config.json

cfg = resolve_config_env_vars(cfg)      # resolves ${VAR} placeholders

# Update workspace and model preset

cfg.agents.defaults.workspace = "~/my_projects/nanobot_ws"
cfg.agents.defaults.model_preset = "fast"

# Add custom provider

cfg.providers.custom = cfg.providers.custom or {}
cfg.providers.custom["myproxy"] = {
    "api_key": "${MYPROXY_KEY}",
    "api_base": "https://myproxy.example.com/v1"
}

save_config(cfg)                        # persists to disk

Summary

  • Store all API keys in environment variables and reference them with ${VAR_NAME} syntax in ~/.nanobot/config.json to keep secrets out of version control.
  • Enable tools.restrict_to_workspace to prevent file system escape vulnerabilities.
  • Use named model_presets for consistent agent behavior and easier environment switching.
  • Bind the API to 127.0.0.1 and require authentication when exposing services to untrusted networks.
  • Validate configurations using nanobot config validate before restarting services.
  • Reload configurations via the /reload API endpoint or gateway restart to apply changes.

Frequently Asked Questions

Where does nanobot store its configuration file?

By default, nanobot stores configuration in ~/.nanobot/config.json. You can customize this path programmatically using nanobot.config.loader.set_config_path() before calling load_config(), or by setting the appropriate environment variable if supported by your deployment wrapper.

How do I securely manage API keys in nanobot config?

Use the ${ENV_VAR} syntax inside your JSON configuration file. The loader function resolve_config_env_vars() in nanobot/config/loader.py substitutes these placeholders with actual values from your environment at runtime. This approach ensures that sensitive credentials never appear in plain text within your configuration files or version control history.

Set tools.restrict_to_workspace = true in your configuration. This enforces that all file operations remain within the directory specified by agents.defaults.workspace (defaulting to ~/.nanobot/workspace). Additionally, avoid running nanobot with elevated privileges, and ensure the workspace directory has appropriate filesystem permissions.

How do I validate my nanobot configuration before starting the service?

Run the command nanobot config validate from your terminal. This command invokes load_config() from nanobot/config/loader.py, which performs Pydantic validation against the schema defined in nanobot/config/schema.py. If validation fails, the command returns detailed error messages indicating which fields contain invalid values or type mismatches.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →