密钥泄露应急响应

SKILL运维和基础设施
运维和基础设施 未标注权限 许可证不明确
安装这个技能

按时间顺序处置密钥泄露:先厘清泄露了什么、扩散到哪,在动 git 历史之前轮换 API key、令牌、密码与证书,重建把密钥固化进去的构建产物,在改写历史与冻结镜像归档之间做出决定,清扫残余副本,最后用可验证的零出现检查收尾。当用户报告 key、令牌、密码、私钥或 env 文件进了 git 或被推到远端,在前端 bundle、容器镜像、CI 日志、截图或备份里发现密钥,收到密钥扫描器或渗透测试报告,需要在暴露后轮换凭据,或纠结是否用 filter-repo 改写历史时使用。

一句话选型结论

按资料字段整理

密钥泄露应急响应是运维和基础设施类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类运维和基础设施 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_617dd917/secret-leak-incident-response-moran
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

运维和基础设施
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_617dd917仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验2026-11-06上游最后核验时间 · 数据更新 2026-11-06
正文体量25.8 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
查服务与日志

按现象定位服务状态与日志线索。

写部署与巡检脚本

把重复的部署、巡检写成脚本。

故障排查

按步骤排查网络、依赖与配置。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在运维和基础设施场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
密钥泄露应急响应当前 未标注权限 未标注 未标注 未标注 有
Azure 部署 调用外部服务 GitHub 仓库 664.2 万 Codex、Claude、Cursor 有
Azure diagnostics 问题管理 调用外部服务 GitHub 仓库 657.6 万 Codex、Claude、Cursor 有
Azure aigateway 部署 调用外部服务 GitHub 仓库 655.3 万 Codex、Claude、Cursor 有
Azure AI 搜索 调用外部服务 GitHub 仓库 651.4 万 Codex、Claude、Cursor 有
Azure Cloud migrate 部署 调用外部服务 GitHub 仓库 650.7 万 Codex、Claude、Cursor 有

SKILL.md 全文

25.8 KB
模型实际读到的说明书原文,来自技能仓库

密钥泄露应急响应

一份应对任意 git 托管软件项目中密钥泄露的运行手册:轮换凭据,隔离或清除每一份副本,并用机械化的检查证明事件已经关闭。它适用于 API key、令牌、数据库密码、私钥、服务凭据以及整份 env 文件;与语言、框架、git 托管平台无关。

命令示例假定 POSIX shell——Windows 上请从 git-bash 或 WSL 里执行;git 命令本身在各平台上行为一致。

各阶段这样排序,是为了让每一步都让下一步更安全。在单个阶段内,顺序比速度更重要;跳过前面通常会造成返工,或让真正的风险原地不动。

目录

  • 何时使用
  • 手册地图
  • 操作原则
  • 反模式与常见问题(Anti-patterns & FAQ)
  • Phase 0 —— 分诊:泄露了什么、扩散到哪
  • Phase 1 —— 先轮换,再碰历史
  • Phase 2 —— 构建期注入的密钥要重建,而不是改配置
  • Phase 3 —— git 历史:改写还是冻结(这是决策,不是条件反射)
  • Phase 4 —— 残留清扫
  • Phase 5 —— 验证关闭与事件记录
  • 错误处理约定
  • 失败模式与恢复
  • 完整走查(端到端样例)

何时使用

自动触发:用户描述与下表场景相关时直接启用,不需要点名本技能。

用户会这么说 实际场景
「完了,我把 .env 推到 GitHub 了」 密钥进 git → Phase 1 轮换、Phase 3 历史处置
「前端 bundle 里能搜到 API key」 构建期内联 → Phase 2
「CI 日志里把 token 打出来了」 日志扩散 → Phase 4 残留清扫
「要不要用 filter-repo 把历史洗掉」 历史处置决策 → Phase 3
「轮换完了,怎么证明这事过去了」 零命中验证与关闭 → Phase 5

手动调用:对话里说「用密钥泄露应急响应处理」,或直接用 @ 引用本技能(平台的完整 slug 可能带作者后缀,不必写全名)。

不适合:没有确认泄露的一般安全评审或渗透测试——先走安全评估流程,本手册按「已泄露」处置。;占位符含义与取值来源见 references/error-handling.md 第六节。

手册地图

