服务 Webhook
服务 Webhook 是 服务端到服务端 的集成回调。
当某个证书签发流程最终状态变为 SUCCESS 时,bbserver 会向你配置的 URL 发起一次带签名的 POST 请求(JSON)。
该 Webhook 只承担“通知”的职责;你的服务如需证书内容,请用现有的导出/下载 API 根据 cert_id 获取。
触发时机
- 事件 Key:
certificate.issued - 触发条件:每次签发成功(包含续签)
- 不会在
PENDING/PROCESSING/FAILED/CANCELLED时触发。
管理 Webhook
你可以在控制台 /service-webhooks 管理,也可以通过 HTTP API 管理:
GET /apiv1/users/:user_id/service_webhooks?offset=0&limit=50GET /apiv1/users/:user_id/service_webhooks/:webhook_idPOST /apiv1/users/:user_id/service_webhooksPUT /apiv1/users/:user_id/service_webhooks/:webhook_idDELETE /apiv1/users/:user_id/service_webhooks/:webhook_id
注意:
secret在创建/更新时必填,且服务器 不会回传;请妥善保管。event_key当前主要使用certificate.issued。
Scope 过滤
每个 Webhook 都有一个 scope JSON 对象。支持的形式:
- 全部证书(默认):
{ "type": "all" }
- 单个证书:
{ "type": "cert_id", "cert_id": 123 }
- 单个域名:
{ "type": "domain", "domain": "example.com" }
如果 scope JSON 无法解析,服务器会按 {type: all} 处理(更宽松)。
请求格式
bbserver 会发送一个 POST 请求,body 为 JSON。
请求头
User-Agent: bbserver-service-webhook/1X-BB-Event: certificate.issuedX-BB-Webhook-Id: <webhook_id>X-BB-Delivery-Id: <outbox_row_id>X-BB-Cert-Id: <cert_id>X-BB-Issue-History-Id: <issue_history_id>X-BB-Timestamp: <unix_ms>X-BB-Signature: sha256=<hex>
请求体
示例:
{
"event": "certificate.issued",
"cert_id": 123,
"issue_history_id": 456,
"user_id": 789,
"ts_ms": 1700000000000,
"domain_name": "example.com"
}
说明:
domain_name可能缺失。- body 中的
ts_ms表示入队时间;签名使用的是请求头里的X-BB-Timestamp。
签名校验
校验步骤:
- 读取 原始 body 字节(必须保持原样)。
- 构造签名输入串:
<timestamp_ms>.<raw_body>
其中 <timestamp_ms> 为请求头 X-BB-Timestamp。
- 使用 webhook 的
secret作为 key,计算HMAC-SHA256。 - 将摘要转为十六进制,与
X-BB-Signature(去掉sha256=前缀)做常量时间比较。
重要:
- 不要先 parse 再 stringify;任何重排/缩进都会改变字节序列,导致验签失败。
- 建议做时间窗口校验(例如
X-BB-Timestamp与当前时间差超过 5 分钟则拒绝)。
投递语义与重试
- 任何
2xx都视为成功。 - 可重试状态码:
408、429、5xx。 - 其它状态码(例如
400/401/403)通常会被视为永久失败。 - 重试为指数退避(起步约 5 秒,逐步增加,并有上限与最大尝试次数)。
建议接收端:
- 接收成功后尽快返回
204。 - 业务处理异步化(写队列/触发任务),避免阻塞回调。
获取证书
Webhook 不会包含私钥等敏感材料。
收到 cert_id 后,请使用你现有的自动化凭证调用证书导出/下载 API 来获取最新证书内容。