API 密钥
三种凭据,三种威胁模型。
pk_ — Publishable
- 设计上就是要发到浏览器里的。作为
X-Client-ID标头随每个已签 名的 B2B 请求发送,也会内嵌在 SDK bundle 中用于客户端发起结账。 - 可以标识你的账户;但不能创建会话、读取其他商户的数据,或触发 任何破坏性操作。
- 泄露一个 publishable key 是低严重性事件。
sk_ — Secret(HMAC 签名密钥)
- 所有 B2B API 调用的 HMAC-SHA256 签名密钥 — 见 身份验证。
- 永远不会在网络上传输。传输的只是它针对每次请求派生出的签名。 所以你只需要担心存储层的泄露(环境变量、git、日志),不用担 心传输层。
- 仅限服务端。绝不应该出现在浏览器 bundle、公开仓库、截图或聊天 消息里。
- 泄露一个 secret 是高严重性事件。
whsec_ — Webhook 签名密钥
- 用于验证我们向你服务器入站投递的 webhook 签名。见 签名验证。
- 每个 webhook 端点各自独立 — 如果你注册了 3 个端点,就有 3 个不
同的
whsec_密钥。环境编码在前缀里:whsec_live_…/whsec_test_…。 - 仅限服务端。和
sk_一样,永远不会在网络上传输 — 只用于在本地 验证 HMAC。 - 轮换有 24 小时宽限窗口。 点击 Rotate 后,旧密钥会在新密钥生
效的同时继续被接受 24 小时(投递会同时携带
X-Signature和X-Signature-Prev),这样你就能在不阻塞流量的情况下重新部署验 证逻辑。 - 重新展示已有密钥功能是有的,需要重新完成 2FA 验证,并会记 录到审计日志 — 用于密钥丢失、又不能接受轮换的情况。仪表板默认 的姿态是”轮换,而不是展示”。
- webhook secret 一旦泄露,攻击者就能向你的 URL 伪造事件。严重程 度中到高,取决于你有多信任事件负载的内容。
Scope
Secret key 是带 scope 的。仪表板允许你用以下 scope 组合之一铸造 密钥:
| Scope | 可以做什么 | 用于 |
|---|---|---|
read | 列出 / 读取订单、会话、退款、余额 | 只读集成(分析、BI) |
write_order | 全部 read 权限 + 创建会话、创建订单、取消订单 | 商店后端 |
write_refund | 全部 read 权限 + 创建退款、把退款标记为已执行 | 客服工具 |
webhook_manage | 全部 read 权限 + 管理 webhook 端点 | DevOps 工具 |
默认铸造的”full access”密钥拥有全部四种 scope。按用途分别铸造密 钥仍然是好习惯 — 它能记录意图,也能让你在强制执行落地时提前做好 准备 — 但在把 scope 当作安全边界之前,请先阅读下面的提醒。
目前 scope 只是建议性的 — 网关并不会强制执行。 网关会验证密
钥的 HMAC 签名,并把你的商户身份(X-Merchant-ID /
X-Merchant-Domain)注入到下游服务,但它不会传递或检查密
钥的 scope。实际情况是,一个泄露的 sk_,不论它挂着什么
scope,都能调用你商户名下任意 /b2b/v1/* 端点 — 一个 read
密钥实际上并不会被阻止创建退款。所以收窄 scope 目前并不能
限制爆炸半径:做入侵应对规划时,请把每个 secret key 都当作
full-access 来对待,真正的防护手段是下文的快速轮换 + 吊销。按
scope 强制执行的功能已在路线图上。
轮换
- 生成新密钥。 仪表板 → Developers → API keys → + Add key。选择 scope。仪表板仅展示一次密钥 — 请立刻 保存。
- 把环境变量更新为新值,覆盖所有环境。然后部署。
- 验证流量。 仪表板会实时展示每个密钥的请求数。等旧密钥的请 求数降到零。
- 吊销旧密钥。 在同一个页面 → kebab 菜单 → Revoke。
目前没有自动重叠窗口 — 一旦你吊销某个密钥,任何用它签名的在
途请求都会收到 401。请相应地规划轮换流程:先部署新密钥,排空
旧密钥的流量,再吊销。
紧急吊销
如果密钥已经泄露(出现在 git 历史、公开的 bundle、被记录的堆栈跟 踪,或合作伙伴的渗透测试报告中)— 立刻吊销,哪怕会导致一些请求失 败。让失败明显地发生,也好过让攻击者手握一个有效凭据。
步骤:
- 仪表板 → Developers → API keys → [key] → Revoke now。 立 即生效,没有宽限期。
- 铸造一个替代密钥并部署。
- 审计近期活动 — 仪表板会展示每个密钥最近 30 天的请求记录,包括 IP 和命中的端点。
如果你怀疑泄露范围不止一个密钥,请联系 [email protected] 来:
- 获取你商户账户的完整审计日志导出
- 批量轮换 webhook secret
- 在你调查期间,可选择冻结账户
存储最佳实践
- 只用环境变量。 永远不要把 secret 提交进 git,哪怕是在写着
“REPLACE ME”的
.env.example里。 - 按环境区分密钥。 dev / staging / prod 使用不同的
sk_test_…和sk_live_…,从你的密钥管理系统中获取(AWS Secrets Manager、Vault、Doppler……)。 - 限制环境变量的访问权限。 在 Kubernetes 中以
Secret挂 载,而不是ConfigMap。在 Vercel / Netlify 中使用按环境变量的 scope,而不是项目级全局变量。 - 不要记录带 body 的请求日志。 即便是在调试时也不要 —
X-Signature里的 HMAC 签名是一次性的,但你的业务负载可能包含 PII。
目前还不支持什么
- ❌ 针对 secret key 的 IP 白名单。已在路线图上。
- ❌ OAuth 风格的按用户 scope token。 目前的密钥模型是按商户 的,不是按用户的。
- ❌ 自动密钥轮换(例如平台强制每周轮换一次)。目前是手动的。
下一步
- 身份验证 — B2B 调用的精 确签名算法。
- Webhooks → 签名验证 —
whsec_在入站事件上如何使用。