阶段 目标 进入下一阶段的闸门
0 分诊 盘点泄露了什么、扩散到哪 每一项都已归类为「设计上公开」或「必须保密」
1 轮换 替换每一个泄露值、作废旧值 提供方明确以拒绝证明旧值已失效
2 重建 清除固化进已部署产物里的值 在构建产物里搜旧值结果为零
3 历史 决定改写还是冻结,执行,验证 选定路径已在每个 ref 与每个镜像仓库上执行
4 清扫 清除其它各处的残留副本 每处要么已清除,要么记为已接受风险
5 关闭 证明关闭并写下记录 四项零出现检查通过;记录已写

操作原则

  1. 轮换优先于清理。 轮换过的密钥在所有地方同时作废。只从历史里删掉、但仍有效的密钥,依然是一张活凭据。绝不要用一次历史改写去换掉一次轮换。
  2. 用拒绝来验证,不靠假设。「我改过了」不算关闭。旧值必须被证明已死(提供方拒绝它)、并且不存在(搜索结果为零)。
  3. 假定副本已经存在。 任何到过公开或半公开面的东西,都已被爬取、缓存、fork、截图或备份。按「至少有一样副本不在你控制之内」来规划。
  4. 边做边写下一切。 轮换日期、范围与未结项都写进事件记录。只活在某人记忆里的部分轮换,会变成下一次事件。

本手册的交付物:一份分诊后的清单、已轮换的凭据、一个历史处置决定(改写、冻结或两者并用)、一次残留清扫,以及一份关闭记录。

反模式与常见问题(Anti-patterns & FAQ)

反模式(顺序做错,等于没做)

  • 先改 git 历史,后轮换密钥:历史改写的窗口期里密钥仍然有效。正确顺序是 Phase 1 轮换 → Phase 2 重建产物 → Phase 3 再决定历史处置。
  • 只删文件、不轮换:从工作区删掉 .env、force-push 覆盖提交,都影响不到已经拿到密钥的人。删除只解决「以后不再泄露」,轮换才解决「已经泄露」。
  • 忽略构建产物与镜像层:前端 bundle 内联的 key、镜像历史层里 COPY 进去的配置,改源码不会消失——必须重建并重新打镜像(Phase 2)。
  • 忘记 CI 日志、构建缓存、截图与工单附件:这些是最常见的二次扩散途径;Phase 4 的残扫范围要覆盖 CI artifact、PR/工单附件、聊天截图与备份。
  • 没有零命中验证就宣布结束:Phase 5 的可复现检查(全仓库、全镜像、全历史)与时间戳留档,才是「关闭事件」的依据。
  • 把轮换当一次性动作:没有登记未完成轮换(Phase 1.3),几周后没人记得哪把密钥还没撤销。

常见问题(FAQ)

Q:密钥只出现在私有仓库里,还要轮换吗?
要。私有 ≠ 安全:协作者、fork、CI 缓存与备份都可能拿到过;先按「已泄露」处理,再按实际暴露面决定后续处置强度。

Q:必须改写 git 历史吗?
不必。判断标准在 Phase 3:仓库已公开或已分发时,改写历史清不干净下游副本,冻结归档 + 轮换 + 监控更划算;只有内部分发可控时才值得 git filter-repo 全量改写。

Q:轮换后旧密钥能留一段时间做灰度吗?
只在有明确兼容窗口时才允许,并且要登记到期时间与撤销动作(Phase 1.3 的未完成轮换清单);没有撤销计划的「两把都能用」就是长期风险。

Q:没有权限改 CI 流水线或仓库历史怎么办?
先把分诊结果与建议动作写进事件记录并升级给有权限的人;分诊与轮换仍要你自己做完,不要因为拿不到权限就停在原地。

Phase 0 —— 分诊:泄露了什么、扩散到哪

动手改任何东西之前,先建一份清单。对每个泄露项回答:它是什么、出现在哪、何时首次暴露、谁可能看到过。

0.1 收集泄露清单

逐个走查所有扩散面。泄露很少停留在最初被发现的地方:

  • git 历史:不只是最新一次 commit。密钥提交过一次,就存在于包含它的每一个 commit 里,也存在于每一个做过的 clone 里。commit message 也要查——密钥同样会漏进 message。
  • 前端构建产物:部署到 CDN 或托管平台的 JS bundle、静态 chunk 与 source map。
  • 容器镜像:镜像层会把构建时存在的一切固化进去,包括 build-arg 的值和被拷贝的文件。已推送的层在 registry 里持久存在,即使 tag 被覆盖也还在。
  • CI/CD 日志:构建与部署日志会回显环境变量、失败命令与堆栈。凡有仓库或 CI 访问权的人都能读日志,而且日志常常被无限期保留。
  • 聊天、工单与截图:聊天串、issue tracker 与 wiki 里粘贴的配置、调试输出与截图。
  • 备份与归档:数据库 dump、卷归档、项目目录副本、旧工作站。

