凭据与密钥
Webhook URL、Bot Token、App Secret、SendKey、PushKey 和用户 Key 都属于凭据。它们只能进入服务器端密钥管理、受保护的 CI Secret 或本地未提交环境变量,不能进入浏览器代码、截图、日志、Issue 或示例文档。
| 类型 | 常见示例 | 风险与生命周期 |
|---|---|---|
| 长期静态密钥 | App Secret、Signing Secret | 可换取其他令牌或伪造签名,必须限制读取主体并定期轮换 |
| 完整 Webhook URL | 群机器人、Workflow URL | URL 本身通常即可发送,日志和监控系统也不能记录完整值 |
| 短期访问令牌 | access token、tenant token | 按返回有效期缓存,按应用和租户隔离,不能永久保存 |
| 接收目标标识 | chat_id、open_id、userid | 通常不是密钥,但可能属于个人信息或暴露组织结构 |
| 用户授权令牌 | OAuth user token | 代表具体用户权限,需要加密保存、撤销和最小 Scope |
- 生产环境优先使用云密钥管理、Secret Manager 或受控部署平台变量。
- CI 只向需要的 Job 和环境注入,Fork PR 不应取得生产 Secret。
- 容器通过运行时环境或挂载 Secret 获取凭据,不写入镜像层。
- 本地使用未提交的
.env或密码管理器,并提供只含变量名的.env.example。 - 应用启动时检查必需变量是否存在,但错误信息只显示变量名,不显示值。
不要把 Token 当普通配置通过前端接口下发。即使页面只有管理员可见,浏览器网络面板、缓存、错误采集和扩展程序仍可能暴露它。
为每个环境和用途创建独立应用或凭据,避免测试、预发布和生产共用。应用可见范围从单个测试用户或测试群开始,确认后再扩大。OAuth 只申请实际调用需要的 Scope;IP 白名单和签名是额外保护,不能替代密钥保存。
凭据清单至少记录:平台、应用或机器人、环境、用途、负责人、创建日期、权限范围、保存位置、最后轮换日期和撤销入口。清单只记录引用和元数据,不记录凭据值。
短期令牌缓存
Section titled “短期令牌缓存”按平台返回的 expires_in 缓存,并在到期前预留刷新余量。缓存键必须包含平台、租户和应用标识,避免多个应用相互覆盖。并发刷新使用单飞或锁,防止大量请求同时换取 Token。
只有平台明确返回“令牌失效”时才刷新并重试一次。权限不足、目标无效和参数错误不能通过反复刷新解决。
- 确认凭据的所有调用方、环境和负责人。
- 平台支持双密钥时先创建新凭据,让调用方同时接受新旧版本。
- 切换发送端并执行最小消息验证。
- 观察业务码、失败率和目标端到达情况。
- 撤销旧凭据,确认旧值调用失败。
- 更新清单中的版本与轮换时间,不把值写入变更记录。
只支持单个 Webhook 或 Secret 时,先准备回滚方式和短暂维护窗口。删除旧机器人前确认新机器人已加入正确目标群。
- 立即撤销、重置或删除对应凭据;不要先花时间确认是否已被利用。
- 暂停相关自动重试,防止旧凭据持续出现在日志和错误系统。
- 检查仓库历史、构建产物、CI 日志、APM、工单、聊天和截图的暴露范围。
- 查看平台审计日志、异常发送和权限变更,记录事件时间线。
- 创建权限更小的新凭据,完成验证后恢复服务。
- 从 Git 历史删除敏感值不能代替平台侧撤销;两项都需要执行。
日志可记录平台、应用别名、目标类型、请求 ID、业务码、耗时和凭据版本。Token 最多保留不可逆哈希用于关联,不能记录头尾明文。异常对象和 HTTP 客户端调试日志也要检查,因为它们可能自动包含请求 URL、Header 或 Body。