跳转到主要内容

概述

关于 HTTP 请求头和示例,请参见 /cn/api/rest/authentication
Shannon 支持 API 密钥认证以保护对编排平台的访问。为了方便本地开发,身份验证默认禁用,可在生产部署时启用。

认证模式

开发模式(默认)

# 在 .env 文件中
GATEWAY_SKIP_AUTH=1
在开发模式下:
  • 不需要 API 密钥
  • 所有请求都被接受
  • 适用于本地测试和开发

生产模式

# 在 .env 文件中
GATEWAY_SKIP_AUTH=0
在生产模式下:
  • 所有请求都需要 API 密钥
  • 无效的密钥返回 401 Unauthorized
  • 对每个密钥实施速率限制

API 密钥格式

Shannon 使用带前缀的 API 密钥:
sk_test_1234567890abcdef    # 测试密钥
sk_live_1234567890abcdef    # 生产密钥
切勿将 API 密钥提交到版本控制系统或公开分享。

创建 API 密钥

通过命令行

# 创建测试 API 密钥(从仓库根目录运行)
make seed-api-key

# 输出
 Test API key created. Use 'sk_test_123456' for testing.
Note: Authentication is disabled by default (GATEWAY_SKIP_AUTH=1)

通过 API(未来版本)

curl -X POST http://localhost:8080/api/v1/keys \
  -H "X-Admin-Token: admin-secret" \
  -d '{
    "name": "My Application",
    "user_id": "user-123"
  }'

速率限制

Shannon 使用固定窗口计数器对每个 API 密钥实施速率限制:

默认限制

限制类型默认值
每分钟请求数60
突发容许值10
Token 预算和并发任务限制由编排器在工作流层级实施,而非在网关层。

速率限制标头

响应包含当前窗口限制。当返回 429 时,会设置 Retry-After:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1730001234

超过速率限制

当您超过速率限制时:
HTTP/1.1 429 Too Many Requests
Retry-After: 30

{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Please retry after the rate limit window resets."
}

处理速率限制

实施指数退避:
import time
import requests
from requests.exceptions import HTTPError

def submit_with_retry(query, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = requests.post(
                "http://localhost:8080/api/v1/tasks",
                headers={"X-API-Key": "sk_test_123456"},
                json={"query": query}
            )
            response.raise_for_status()
            return response.json()

        except HTTPError as e:
            if e.response.status_code == 429:
                retry_after = int(e.response.headers.get('Retry-After', 60))
                print(f"Rate limited. Retrying after {retry_after}s...")
                time.sleep(retry_after)
            else:
                raise

    raise Exception("Max retries exceeded")

多租户

Shannon 支持具有租户隔离的多租户部署:

租户 ID

在请求中包含租户 ID:
curl -X POST http://localhost:8080/api/v1/tasks \
  -H "X-API-Key: sk_test_123456" \
  -H "X-Tenant-ID: org-acme" \
  -H "Content-Type: application/json" \
  -d '{"query": "Process data"}'

租户隔离

每个租户都有:
  • 隔离的会话存储
  • 通过共享 Qdrant 集合中的负载过滤器(tenant_id)实现的每租户隔离
  • 独立的预算跟踪
  • 专用指标

OPA 策略执行

Shannon 使用 Open Policy Agent 进行细粒度访问控制:

策略结构

package shannon.auth

import future.keywords.if

# Default deny
default allow = false

# Allow if user has valid API key and appropriate permissions
allow if {
    input.api_key_valid
    input.user.team in ["engineering", "data-science"]
    input.task.mode in allowed_modes[input.user.team]
}

# Team-specific allowed modes
allowed_modes := {
    "engineering": ["simple", "standard", "complex"],
    "data-science": ["standard", "complex"]
}

# Token budget limits by team
max_tokens[team] := 50000 if team == "data-science"
max_tokens[team] := 10000 if team == "engineering"

策略模式

config/shannon.yaml 中配置:
policy:
  enabled: true
  mode: "enforce"  # dry-run, enforce, off
  path: "/app/config/opa/policies"
  fail_closed: false  # Allow on policy errors
模式:
  • enforce: 拒绝违反策略的请求
  • dry-run: 记录违规但允许请求
  • off: 禁用策略执行

示例: 限制模型

package shannon.models

# Only allow specific models per team
allowed_models[user.team] contains model if {
    user.team == "cost-sensitive"
    model in ["gpt-5-mini", "claude-haiku"]
}

allowed_models[user.team] contains model if {
    user.team == "premium"
    model in ["gpt-5-thinking", "claude-opus", "gpt-5", "claude-sonnet"]
}

安全最佳实践

1. 定期轮换密钥

# 创建新密钥
make seed-api-key

# 用新密钥更新应用程序
# 迁移后撤销旧密钥

2. 使用环境变量

import os
from shannon import ShannonClient

client = ShannonClient(
    base_url=os.environ["SHANNON_BASE_URL"],
    api_key=os.environ["SHANNON_API_KEY"],
)

3. 在生产环境中启用 HTTPS

# config/shannon.yaml
gateway:
  tls:
    enabled: true
    cert_file: "/path/to/cert.pem"
    key_file: "/path/to/key.pem"

4. 监控 API 密钥使用情况

在 Prometheus 指标中跟踪使用情况:
# Requests per API key
sum by (api_key_id) (rate(shannon_gateway_requests_total[5m]))

# Errors by API key
sum by (api_key_id) (rate(shannon_gateway_errors_total[5m]))

5. 实施 IP 白名单

# config/shannon.yaml
gateway:
  ip_whitelist:
    enabled: true
    allowed_ips:
      - "10.0.0.0/8"
      - "192.168.1.100"

故障排除

原因: 缺少或无效的 API 密钥解决方案:
# 验证是否启用了身份验证
grep GATEWAY_SKIP_AUTH .env

# 如果已启用,检查您的 API 密钥
curl -H "X-API-Key: sk_test_123456" \
  http://localhost:8080/api/v1/tasks
原因: API 密钥有效但权限不足(OPA 策略)解决方案: 检查 OPA 策略日志:
docker compose logs orchestrator | grep "policy"
原因: 超过速率限制解决方案: 实施带指数退避的重试逻辑:
retry_after = response.headers.get('Retry-After', 60)
time.sleep(int(retry_after))
原因: 密钥可能已过期或被撤销解决方案: 创建新的测试密钥:
make seed-api-key

下一步