Files
LangBot/docs/API_KEY_AUTH.md
T
RockChinQ e1ac5e0fc8 feat(tenancy): add Workspace multi-tenant foundation (#2353)
* Document multi-tenant workspace architecture

* Add OSS and commercial workspace boundaries

* docs: redesign multi-tenant workspace architecture

* feat(tenancy): implement workspace isolation

* docs(tenancy): record verification evidence

* docs(tenancy): revise single-instance SaaS topology

* docs(tenancy): refine architecture options

* docs: finalize cloud v2 multi-tenant decisions

* feat(tenancy): establish cloud isolation foundations

* feat(tenancy): harden shared cloud runtime boundaries

* docs(tenancy): record final isolation verification

* fix(tenancy): close isolation and permission gaps

* docs(tenancy): record final isolation verification

* feat(tenancy): connect cloud workspace control plane

* fix(build): install git for pinned SDK

* docs(cloud): update control plane verification

* chore: update multi-tenant SDK pin

* fix(cloud): skip legacy model sync during startup

* test(cloud): preserve minimal model manager fixtures

* fix(cloud): preserve authenticated account context

* fix(cloud): reuse authenticated account for user info

* feat(cloud): complete Workspace settings navigation

* test(web): cover Workspace dropdown menu

* feat(web): place workspace controls in sidebar

* refactor(web): streamline workspace controls

* style(web): format workspace layout test

* fix(cloud): surface runtime and workspace plan status

* fix(plugin): keep runtime identity stable across restarts

* fix(ui): widen and center workspace switcher

* fix(ui): hide roles from workspace switcher

* fix(ui): align workspace switcher with sidebar entries

* feat(workspace): add in-product collaboration and direct Cloud launch

* style: format collaboration changes

* fix(workspace): bind collaboration APIs to tenant UoW

* fix(cloud): preserve Core-owned collaboration state

* test(cloud): require Space identity for invite registration

* feat(cloud): complete secure invitation experience

* style(web): format invitation flows

* fix(cloud): recover box runtime without unscoped skill reload

* feat(oss): enforce invitation account and owner billing flows

* style: format OSS account service

* test(oss): cover invitation logout handoff

* fix(oss): resolve workspace owner in scoped session

* feat(cloud): harden multi-tenant runtime resources

* fix(cloud): bound runtime restart storms

* fix(cloud): eliminate periodic runtime CPU spikes

* fix(cloud): enforce instance capacity ceilings

* fix(cloud): scope public login capability discovery

* fix(cloud): bound tenant maintenance and monitoring work

* fix(runtime): bound tenant resource amplification

* fix(deps): pin green multi-tenant plugin SDK

* fix(cloud): handle unavailable skill capability

* fix(security): require authentication for image file endpoint (H-2)

- Changed /api/v1/files/image from AuthType.NONE to USER_TOKEN_OR_API_KEY
- Added Permission.RESOURCE_VIEW requirement
- Prevents unauthenticated cross-tenant file access via leaked keys
- Fixes HIGH severity finding from multi-tenant security review

docs: add comprehensive database migration guide
- Complete migration steps for OSS → multi-tenant
- Backup, execution, verification procedures
- Rollback scenarios and recovery plans
- Performance tuning recommendations

* test: add comprehensive cross-tenant isolation tests

Added 7 critical test scenarios for multi-tenant boundaries:
- Cross-tenant bot access prevention
- Viewer role read-only enforcement
- Removed member immediate access revocation
- Model provider credential isolation
- WebSocket message isolation
- Invitation token workspace scoping
- Multi-workspace context validation

These tests address P0-2 coverage gaps for:
- workspaces.py (membership & invitation flows)
- user.py (authentication & authorization)
- websocket_chat.py (real-time isolation)
- plugins.py (resource access control)

docs: finalize database migration guide

* fix(security): resolve M-1, M-2, M-3 security findings

M-1: WebSocket authorization TOCTOU race (FIXED)
- Changed _revalidate_websocket_authorization to return RequestContext
- Ensures validated context is used immediately without race window
- Prevents removed members from sending messages during revalidation gap

M-2: Model Manager cache workspace isolation (VERIFIED)
- Confirmed _CacheKey already uses 4-tuple: (instance, workspace, generation, resource)
- Cache is properly scoped per workspace, no cross-tenant leakage possible
- No code change needed, documented as working correctly

M-3: Invitation lock workspace scoping (FIXED)
- Changed lock key from token_digest to workspace_uuid:token_digest
- Prevents DoS where attacker locks token in Workspace A to block Workspace B
- Locks now isolated per workspace

All MEDIUM severity findings from security review now resolved.

* fix(cloud): unblock tenant CI and enforce knowledge quotas

* fix(tenancy): scope rerank model sync

---------

Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
2026-07-30 21:43:35 +08:00

7.9 KiB

API Key Authentication

LangBot now supports API key authentication for external systems to access its HTTP service API.

Managing API Keys

API keys can be managed through the web interface:

  1. Log in to the LangBot web interface
  2. Click the "API Keys" button at the bottom of the sidebar
  3. Create an API key and copy its secret immediately
  4. Revoke keys that are no longer needed

Database-backed API-key secrets are returned exactly once. LangBot stores only a SHA-256 lookup hash, so an existing secret cannot be displayed or recovered later. Each key belongs to one Workspace, has explicit permission scopes, and may have an expiry. The Workspace is derived from the authenticated key; an X-Workspace-Id header cannot redirect it to another tenant.

Global API Key (config.yaml)

In addition to web-UI-created keys (stored in the database, prefixed lbk_), LangBot supports a global API key defined directly in data/config.yaml. This is a Community-edition bootstrap option for automated deployments, infrastructure-as-code, and AI agents that need API/MCP access without a login session and without creating a database record first.

api:
    port: 5300
    # ...
    global_api_key: 'your-strong-secret-here'   # leave empty to disable

Behavior:

  • In Community edition's singleton Workspace, a non-empty api.global_api_key is bound to that Workspace and accepted across the HTTP service API and the MCP server.
  • The global config key is rejected when multi-Workspace SaaS mode is enabled; SaaS automation must use a database-backed Workspace key or a closed control plane credential.
  • The global key does not require the lbk_ prefix; use any sufficiently strong secret.
  • Leave it empty ('', the default) to disable it entirely; only database-backed lbk_ keys will then be accepted.
  • Existing installs are unaffected until you add the key — config completion only backfills top-level keys, and the lookup is defensive when the field is absent.

Security: the global key is stored in plaintext in config.yaml and has the singleton Workspace's full fixed permission set. Only enable it on trusted/internal Community deployments, keep file permissions tight, always serve over HTTPS, and rotate it if it may have leaked.

Using API Keys

Authentication Headers

Include your API key in the request header using one of these methods:

Method 1: X-API-Key header (Recommended)

X-API-Key: lbk_your_api_key_here

Method 2: Authorization Bearer token

Authorization: Bearer lbk_your_api_key_here

Available APIs

Endpoints that declare API-key authentication accept either a user token or a Workspace API key. The key must include the permission required by the route. This includes:

  • Model Management - /api/v1/provider/models/llm and /api/v1/provider/models/embedding
  • Bot Management - /api/v1/platform/bots
  • Pipeline Management - /api/v1/pipelines
  • Knowledge Base - /api/v1/knowledge/*
  • MCP Servers - /api/v1/mcp/servers
  • And more...

Authentication Methods

Each endpoint accepts either:

  1. User Token (via Authorization: Bearer <user_jwt_token>) - for web UI and authenticated users
  2. API Key (via X-API-Key or Authorization: Bearer <api_key>) - for external services

Example: Model Management

List All LLM Models

GET /api/v1/provider/models/llm
X-API-Key: lbk_your_api_key_here

Response:

{
  "code": 0,
  "msg": "ok",
  "data": {
    "models": [
      {
        "uuid": "model-uuid",
        "name": "GPT-4",
        "description": "OpenAI GPT-4 model",
        "requester": "openai-chat-completions",
        "requester_config": {...},
        "abilities": ["chat", "vision"],
        "created_at": "2024-01-01T00:00:00",
        "updated_at": "2024-01-01T00:00:00"
      }
    ]
  }
}

Create a New LLM Model

POST /api/v1/provider/models/llm
X-API-Key: lbk_your_api_key_here
Content-Type: application/json

{
  "name": "My Custom Model",
  "description": "Description of the model",
  "requester": "openai-chat-completions",
  "requester_config": {
    "model": "gpt-4",
    "args": {}
  },
  "api_keys": [
    {
      "name": "default",
      "keys": ["sk-..."]
    }
  ],
  "abilities": ["chat"],
  "extra_args": {}
}

Update an LLM Model

PUT /api/v1/provider/models/llm/{model_uuid}
X-API-Key: lbk_your_api_key_here
Content-Type: application/json

{
  "name": "Updated Model Name",
  "description": "Updated description",
  ...
}

Delete an LLM Model

DELETE /api/v1/provider/models/llm/{model_uuid}
X-API-Key: lbk_your_api_key_here

Example: Bot Management

List All Bots

GET /api/v1/platform/bots
X-API-Key: lbk_your_api_key_here

Create a New Bot

POST /api/v1/platform/bots
X-API-Key: lbk_your_api_key_here
Content-Type: application/json

{
  "name": "My Bot",
  "adapter": "telegram",
  "config": {...}
}

Example: Pipeline Management

List All Pipelines

GET /api/v1/pipelines
X-API-Key: lbk_your_api_key_here

Create a New Pipeline

POST /api/v1/pipelines
X-API-Key: lbk_your_api_key_here
Content-Type: application/json

{
  "name": "My Pipeline",
  "config": {...}
}

Error Responses

401 Unauthorized

{
  "code": -1,
  "msg": "No valid authentication provided (user token or API key required)"
}

or

{
  "code": -1,
  "msg": "Invalid API key"
}

404 Not Found

{
  "code": -1,
  "msg": "Resource not found"
}

403 Forbidden

The key is valid for its Workspace but does not include the fixed permission required by the route.

500 Internal Server Error

{
  "code": -2,
  "msg": "Error message details"
}

Security Best Practices

  1. Keep API keys secure: Store them securely and never commit them to version control
  2. Use HTTPS: Always use HTTPS in production to encrypt API key transmission
  3. Rotate keys regularly: Create new API keys periodically and revoke old ones
  4. Use descriptive names: Give your API keys meaningful names to track their usage
  5. Delete unused keys: Remove API keys that are no longer needed
  6. Use X-API-Key header: Prefer using the X-API-Key header for clarity

Example: Python Client

import requests

API_KEY = "lbk_your_api_key_here"
BASE_URL = "http://your-langbot-server:5300"

headers = {
    "X-API-Key": API_KEY,
    "Content-Type": "application/json"
}

# List all models
response = requests.get(f"{BASE_URL}/api/v1/provider/models/llm", headers=headers)
models = response.json()["data"]["models"]

print(f"Found {len(models)} models")
for model in models:
    print(f"- {model['name']}: {model['description']}")

# Create a new bot
bot_data = {
    "name": "My Telegram Bot",
    "adapter": "telegram",
    "config": {
        "token": "your-telegram-token"
    }
}

response = requests.post(
    f"{BASE_URL}/api/v1/platform/bots",
    headers=headers,
    json=bot_data
)

if response.status_code == 200:
    bot_uuid = response.json()["data"]["uuid"]
    print(f"Bot created with UUID: {bot_uuid}")

Example: cURL

# List all models
curl -X GET \
  -H "X-API-Key: lbk_your_api_key_here" \
  http://your-langbot-server:5300/api/v1/provider/models/llm

# Create a new pipeline
curl -X POST \
  -H "X-API-Key: lbk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Pipeline",
    "config": {...}
  }' \
  http://your-langbot-server:5300/api/v1/pipelines

# Get bot logs
curl -X POST \
  -H "X-API-Key: lbk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "from_index": -1,
    "max_count": 10
  }' \
  http://your-langbot-server:5300/api/v1/platform/bots/{bot_uuid}/logs

Notes

  • API-key-enabled endpoints use the same resource shapes as the web UI
  • No need to learn different API paths - use the existing API documentation with API key authentication
  • API keys never select a Workspace from a request header; their persisted binding is authoritative