0.2 对每一项归类

  • 设计上公开:本就打算随客户端代码发布的值——可公开的 key 与客户端标识符,其提供方本来就预期它们可见。暴露是正常的。轮换是可选项;应当去查提供方对这类 key 实际提供哪些限制(origin/referrer 白名单、scope、服务端滥用防护)并配上。限制能力因提供方而异——到提供方文档里确认,不要假设一定有域名白名单。
  • 必须保密:任何能换到访问权的东西——私钥、密码、提供方 API key、会话令牌、连接串。这些驱动本手册的其余部分。

拿不准时,按「必须保密」归类。多轮换一次只花几分钟;少轮换一次要付整个事件。

分诊产出:一张表,列为 条目 / 暴露在哪 / 首次暴露时间 / 归类 / 扩散面。后续每个阶段都引用这张表。

0.3 控制仍在扩散的东西

控制在被捕获之前才有用;它永远替代不了轮换。

  • 如果密钥几分钟前刚推到有访问控制的远端,删分支也许能抢在人眼之前。把这样换来的时间当额外奖励,不是修复——轮换照做。
  • 在公开远端上,假定几分钟内就被捕获。别演「删了就没事」这出戏,直接进 Phase 1。
  • 尽可能撤销分享链接,删除仍可编辑的截图与聊天消息。
  • 提供方支持的话,立刻轮换已暴露的会话令牌:它们一撤销就立即失效,常常是整个事件里最快的得分点。

Phase 1 —— 先轮换,再碰历史

在做任何关于 git 历史的决定之前先轮换。理由是:只清历史不轮换,所有现存副本——fork、clone、缓存、截图——手里仍是一张有效凭据。只轮换不清理,历史里只留下一具难看的尸体。前者让事件变得无害,后者不能。

1.1 生成并保存替换值

  • 新值必须是高熵随机:生成器产出的一长串随机 hex 或 base64,或提供方自己的重新生成按钮。绝不要旧值的变体,绝不要人类能记住的东西。
  • 新值只存进被 gitignore 的 env 文件或密钥管理服务。如果落进了文件,在它第一次 commit 之前先确认该文件已被忽略(git check-ignore <path>)。

1.2 部署、撤销、验证——按这个顺序

  1. 部署新值到每一个消费方:应用 env、CI 变量、容器 env,以及开发机配置。如果密钥是构建期注入的,先重建(Phase 2)——已部署的产物才是消费方。
  2. 在提供方撤销旧值:控制台、管理 API,或移除配置。真正杀死密钥的是提供方侧的撤销;从自己仓库里删掉并不算。
  3. 验证旧值被拒绝:用旧值真实发起一次带认证的调用,确认返回授权失败(401/403,或该提供方等价的未授权响应)。证据带时间戳留存。
  4. 验证新值可用(在生产上),免得事件演变成一次故障。

1.3 显式跟踪未完成的轮换

有些凭据没法立刻轮换:与第三方共享、嵌在已出货的客户端设备里,或归另一个团队所有。每一条都作为未结项写进事件记录,带上负责人与目标日期。「轮换了一部分」却永远不完成,是本阶段最常见的失败模式——悄悄留着的未结项比从未开始的更糟,因为所有人都以为它做完了。

1.4 按依赖顺序轮换

对一个被多个系统消费的凭据,从 Phase 0 的表里梳理出消费方,按刻意安排的顺序更新:先预发环境做彩排,再更新生产消费方,最后是开发机。这能避免经典的次生故障——撤销之后还有消费方指着旧值。

如果提供方根本不提供撤销——有些自建或遗留系统就是不能——就上临时措施,例如网关拒绝规则、IP 白名单或网络边界,并把该值记为未结项,直到能做真正的轮换。临时措施限制的是谁能用这个泄露值;只有轮换才能让它退役。

Phase 2 —— 构建期注入的密钥要重建,而不是改配置

