轮换前先盘点哪些东西?

我会先开一张表,不急着改 GitHub 后台。

字段示例为什么要写
secret 名称CLOUDFLARE_API_TOKEN后面比对 workflow
使用范围production / staging决定放 repository 还是 environment
供应商Cloudflare / Stripe / Supabase知道去哪里撤销旧密钥
权限deploy、read-only、billing判断能不能降权
owner谁能重建防止只有一个人会操作
轮换窗口2026-03-04 10:00 UTC出问题能查时间线

GitHub 官方文档支持 repository、environment 和 organization secrets。小 SaaS 团队最容易犯的错,是把生产和测试共用一个仓库级 secret。这样 staging workflow 一旦被误触发,也能拿到生产权限。

我的规则是:生产部署、支付、数据库写权限,一律放 production environment;测试环境放 staging;只读通知类 token 才考虑 repository secret。

environments 怎么拆?

先建三个 environment:previewstagingproduction

  • preview:只允许读权限,给 PR 预览用。
  • staging:允许写测试资源,禁止碰生产数据库。
  • production:加 required reviewers,至少一人批准。

GitHub environments 可以把 secrets 和部署保护规则绑在一起。这样不是每个 workflow 都能直接碰生产。独立开发者一个人做项目时,也建议保留 production environment,因为三个月后你会忘记某个 workflow 的触发条件。

如果你的部署链路依赖 Cloudflare Pages、Workers 或 R2,生产 token 只给对应资源的最小权限,不要用账号级全权限 token。轮换密钥不是形式主义,顺手降权才是收益。

轮换清单怎么执行

按这个顺序走,少出事故:

  1. 冻结部署窗口:至少 30 分钟内不要合并大 PR。
  2. 导出当前 workflow 列表:确认哪些 job 读取了目标 secret。
  3. 在供应商后台创建新密钥:权限按最小化设置。
  4. 在 GitHub environment 写入新值:不要改错环境。
  5. 跑 staging workflow:验证构建、迁移、部署、回调。
  6. 跑 production smoke workflow:只做最小验证。
  7. 撤销旧密钥:在供应商后台删除或禁用。
  8. 查 audit log:确认没有异常成员和规则变更。
  9. 记录结果:写 owner、时间、旧密钥撤销状态。

我不建议把所有供应商密钥同一天轮换。Cloudflare、Stripe、数据库、邮件、AI API 分批做,每批之间留 15-30 分钟观察窗口。一次改完看起来效率高,失败时定位很痛苦。

审计日志看什么

轮换当天至少看这几类:

信号正常情况需要追查
secret 更新只有指定 owner 操作多人重复修改同一 secret
environment 规则required reviewers 未变审批规则被临时关闭
workflow 触发轮换相关 workflow奇怪分支触发生产部署
成员权限无新增 admin临时 admin 未回收
第三方 App无新增授权未知 App 读取仓库

GitHub 的 audit log 对组织很有用,但前提是你知道自己要找什么。不要只搜「secret」,还要看 environment、repo permission、workflow dispatch、GitHub App 相关记录。

远程团队避免轮换当天掉线

轮换当天最怕的是:人在机场或酒店 Wi-Fi,GitHub、Cloudflare、Stripe 后台来回跳,2FA 又在另一台设备上。我的做法很土:提前一天确认 2FA 设备、电源、备用网络和供应商登录状态。

如果团队成员分布在不同国家,至少让执行人和审批人都能稳定打开 GitHub、Cloudflare、Stripe 后台。需要跨平台处理部署时,可以准备一条海外服务跑 GitHub Actions / Cloudflare 的稳定线路,避免轮换窗口里因为后台连接不稳而误判为权限问题。

注意,这不是让网络替代权限管理。权限、审计和最小化才是正事;稳定访问只是降低操作噪音。

回滚设计

不要把回滚写成「恢复旧 secret」。更稳的设计是两段式:

  • 新密钥上线后,旧密钥保留 30-60 分钟但不再写入 GitHub。
  • 如果生产 smoke test 失败,判断是 secret 值错误、权限不足、供应商限制,还是 workflow 读错环境。
  • 只有确认新密钥无法快速修复,才把旧密钥重新写回 environment。
  • 回滚后也要记录原因,并重新安排轮换,不要让旧密钥无限期复活。

Stripe、Cloudflare、数据库这类关键密钥,回滚窗口要短。你保留旧密钥越久,泄露面就越大。

轮换后的收尾检查

我会做五件小事:

  1. 搜 workflow 里有没有硬编码 token。
  2. 检查 PR 预览有没有拿到生产 secret。
  3. 确认旧密钥在供应商后台已经撤销。
  4. 给 secret owner 发一条完成记录。
  5. 把下一次轮换日期放进团队日历。

真正成熟的密钥管理,不是某次轮换做得多漂亮,而是下次轮换不用重新想流程。

相关阅读