机器人凭证与 Webhook
每个机器人都有独立凭证,与合作伙伴组织的 API 密钥分开。
推荐的安全模型
| 凭证 | 用途 | 存储方式 |
|---|---|---|
合作伙伴 API 密钥(sk_…) | 管理所有机器人、轮换密钥和发送中心消息 | 静态数据采用哈希存储 |
机器人令牌(bot_….…) | 机器人范围的 API 调用(入站 Webhook 和未来的机器人 API) | 静态数据采用哈希存储;仅显示一次 |
Webhook 密钥(whsec_…) | 使用 HMAC 对 Webhook 正文签名 / 验证 | 因签名需要而存储;应像密码一样保护 |
| Webhook URL | 接收 MorisBox 事件的合作伙伴 HTTPS 端点 | 明文 URL |
为什么不使用 OAuth client_id 和 client_secret?
OAuth 客户端凭证更适合由用户委托的访问。机器人属于机器到机器通信:一个高熵机器人令牌,加上 Webhook 的 HMAC 签名,对于此用例更简单、更稳健。
最佳实践
- Webhook 仅使用 HTTPS(开发环境允许 localhost)
- 每个出站事件都使用 HMAC-SHA256 正文签名
- 可选的机器人级 IP 允许列表
- 无需重新创建机器人即可轮换令牌 / 密钥
- 切勿记录完整令牌
创建机器人(密钥仅返回一次)
POST /api/v1/bots
{
"code": "portail",
"name": "SEED Portail",
"runtime_mode": "local",
"webhook_url": "https://partner.example/hooks/morisbox/portail"
}
201 响应
{
"bot": {
"code": "portail",
"credentials": {
"token_prefix": "bot_a1b2c3",
"token_configured": true,
"webhook_url": "https://partner.example/hooks/morisbox/portail",
"webhook_secret_prefix": "whsec_ab12",
"inbound_webhook_path": "/api/v1/bots/portail/webhook"
}
},
"bot_token": "bot_a1b2c3d4e5f6.xxxxxxxx",
"webhook_secret": "whsec_xxxxxxxx",
"warning": "Store bot_token and webhook_secret now…"
}
请将
bot_token和webhook_secret存储在密钥管理系统中。之后无法再次获取,只能通过轮换重新生成。
管理凭证
| 方法 | 路径 | 身份验证 | 说明 |
|---|---|---|---|
| GET | /bots/{code}/credentials | 合作伙伴密钥或机器人令牌 | 仅显示前缀 |
| POST | /bots/{code}/token/rotate | 合作伙伴密钥 | 新 bot_token(仅一次) |
| PUT | /bots/{code}/webhook | 合作伙伴密钥 | 设置 webhook_url,可选 rotate_secret |
| POST | /bots/{code}/webhook/secret/rotate | 合作伙伴密钥 | 新 Webhook 密钥 |
| POST | /bots/{code}/webhook/test | 合作伙伴密钥 | 发送已签名的测试事件 |
| PATCH | /bots/{code} | 合作伙伴密钥 | 更新名称、渠道、allowed_ips 等 |
配置 Webhook
PUT /api/v1/bots/portail/webhook
Authorization: Bearer sk_…
{
"webhook_url": "https://partner.example/hooks/morisbox/portail",
"rotate_secret": true,
"allowed_ips": "203.0.113.10"
}
出站 Webhook(MorisBox → 您)
当 MorisBox 向您的 webhook_url 发送 POST 请求时:
POST https://partner.example/hooks/morisbox/portail
Content-Type: application/json
X-Seed360-Event: bot.webhook.test
X-Seed360-Bot: portail
X-Seed360-Signature: sha256=<hex>
X-Seed360-Bot-Secret: <webhook_secret>
正文
{
"event": "bot.webhook.test",
"bot": {
"ref": "…",
"code": "portail",
"partner_code": "seed"
},
"payload": {}
}
验证签名(Python)
import hmac, hashlib
def verify(raw_body: bytes, header_sig: str, secret: str) -> bool:
sig = header_sig.removeprefix("sha256=")
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig)
应优先验证 HMAC,不要只依赖密钥请求头。
入站 Webhook(您 → MorisBox)
POST /api/v1/bots/{code}/webhook
使用以下任一种方式进行身份验证:
Authorization: Bearer <bot_token>X-Seed360-Bot-Secret: <webhook_secret>X-Seed360-Signature: sha256=<hmac of body with webhook_secret>
{
"event": "custom.event",
"data": { "ok": true }
}
使用机器人令牌
GET /api/v1/bots/portail
Authorization: Bearer bot_a1b2c3d4e5f6.xxxx
机器人令牌的权限范围仅限该机器人。合作伙伴 API 密钥管理整个组织。
运维清单
- 创建机器人 → 存储
bot_token和webhook_secret - 部署 HTTPS 接收器 →
PUT …/webhook - 运行
POST …/webhook/test,直到返回ok: true - 泄露后通过
token/rotate/webhook/secret/rotate轮换