前端框架的环境变量(NEXT_PUBLIC_、VITE_、REACT_APP_* 及同类)会在构建期以字面量字符串替换进 bundle。有三个后果常被忽略:

  • 事后改 env 文件,对已经部署的东西毫无影响。旧值会留在每一个正在被服务的 bundle 里,直到重建上线。
  • 任何打开浏览器 devtools 的人都能读到这个值。把密钥打进客户端代码,等同于公开发布。
  • 所以轮换要求:构建环境里放新值 → 重建 bundle 或镜像 → 重新部署 → 失效 CDN 缓存。跳过重建的轮换,在用户侧等于没轮换。
  • source map 也算构建产物:它们让压缩后的 bundle 重新变得可全文搜索,所以 bundle 里有的东西,已发布的 map 里也有。不要发布生产 source map;已经发出去的也要纳入产物搜索范围。
  • 重新部署后,旧 bundle 仍留在被缓存的 URL 上。失效 CDN 与代理缓存,然后确认先前部署的 bundle 不再从任何地方被服务。

验证重建:在已发布的构建产物里搜旧值;计数必须为零:

grep -rc "<old-key>" dist/ || echo "clean: 0 occurrences"
# 注意:工作区零命中 ≠ 对象库里没有——历史提交仍在 .git/objects,需另跑
#   git rev-list --all | xargs -r git grep -F "<old-key>"
# 两者都为零,才能写「零命中」结论;值含特殊字符时先转义或用 -F。

防御性做法:让机器凭据完全不进浏览器

持久的修法是架构性的:浏览器永远不该携带机器对机器的凭据。

  • 把凭据挪到反向代理或网关层:配置 proxy_set_header(nginx)或你网关的等价配置,在服务端给代理请求附上 API key。
  • 从每个前端调用点移除硬编码的 header 或默认值——这往往涉及几十个文件——然后重建前端。
  • 代理从 env 文件或密钥存储读自己的 key,绝不从前端构建里读。
  • 结果:即使整份前端 bundle 泄露也暴露不了什么,因为 bundle 里根本没有可暴露的东西。

这种模式适用于守护机器 API 的凭据。用户级认证(登录会话、按用户的令牌)是另一个问题,代理注入解决不了。

Phase 3 —— git 历史:改写还是冻结(这是决策,不是条件反射)

> 完整决策因素与两条路径(git filter-repo / 冻结镜像仓库)见 references/history-disposition.md —— 结论:历史处置是决策不是条件反射——仓库已分发时改写清不干净下游副本,冻结归档 + 轮换 + 监控更划算。

Phase 4 —— 残留清扫

轮换与历史工作清掉的是主要副本。还要清扫那些被遗忘、旧值仍存活的地方:

  • 镜像 registry:旧镜像层仍可按 digest 拉取;删除或覆盖受影响的 tag,并在 registry 支持时清除其缓存。
  • fork 与托管侧缓存:git 托管平台上的 fork、缓存的 commit 视图、归档的 PR diff。
  • CI 缓存、产物与日志:一个被打印出来的环境变量会永远活在日志里;平台允许的地方,清除日志与产物。
  • 队友的本地 clone:陈旧分支、stash 与编辑器历史;请每位协作者重新 clone 并确认。
  • 备份归档:数据库 dump、卷归档、改写前的 bundle、项目目录副本。新值验证通过后,删除含旧值的那些。
  • 部署平台的构建日志,以及任何摄入过 CI 输出的日志聚合系统。
  • 事件讨论期间产生的聊天与工单附件。
  • 公开网页存档与搜索缓存:仓库页面的快照。这些通常清不掉——记为已接受风险,靠「该值已死」兜底。

对每一处:能清就清。清不掉的地方——第三方存档、已打印的日志、别人的 fork——在事件记录里记为已接受的残留风险,并写上「该值已死」这一缓解事实。

Phase 5 —— 验证关闭与事件记录

关闭是机械的,不是叙事的。旧值必须在你能控制的四个地方达到零出现:

  1. 当前源码树 —— 递归搜索旧值 → 0
  2. 完整 git 历史 —— 跨所有 ref、内容与 commit message 做 pickaxe 搜索 → 0。具体命令:

bash git log --all -S'<old-secret>' --oneline # commits that introduced or removed the string git rev-list --all | xargs -r git grep -F '<old-secret>' # -F 按字面量匹配;值里有 $ . * 等先转义或用 -F # through xargs batches past ARG_MAX on large # repos (-r = do nothing on empty input)
3. 构建产物 —— 已发布的 bundle、镜像、source map → 0
4. 仍在你手里的备份与归档 → 0,或已删除

