API 密钥
API 密钥是网关的唯一身份凭证。一份密钥代表”某个成员在某个组织下”的请求来源——所有计费、配额、用量统计都按密钥粒度记账。
密钥格式
owo-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
└─┘ └─────────────────── 43 字符 base64url ──────────────────┘
│
└─ 平台前缀,固定 owo-- 总长度 47 字符
- 前缀
owo-用于在日志 / 错误信息里快速识别本平台密钥 - 后 43 字符是 base64url 编码的随机密文
创建后只完整展示一次。控制台之后只能显示脱敏形式
owo-xxxx****xxxx,方便核对但无法导出。请第一时间存进密码管理器或服务器密文 (Secret) 系统。
鉴权方式
网关同时接受两种 HTTP header,互为别名:
Authorization: Bearer owo-xxxxxxxxx...x-api-key: owo-xxxxxxxxx...- OpenAI 协议族(
/v1/chat/completions、/v1/responses、/v1/embeddings、/v1/images/generations)习惯用Authorization: Bearer ... - Anthropic 协议族(
/v1/messages)习惯用x-api-key: ...
两者效果完全一致,可以按 SDK 默认行为来选。
字段一览
| 字段 | 是否必填 | 说明 |
|---|---|---|
name | 必填 | 在组织内唯一;用来辨识用途,例如 cursor-personal、backend-prod |
tag | 可选 | 成本中心 / 项目标签;会被反规范化进每条 usage 记录,便于对账 |
expiresAt | 可选 | ISO 时间戳;过期后自动停用 |
rateLimitRpm | 可选 | 每分钟最大请求数;空值表示不限 |
rateLimitTpm | 可选 | 每分钟最大 token 数;空值表示不限 |
modelScope | 可选 | 模型白名单数组;空值表示放行所有可用模型 |
isActive | 系统字段 | 软删除标志;停用后立即对网关生效 |
想给 Cursor、Claude Code、生产后端各开一个 Key? 推荐做法。每个 Key 单独命名 + 单独 scope,可以在用量页面按 Key 维度看到分布,出问题时也能精确撤销。
生命周期
创建 (create)
│
▼
活跃 (active) ──┬── 轮换 (rotate) ── 同名重发;旧密钥立即失效
│
├── 限速 / scope 调整 ── 立即生效(缓存 5 秒内传播)
│
└── 停用 (revoke) ── 软删除;可被审计但无法恢复创建
控制台 API 密钥 → 创建密钥,或调用 POST /api/org/keys。返回体里的 key 字段是完整密文,仅此一次出现。
轮换
控制台 密钥列表 → ⋯ → 轮换密钥。轮换会:
- 立即停用旧密钥(网关下一次校验即拒)
- 用相同的
name、tag、expiresAt、scope、限速重发一把新密钥 - 返回新密文,仍然只展示一次
用法:怀疑泄露、定期轮换、人员离职时使用。
停用
控制台 密钥列表 → ⋯ → 停用。停用后:
- 网关立即拒绝该密钥的所有请求(
401) - 历史用量、审计日志保留,便于事后追溯
- 无法”再次启用”——确实需要的话请重新创建一把
批量撤销(管理员)
组织 admin / owner 在 团队管理 → 成员详情 可以一键撤销某成员名下全部密钥,用于离职或安全事件应急。详见 团队管理。
限速 (Rate limit)
网关在密钥粒度做两个维度限速:
| 维度 | 含义 | 触发后 |
|---|---|---|
rateLimitRpm | 每分钟最大请求数 (Requests Per Minute) | 返回 429 rate_limit_exceeded |
rateLimitTpm | 每分钟最大 token 数 (Tokens Per Minute) | 返回 429 rate_limit_exceeded |
限速窗口是滑动 60 秒。当响应被截断或返回 429,请按 错误码与重试 里的指数退避策略处理。
模型 Scope
modelScope 是一个字符串数组,列出该密钥允许调用的模型 ID。空值(默认)= 放行所有当前可用模型。
{
"modelScope": ["gpt-5.5", "claude-sonnet-4-6"]
}被 scope 拒绝的请求会返回 403 forbidden,错误信息里指出拒绝模型名,方便上层兜底切换。
典型用法:给生产环境密钥锁定到稳定型号,给试验性密钥放开全部新模型,避免”测试时用了贵模型一不小心烧掉预算”。
过期时间
expiresAt 是可选字段。设置后:
- 到期前正常使用
- 到期瞬间网关开始拒绝(
401 unauthorized+key_expired子码) - 控制台会在到期前 7 天发送邮件提醒(如果开启了告警)
适合临时密钥——例如给外部承包商一把 30 天有效的密钥,到期自动失效,无需手动跟踪。
最佳实践
✅ 推荐
- 一项目一密钥。粒度越细,撤销和审计越精准。
- 生产密钥 设置
modelScope锁定型号 + RPM/TPM 限速。 - CI / 临时调试 用带
expiresAt的短期密钥。 - 存到密文系统(Vault、AWS Secrets Manager、
.env+ 加密备份)。
❌ 避免
- 不要把密钥提交到 Git——即使是私有仓库,密钥可能因 CI 日志、Issue 截图泄露。
- 不要在前端代码(浏览器、APP)里直接使用密钥。任何
owo-...出现在客户端流量里都视为泄露——请在你的服务端代理一层。 - 不要长期共用同一把”团队总钥匙”。每个成员各开自己的密钥,离职时只撤销 ta 名下的;用一把共享 Key 等于一旦泄露就要全员轮换。
常见问题
Q: 密钥被泄露了怎么办? A: 立刻 停用(不要等”轮换”)。然后排查 usage 记录里是否有非自己 IP 的调用、是否产生了非预期的扣费——必要时联系工单申请扣款回滚。
Q: 为什么我创建密钥时已经保存了,但还是看不到完整 Key? A: 出于安全考虑,刷新或离开页面后明文密钥就无法再调出。请重新创建一把,并这次立刻保存。
Q: 密钥能跨组织复用吗? A: 不能。密钥归属到「成员 + 组织」二元组,切换组织等于切换扣费来源,必须用对应组织的密钥。
Q: 密钥前缀为什么是 owo-?
A: 历史前缀,会一直保留。在日志和错误信息里方便一眼识别”这是 ttttt.ai 平台的密钥”。