docs: update serve api key requirement

maintainer edit: Align OpenAI-compatible API docs and examples with the new fail-closed api.api_key requirement while keeping /health documented as unauthenticated.
This commit is contained in:
chengyongru
2026-07-08 12:16:12 +08:00
committed by Xubin Ren
parent 460c62c0b0
commit 28141ce20b
4 changed files with 22 additions and 12 deletions
+1 -1
View File
@@ -107,7 +107,7 @@ File operations have path traversal protection, but:
**API Calls:** **API Calls:**
- All external API calls use HTTPS by default - All external API calls use HTTPS by default
- Timeouts are configured to prevent hanging requests - Timeouts are configured to prevent hanging requests
- The OpenAI-compatible API server must set `api.api_key` when binding to `0.0.0.0` or `::`; otherwise startup fails to prevent unauthenticated network access - The OpenAI-compatible API server requires `api.api_key` for API routes; only `/health` remains unauthenticated for probes and load balancers
- Consider using a firewall to restrict outbound connections if needed - Consider using a firewall to restrict outbound connections if needed
**WhatsApp:** **WhatsApp:**
+2
View File
@@ -204,6 +204,8 @@ Default API endpoint:
http://127.0.0.1:8900 http://127.0.0.1:8900
``` ```
`nanobot serve` requires `api.apiKey`; send it as a Bearer token on API routes.
See [`openai-api.md`](./openai-api.md) for request examples. See [`openai-api.md`](./openai-api.md) for request examples.
## Status ## Status
+18 -10
View File
@@ -5,33 +5,32 @@ nanobot can expose a minimal OpenAI-compatible endpoint for local integrations:
```bash ```bash
nanobot plugins enable api nanobot plugins enable api
nanobot agent -m "Hello!" nanobot agent -m "Hello!"
# Set api.apiKey first; see Authentication below.
nanobot serve nanobot serve
``` ```
Run the CLI check first. If `nanobot agent -m "Hello!"` fails, fix provider or config setup before debugging the API server. By default, the API binds to `127.0.0.1:8900`. You can change this in `config.json`. Run the CLI check first. If `nanobot agent -m "Hello!"` fails, fix provider or config setup before debugging the API server. By default, the API binds to `127.0.0.1:8900`. You can change this in `config.json`. `nanobot serve` requires `api.apiKey`; set it before starting the server.
For setup help, see [`quick-start.md`](./quick-start.md), [`providers.md`](./providers.md), and [`troubleshooting.md`](./troubleshooting.md). For setup help, see [`quick-start.md`](./quick-start.md), [`providers.md`](./providers.md), and [`troubleshooting.md`](./troubleshooting.md).
## Authentication ## Authentication
Local-only `127.0.0.1` usage does not require an API key. If you bind the API `nanobot serve` requires `api.apiKey` for all API binds. Without it, startup
server to all interfaces with `api.host: "0.0.0.0"` or `"::"`, nanobot requires fails before the agent is initialized. Keep the key secret and send it as a
`api.apiKey`; otherwise startup fails to avoid exposing an unauthenticated agent Bearer token on API routes.
endpoint on the network.
```json ```json
{ {
"api": { "api": {
"host": "0.0.0.0", "host": "127.0.0.1",
"port": 8900, "port": 8900,
"apiKey": "${NANOBOT_API_KEY}" "apiKey": "${NANOBOT_API_KEY}"
} }
} }
``` ```
When `api.apiKey` is set, send it as a Bearer token on API routes. The health The health endpoint remains unauthenticated so local probes and load balancers
endpoint remains unauthenticated so local probes and load balancers can still can still check process health.
check process health.
```bash ```bash
curl http://127.0.0.1:8900/v1/models \ curl http://127.0.0.1:8900/v1/models \
@@ -70,6 +69,7 @@ If `channel` points to a channel that is not enabled in your config, nanobot wil
```bash ```bash
curl http://127.0.0.1:8900/v1/chat/completions \ curl http://127.0.0.1:8900/v1/chat/completions \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-H "Authorization: Bearer $NANOBOT_API_KEY" \
-d '{ -d '{
"messages": [{"role": "user", "content": "hi"}], "messages": [{"role": "user", "content": "hi"}],
"session_id": "my-session" "session_id": "my-session"
@@ -83,6 +83,7 @@ Send images inline using the OpenAI multimodal content format:
```bash ```bash
curl http://127.0.0.1:8900/v1/chat/completions \ curl http://127.0.0.1:8900/v1/chat/completions \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-H "Authorization: Bearer $NANOBOT_API_KEY" \
-d '{ -d '{
"messages": [{"role": "user", "content": [ "messages": [{"role": "user", "content": [
{"type": "text", "text": "Describe this image"}, {"type": "text", "text": "Describe this image"},
@@ -98,11 +99,13 @@ Upload any supported file type (images, PDF, Word, Excel, PPT) via multipart:
```bash ```bash
# Single file # Single file
curl http://127.0.0.1:8900/v1/chat/completions \ curl http://127.0.0.1:8900/v1/chat/completions \
-H "Authorization: Bearer $NANOBOT_API_KEY" \
-F "message=Summarize this report" \ -F "message=Summarize this report" \
-F "files=@report.docx" -F "files=@report.docx"
# Multiple files with session isolation # Multiple files with session isolation
curl http://127.0.0.1:8900/v1/chat/completions \ curl http://127.0.0.1:8900/v1/chat/completions \
-H "Authorization: Bearer $NANOBOT_API_KEY" \
-F "message=Compare these files" \ -F "message=Compare these files" \
-F "files=@chart.png" \ -F "files=@chart.png" \
-F "files=@data.xlsx" \ -F "files=@data.xlsx" \
@@ -117,10 +120,13 @@ Supported file types:
## Python (`requests`) ## Python (`requests`)
```python ```python
import os
import requests import requests
resp = requests.post( resp = requests.post(
"http://127.0.0.1:8900/v1/chat/completions", "http://127.0.0.1:8900/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['NANOBOT_API_KEY']}"},
json={ json={
"messages": [{"role": "user", "content": "hi"}], "messages": [{"role": "user", "content": "hi"}],
"session_id": "my-session", # optional: isolate conversation "session_id": "my-session", # optional: isolate conversation
@@ -134,11 +140,13 @@ print(resp.json()["choices"][0]["message"]["content"])
## Python (`openai`) ## Python (`openai`)
```python ```python
import os
from openai import OpenAI from openai import OpenAI
client = OpenAI( client = OpenAI(
base_url="http://127.0.0.1:8900/v1", base_url="http://127.0.0.1:8900/v1",
api_key="dummy", api_key=os.environ["NANOBOT_API_KEY"],
) )
resp = client.chat.completions.create( resp = client.chat.completions.create(
+1 -1
View File
@@ -404,7 +404,7 @@ def create_app(
agent_loop: An initialized AgentLoop instance. agent_loop: An initialized AgentLoop instance.
model_name: Model name reported in responses. model_name: Model name reported in responses.
request_timeout: Per-request timeout in seconds. request_timeout: Per-request timeout in seconds.
api_key: Optional API key for Bearer-token authentication. api_key: API key for Bearer-token authentication on API routes.
""" """
app = web.Application(client_max_size=20 * 1024 * 1024) # 20MB for base64 images app = web.Application(client_max_size=20 * 1024 * 1024) # 20MB for base64 images
app["agent_loop"] = agent_loop app["agent_loop"] = agent_loop