再加行为检查:提供方以授权失败拒绝旧值,并接受新值。

然后写事件记录,写进仓库的 ops 文档或 changelog。用下面这样的结构,让下一个读者能审计它:

# Secret leak incident — <date>
## Scope
- <credential-name>: rotated <date>, method <provider-console|admin-api|config>;
  old value verified rejected <date>; new value verified live <date>
## History disposition
- Decision: <rewrite|freeze|hybrid> — because <exposure, rotation status, collaborator count>
- Mirrors: <each affected remote and its disposition>
## Verification (all dated)
- Source tree search: 0 occurrences
- Full history search (all refs, content and messages): 0 occurrences
- Build artifacts: 0 occurrences
- Backups: purged or deleted (list each)
## Open items
- <credential>: rotation pending, owner <name>, target <date>
## Residual risks
- <location>: cannot purge because <reason>; accepted because the value is dead

用同样的字段填它——日期与范围、动作与理由、验证证据、未结项、残留风险——按你的命名习惯调整。

错误处理约定

本技能把出错分成四类,处置与重试策略不同,不要混着来:

类别 典型情况 处置 可重试
输入错误 参数缺失、路径或格式不对 直接拒绝,指出缺哪个字段 否
环境错误 权限、网络、依赖服务不可用 给检查命令,停下等修复 修复后
证据不足 日志、指标、状态缺失 先补证据,不做判断 补证据后
结论冲突 多个判据指向不同根因 列冲突点,先安全后性能 否

统一输出格式(每次给结论都按这四段写,便于他人复核):

判据:<看到的现象与具体取值>
结论:<属于哪一类 / 最可能的根因>
动作:<最小修改,或需要补的证据>
验证:<怎么确认修好了>

本技能常见错误码:

代码 现象 处置
E-ENV-01 轮换后旧 key 仍能调用 找出仍在用的副本逐个撤销(Phase 1.2)
E-ENV-02 git 历史里还能搜到 按 Phase 3 改写历史或冻结归档
E-ENV-03 镜像层里仍有密钥 重建镜像并重新推送(Phase 2)
E-ENV-04 扫描 0 命中但不敢关闭 扩范围重扫,留命令与时间戳
E-ENV-05 新凭据部署后不生效 重启或重建服务并做一次真实调用验证(Phase 1.2)

输入校验清单、重试与退出语义见 references/error-handling.md。

失败模式与恢复

失败现象 常见原因 检查方法 恢复动作 可否重试
轮换后旧 key 仍能调用 还有副本在用(缓存 / 另一环境) curl -H "Authorization: Bearer <旧值>" <api>,断言返回 401 找出仍在用的副本逐个撤销(Phase 1.2) 不重试(必须清零)
git 历史里还能搜到 只在工作区删了文件 git log -S'<前缀>' --all -p、git rev-list --all 后 grep(-S 只命中内容变更,不覆盖提交信息;提交信息要另用 git log --all --grep='<前缀>' 查) 按 Phase 3 改写历史或冻结归档 不适用
镜像层里仍有密钥 构建期 COPY 进去的 docker history --no-trunc <image> 查层内容 重建镜像并重新推送(Phase 2) 可重试(重建)
扫描 0 命中但不敢关闭 扫描范围不全 核对范围是否含 CI 产物、工单附件、备份(Phase 4) 扩范围重扫,留命令与时间戳 可重试
新凭据部署后不生效 部署未刷新 / 读的是旧环境 docker exec <c> env 看实际注入值 重启或重建服务并做一次真实调用验证(Phase 1.2) 可重试

失败时优先中止:历史改写(Phase 3)一旦开始就不可逆,动它之前必须完成轮换并冻结备份;拿不准就先冻结归档,别改写。

完整走查(端到端样例)

走查一:前端打包产物里出现密钥(构建期注入 → 必须重建)

场景:前端打包产物里出现 sk- 开头的 key,需轮换并重建(Phase 2)。

输入:用户原话「客户说在我们前端的 js 里搜到一个 sk- 开头的 key,是不是要全换掉」。

