架构
下面是实际部署采用的参考架构。比组件本身更重要的,是信任边界划在哪里。
数据流
客户端(你的业务服务、内部工具)
│ 虚拟密钥 (vk-...),永远不是服务商密钥
▼
┌───────────────────────────────────────────────┐
│ 反向代理 (Caddy / nginx) │ TLS、HSTS、限流、
│ - 终结 HTTPS │ 安全响应头
└───────────────┬───────────────────────────────┘
▼
┌───────────────────────────────────────────────┐
│ 网关 (LiteLLM / one-api 等) │
│ - 认证:虚拟密钥 → 团队、配额、模型 │
│ - 路由:模型名 → 上游池 │
│ - 用量计量、请求日志(已脱敏) │
│ - 故障转移:自动重试下一个健康上游 │
└──────┬──────────────────────────┬─────────────┘
▼ ▼
┌──────────────┐ ┌──────────────┐
│ 密钥保管 │ │ SQLite/Postgres│
│ (env/文件, │ │ 用量、密钥、 │
│ 0600, 不可 │ │ 审计日志 │
│ 经 web 访问)│ └──────────────┘
└──────┬───────┘
▼ 服务商密钥 (sk-...,归你所有)
上游服务商(OpenAI、Anthropic、Google 等官方 API)
信任边界
| 边界 | 规则 |
|---|---|
| 公网 → 代理 | 对外只开放 443。管理后台绝不暴露在公网,只能通过 SSH 隧道或 VPN 访问。 |
| 代理 → 网关 | 走回环或内网。网关容器任何时候都不绑定公网端口。 |
| 网关 → 密钥库 | 服务商密钥仅网关进程用户可读(0600、非 root),不会出现在日志、报错信息或返回给客户端的任何内容里。 |
| 客户端 → 网关 | 客户端只持有带配额、可吊销的虚拟密钥。即便某个客户端被攻破,损失也只是一把虚拟密钥的额度,动不到服务商账号。 |