Skip to content

Authentication

The NimbleBrain API authenticates requests using a shared secret set in the NB_API_KEY environment variable. You can pass this key as a Bearer token or exchange it for an HttpOnly session cookie.

Include the API key in the Authorization header:

Terminal window
curl http://localhost:3000/v1/workspace \
-H "Authorization: Bearer your-secret-key"

The server performs a constant-time comparison against NB_API_KEY. If the key does not match, the server returns 401 with an empty body.

For browser-based clients, exchange the API key for an HttpOnly cookie using the login endpoint. The cookie is automatically sent on subsequent requests.

Validate the API key and receive a session cookie.

Request body:

FieldTypeRequiredDescription
keystringYesThe API key to validate

Response:

{
"ok": true
}

On success, the response includes a Set-Cookie header:

Set-Cookie: nb_session=<key>; HttpOnly; SameSite=Strict; Path=/; Max-Age=604800

Cookie properties:

  • HttpOnly — not accessible from JavaScript
  • SameSite=Strict — only sent on same-site requests
  • Secure — set when the server is not running on localhost
  • Max-Age=604800 — 7-day expiry

Error responses:

StatusCondition
400Missing or non-string key field
401Key does not match NB_API_KEY

Example:

Terminal window
curl -X POST http://localhost:3000/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"key": "your-secret-key"}' \
-c cookies.txt

Clear the session cookie. Requires authentication.

Response:

{
"ok": true
}

The response sets the cookie’s Max-Age to 0, which instructs the browser to delete it.

Example:

Terminal window
curl -X POST http://localhost:3000/v1/auth/logout \
-H "Authorization: Bearer your-secret-key"

Check whether the current session is valid. Requires authentication. Returns 200 if authenticated, 401 otherwise.

Response:

{
"authenticated": true
}

Example:

Terminal window
curl http://localhost:3000/v1/auth/session \
-b cookies.txt

When both a Bearer token and a session cookie are present, the Bearer token takes precedence. The server checks the Authorization header first, then falls back to the nb_session cookie.

  • Minimum length: 8 characters
  • Keys shorter than 16 characters produce a startup warning
  • The server refuses to start if the key is shorter than 8 characters

CORS behavior is determined by NB_API_KEY and ALLOWED_ORIGINS:

NB_API_KEYALLOWED_ORIGINSBehavior
Not setN/AAccess-Control-Allow-Origin: * (dev mode)
SetSet (comma-separated)Only matching origins get CORS headers with credentials: true
SetNot setSame-origin only (no CORS headers)

Set ALLOWED_ORIGINS as a comma-separated list of origins:

Terminal window
export ALLOWED_ORIGINS="https://app.example.com,https://staging.example.com"

The server always responds to OPTIONS preflight requests with:

Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, Mcp-Session-Id, Last-Event-ID, Mcp-Protocol-Version
Access-Control-Expose-Headers: Mcp-Session-Id, Mcp-Protocol-Version

Every failed authentication attempt is logged to stderr with the client IP and timestamp:

[nimblebrain] AUTH FAIL ip=203.0.113.42 timestamp=2025-10-15T14:30:00.000Z