curl -s https://<site>/assets/index-*.js | grep -o 'sk-[A-Za-z0-9]\{8,\}' | head
grep -rn 'VITE_API_KEY\|sk-' --include=*.ts --include=*.tsx . | head
docker history --no-trunc <image> | grep -i build

中间输出(示例):

sk-live-4f9c…(示例)

./src/config.ts:7:  apiKey: import.meta.env.VITE_API_KEY
./.env.production:2:VITE_API_KEY=sk-live-4f9c…(示例)

<missing> 0B  RUN /bin/sh -c npm run build   # 构建期把 VITE_* 内联进产物

定位与修复:密钥走的是 VITE_ 前缀,构建期被内联进 JS,改 .env 不生效 →

  1. Phase 1:先轮换该 key(不等改代码);
  2. Phase 2:改由服务端反向代理注入,去掉 VITE_ 前缀,重建镜像;
  3. 旧镜像与旧 CDN 产物下架。

修复后复测:

$ curl -s https://<site>/assets/index-*.js | grep -c 'sk-live'
0
$ curl -s -o /dev/null -w '%{http_code}\n' -H 'Authorization: Bearer sk-live-4f9c…(示例)' https://<api>/v1/models
401

结论:验证 Phase 2「构建期注入的密钥要重建而不是改配置」,以及 Phase 5 的零命中验证。

走查二:仓库历史里仍躺着一把旧 key(改写还是冻结)

输入:用户原话「审计说我们 git 历史里还有一把旧 key,要不要用 filter-repo 洗掉」。

git log -S 'sk-live' --oneline --all
git remote -v

中间输出(示例):

a1b2c3d rotate keys
f9e8d7c initial import

origin  https://github.com/example/app.git (fetch)
origin  https://github.com/example/app.git (push)

定位:命中 2 个提交,仓库已推到公开远端——改写历史清不掉已克隆到下游的副本、fork 与镜像归档,收益低而代价高。按 Phase 3 的决策因素,这里应走「冻结归档」而不是全量改写;同时旧 key 已在 Phase 1 轮换过(否则先别碰历史)。

修复:旧仓库设为只读归档并新建干净仓库承接开发;事件记录写明「改写 / 冻结」的处置理由与时间。

复测:

git -C <new-repo> log -S 'sk-live' --oneline --all
curl -s -o /dev/null -w '%{http_code}\n' -H 'Authorization: Bearer sk-live-<旧值>' https://app.example.com/v1/models
(新仓库无输出)

401

结论:验证 Phase 3 的判据——历史处置是决策不是条件反射;先轮换,再按「仓库是否已分发」在改写与冻结之间选。

分工:走查一覆盖 Phase 2「构建期注入要重建产物」,走查二覆盖 Phase 3「历史改写还是冻结」,两者都在轮换之后、清扫之前。

附录 —— 预防模式

  • CI 里的密钥扫描(gitleaks、trufflehog,或托管平台自带的扫描),在 push 与 PR 时都跑,并为命中写明处置方式。扫描把未来的泄露从「几个月后才发现」变成「几分钟内抓住」。
  • env 文件卫生:从第一次 commit 起就把 .env 写进 .gitignore;提交一个只含占位名的 .env.example。卫生也管历史——今天引入的模式修不了旧 commit。
  • 服务端注入架构:网关通过代理 header 注入附带机器凭据;前端 bundle 里一个都没有。新的前端功能一开始就按这个形状做,不要等出事后返工。
  • 生成式、单一用途的密钥:高熵、按环境、按消费方。共享值会把轮换变成一次协调工程,而不是按一下按钮。
  • 最小权限与短生命周期:把每个凭据限定到最窄的权限集,提供方支持时优先用短生命周期或自动轮换的凭据。泄露一把只读范围的 key 和泄露一把 admin key 是完全不同的事件——范围决定你在处理哪一种。
  • 常备凭据清单:维护一张活的映射表,记录每个凭据住在哪——仓库、CI、镜像、设备、第三方。Phase 0 的清单应当变成这张常备清单,也是下一次事件之前你要演练对照的东西。

延伸阅读

references/error-handling.md · references/history-disposition.md

常见问题

5 问
答案由本站依据条目字段整理
密钥泄露应急响应怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_617dd917/secret-leak-incident-response-moran。安装方式为未标注。装完刷新技能列表或重开客户端。

密钥泄露应急响应支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

密钥泄露应急响应权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

密钥泄露应急响应收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

密钥泄露应急响应用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 2026-11-06。