openclaw/clawrouter
GitHub: openclaw/clawrouter
ClawRouter 是一个运行于 Cloudflare Workers 边缘的多提供商 API 网关,为 OpenClaw 服务统一代理密钥授权、预算计量和跨模型提供商路由。
Stars: 0 | Forks: 2
# ClawRouter
ClawRouter 是一个专为 OpenClaw 服务设计的高吞吐量 API 网关和提供商路由器。
它负责代理密钥、服务身份、版本化的上游授权(upstream grants)、预算,以及跨模型提供商、搜索 API、工具 API 和未来服务提供商的计量使用情况。
当前的实现目标:
- 基于 Cloudflare Workers 的 Rust/Wasm 数据平面
- Durable Object 预算账本
- 串行化的 Durable Object 访问控制授权机构
- TypeScript 管理/控制 UI
- 声明式服务提供商清单(manifests)
- OpenClaw 原生的 `clawrouter-` 密钥路由
- 基于 Cloudflare KV 的迁移与版本 1 兼容性记录
- API key/OAuth/订阅授权以及提供商健康状态
## 提供商注册表
提供商支持是数据驱动的。大多数集成只需通过创建一个文件即可完成:
```
providers/.provider.yaml
```
该文件声明了服务 ID、认证方案、必要时的 OAuth 平台映射、base URL、路由模板、适配器系列、模型/能力映射以及计费计量器。Rust 编译器将这些文件转换为供边缘运行时和管理 UI 使用的提供商快照。
内置的入门级覆盖范围:
- 模型 API:OpenAI, Anthropic, Google Gemini, Azure OpenAI, AWS Bedrock, MiniMax, Mistral, Cohere, xAI, Groq, Perplexity, DeepSeek, Together, Fireworks, Hugging Face, Replicate
- 网关 API:OpenRouter, Cloudflare AI Gateway
- 工具/API 平台:Tavily, Firecrawl(无密钥入门访问;可选配置 API key 以获取更高限额)
使用以下命令验证目录:
```
cargo run -p clawrouter -- provider compile providers/*.provider.yaml
```
在真正部署到 Cloudflare 之前,请运行:
```
pnpm cf:doctor
```
它会检查 Wrangler 身份验证、所需的 GitHub Actions 密钥名称、本地部署环境、提供商绑定覆盖率以及全员提供商的冒烟测试计划,且不会打印出密钥的值。真正的部署至少需要通过一个实时黄金提供商(golden-provider)的冒烟测试;其结果会被持久化存储在 `POLICY_KV` 中,以便状态就绪检查能够区分出已验证、失败、过期、未验证和已禁用的提供商。
浏览器控制台旨在置于 Cloudflare Access 的保护之下。使用以下命令配置该边缘网关:
```
CLOUDFLARE_ACCOUNT_ID=... \
CLOUDFLARE_API_TOKEN=... \
CLAWROUTER_ACCESS_GITHUB_ORGS=openclaw \
CLAWROUTER_ACCESS_ADMIN_EMAILS=you@example.com \
pnpm cf:access
```
然后使用打印出的 `CLAWROUTER_ACCESS_TEAM_DOMAIN` 和 `CLAWROUTER_ACCESS_AUD` 值重新部署。`/` 会重定向到受 Access 保护的 `/dashboard` 路径,`/dashboard` 会重定向到具有角色感知能力的 `/dashboard/home`,而规范的控制台视图位于 `/dashboard/*` 下,同时公开的 `/v1` 目录和代理路由保持常规状态。Access 应用还必须保护 `/v1/session*`、`/v1/playground/*`、`/v1/admin/*` 和 `/v1/oauth/callback`,以便浏览器控制台能够从已验证的 Access 会话中引导身份、授权权益、会话配额使用情况、playground 调用、管理变更(mutations)以及 OAuth 回调。如果 `/dashboard/*`、`/v1/session`、`/v1/session/usage`、`/v1/playground/*` 或 `/v1/oauth/callback` 上出现 ClawRouter 的 `access_session_required` JSON 响应体,这意味着 Access 应用尚未覆盖该控制台路径,并且 `pnpm cf:smoke` 会将其视为一次失败的部署冒烟测试。
`Deploy Cloudflare` 工作流也可以执行 Access 步骤:在添加了能够管理 Zero Trust Access 应用和策略的 `CLOUDFLARE_API_TOKEN` 后,通过设置 `provision_access=true` 来触发它。生产环境的默认设置允许配置的 GitHub 身份提供商验证通过的 `openclaw` GitHub 组织成员访问。真正的部署还需要 KV 写入权限,因为 Wrangler 在发布时会验证 Worker 的 `POLICY_KV` 绑定。请保持将 `access_domain` 设置为控制台主机名;`worker_url` 仅作为部署后的冒烟测试目标。
## Edge Proxy
该 Worker 目前暴露了以下接口:
- `GET /v1/health`
- `GET /v1/providers`
- `GET /v1/routes`
- `GET /v1/session`
- `GET /v1/entitlements`
- `GET /v1/me`
- `GET /v1/usage`
- `GET /v1/models`
- `GET /v1/catalog`
- `GET /v1/oauth/callback`
- `GET /v1/key/inspect`
- `POST /v1/chat/completions`
- `POST /v1/responses`
- `POST /v1/embeddings`
- `POST /v1/messages`
- `POST /v1/messages/count_tokens`
- `POST /v1/proxy//`
- ` /v1/native//`
- `GET /v1/admin/overview`
- `GET /v1/admin/tenants`
- `GET /v1/admin/usage`
- `GET /v1/admin/policies`
- `GET /v1/admin/credentials`
- `GET /v1/admin/connections`
- `GET /v1/admin/access-users`
- `GET /v1/admin/policy-bindings`
- `GET /v1/admin/provider-status`
- `GET /v1/admin/provider-health`
- `GET /v1/admin/upstream-grants`
- `GET /v1/admin/assignment-rules`
- `PUT /v1/admin/access-users/`
- `PUT /v1/admin/access-user-grants/`
- `PUT /v1/admin/policy-bindings`
- `PUT /v1/admin/policies/`
- `PUT /v1/admin/credentials/`
- `PUT /v1/admin/connections/`
- `PUT /v1/admin/upstream-grants///`
- `PUT /v1/admin/assignment-rules/`
- `POST /v1/admin/policies//revoke`
- `POST /v1/admin/credentials//revoke`
- `POST /v1/admin/upstream-grants////revoke`
- `POST /v1/admin/upstream-grants////refresh`
- `POST /v1/admin/upstream-grants////authorize`
- `POST /v1/admin/assignment-rules/reconcile`
在迁移期间,遗留的 `GET|PUT /v1/admin/keys...`、`POST /v1/admin/keys//revoke` 和 `GET /v1/admin/users` 将保留作为兼容性别名。新的控制平面客户端应直接使用 policies、credentials 和 tenants。遗留的撤销别名会将 `` 视为凭据 ID,并且绝不会禁用共享的策略。
兼容 OpenAI 的代理请求会根据请求体内的 `model` 字段进行路由,例如 `openai/gpt-4.1-mini`。在使用上游提供商密钥之前,Worker 会从串行化的 `ACCESS_CONTROL` Durable Object 授权机构验证已颁发的凭据及其策略。`POLICY_KV` 中的 `credentials/` 和 `policies/` 会为迁移提供种子数据,并作为兼容性副本保留:
```
{"enabled":true,"secretSha256":"","policyId":"team_docs","policyGeneration":"policy_..."}
```
```
{
"enabled": true,
"generation": "policy_...",
"providers": ["openai"],
"allProviders": false,
"tenantId": "team_docs",
"tokenRole": "service",
"monthlyBudgetMicros": 100000000
}
```
策略和凭据的版本(generation)必须匹配。强一致性的授权机构写入操作使得撤销和范围缩减能够立即生效;在迁移或轮换未完成的期间,版本不匹配的情况仍会执行失败关闭(fail closed)。规范的策略编辑会保留其版本号。遗留的密钥变更别名拒绝同时更改策略范围和密钥。
`GET /v1/catalog` 是限定于凭据范围的客户端集成契约。它仅返回允许使用的提供商和可执行的模型。每个提供商行都会报告统一的 OpenAI 兼容 `/v1` 路由是否可用、其原生代理 base URL,以及其可执行原生路由的请求/响应格式。客户端可以使用这些字段来选择真实的提供商传输方式,而无需根据提供商 ID 进行猜测。
禁用凭据可撤销单个已颁发的密钥,禁用策略可撤销绑定到该策略的所有用户和凭据,或者禁用提供商连接可在全局范围内停止该提供商。只有在 `keys/` 记录是真正的迁移前记录时,它们在迁移期间才保持可读状态。携带版本的兼容性记录将保持禁用状态,绝不会作为授权的后备方案。有关 Cloudflare 配置、部署、密钥注册和冒烟测试命令,请参阅 `docs/deploy-cloudflare.md`。
名为遗留版本的 `pnpm cf:oauth:put` 和 `pnpm cf:oauth:revoke` 助手会为 `api_key`、`oauth` 和 `subscription` 连接写入规范的版本 1 上游授权记录。它们仅通过 stdin、环境变量或文件接受访问令牌、刷新令牌以及单字段或多字段凭据,绝不接受 argv 传参。
撤销操作会在移除密钥的同时,将授权元数据保留在一个已禁用的墓碑(tombstone)中。有关完整的操作流程,请参阅 `docs/deploy-cloudflare.md`。
管理端点接受已验证的 Cloudflare Access 管理会话,或者针对 `CLAWROUTER_ADMIN_TOKEN_SHA256` 的 `Authorization: Bearer ` 验证。提供商批准的浏览器 OAuth 仅从已验证的 Access 管理会话启动,使用一次性 PKCE 状态,并存储生成的授权,而不会将提供商令牌返回给浏览器。
浏览器控制台在颁发凭据之前,会在浏览器内对生成的代理密钥进行哈希处理,独立于凭据和提供商连接管理策略,分配明确的用户/组策略绑定,显示提供商就绪状态和请求审计,并包含一个由 Cloudflare Access 提供支持的 playground,用于模型和清单代理服务路由。管理权限来自于 Access 管理员白名单,而不是可编辑的用户行,并且不隐含提供商访问权限。
通用的 REST/工具代理请求是由清单驱动的:
```
curl "$CLAWROUTER_BASE_URL/v1/proxy/tavily/search" \
-H "authorization: Bearer $CLAWROUTER_KEY" \
-H "content-type: application/json" \
--data '{"body":{"query":"openclaw"},"query":{"topic":"news"}}'
```
Worker 从编译好的提供商快照中解析 `provider` 和 `endpoint`,应用清单中的路径/查询/标头/认证映射,转发请求,并向 `USAGE_QUEUE` 发送使用事件。同一个 Worker 会将该队列消费到有界的 `USAGE_LEDGER` 报告 Durable Object 中,并重放未结算的预算更新。审计事件会保留身份、策略、凭据、提供商、路由能力、模型、时间、结果、安全可用情况下的 token 以及成本,保留期为 30 天。Prompt 和 completion 的请求体绝不会存储在使用账本中。如果访问策略启用了请求内容保留(默认启用)且凭据所有者未被豁免,LLM 请求体将被分开存储 30 天;请参阅[内容保留](docs/content-retention.md)。
`/v1/usage` 返回调用者策略的预算及使用情况摘要;`/v1/admin/usage` 返回预算行以及所有租户的使用情况摘要和最近的请求审计。
当所选模型在其提供商清单中具有版本化定价时,预算请求会在进行上游调用之前预留上限 token 成本。显式的策略 `requestCostMicros` 仍然作为固定成本覆盖项;无定价的路由仅在月度预算之外保留一_micro 的回退机制。没有版本化定价的预算调用会执行失败关闭。成功的响应会结算其实际的 token 成本,包括报告时的缓存输入。SSE 响应会进行内联计量,而不会缓冲客户端流。缺失或中断的使用情况仍按保守的预留量进行收费;非 2xx 和传输失败的情况会退款预留额度。失败的结算调用会被持久化到 `USAGE_QUEUE` 以便进行持久重试,同时预留额度仍保持计费的失败关闭状态。耗尽自动重试的消息将被移至独立的使用 DLQ,供操作员在 Cloudflare 的四天未消费 DLQ 保留期到期之前进行检查和重放。内部预留 ID 独立于调用者提供的请求 ID 生成。
Codex 和 Claude Code 集成、定价字段、预留语义以及 agent 归因标头记录在 [`docs/agent-spend-control.md`](docs/agent-spend-control.md) 中。
当清单声明的授权和剩余的运行时配置就绪时,OAuth、SigV4 和部署模板化提供商将通过同样执行策略的代理进行处理。提供商密钥可以来自有范围限制的上游授权,而不是 Worker 全局绑定。
标签:AI工具, API网关, Durable Objects, Rust/Wasm, Streamlit, 可视化界面, 大模型路由, 程序员工具, 访问控制, 通知系统