# Best Practices for nanobot Config: Secure Setup and Optimization Guide

> Master nanobot config best practices. Secure your setup using environment variables restricted workspaces and named model presets for optimized HKUDS/nanobot performance.

- Repository: [✨Data Intelligence Lab@HKU✨/nanobot](https://github.com/HKUDS/nanobot)
- Tags: best-practices
- Published: 2026-07-22

---

**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`](https://github.com/HKUDS/nanobot/blob/main/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:

```bash
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`:

```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`](https://github.com/HKUDS/nanobot/blob/main/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`](https://github.com/HKUDS/nanobot/blob/main/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:

```json
{
  "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`](https://github.com/HKUDS/nanobot/blob/main/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`](https://github.com/HKUDS/nanobot/blob/main/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`](https://github.com/HKUDS/nanobot/blob/main/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`](https://github.com/HKUDS/nanobot/blob/main/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:

```python
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`](https://github.com/HKUDS/nanobot/blob/main/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.

### What is the recommended way to restrict file system access for nanobot agents?

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`](https://github.com/HKUDS/nanobot/blob/main/nanobot/config/loader.py), which performs Pydantic validation against the schema defined in [`nanobot/config/schema.py`](https://github.com/HKUDS/nanobot/blob/main/nanobot/config/schema.py). If validation fails, the command returns detailed error messages indicating which fields contain invalid values or type mismatches.