mcpField
D
deid

deid

github.com/lilmgenius安全1.4k11 次安装3 天前更新
代码仓库

关于 deid

deid 是一项技能,可根据所有者记录中的特征,在共享内容中查找并替换其数据。它通过决策文件记录更改以便重放,并报告受影响的 Git 历史,但不会改写历史。

主要功能

  1. 01根据所有者记录构建带标签的检索项
  2. 02扫描文件且不打印匹配值
  3. 03应用已记录的替换或保留决策
  4. 04更改后检查内容与测试
  5. 05报告 Git 历史中的匹配提交

适用场景

  1. 01从仓库中移除个人数据
  2. 02替换测试夹具中的客户信息
  3. 03检查共享模板是否含所有者数据
  4. 04决定如何处理含敏感信息的 Git 历史

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/lilmgenius/paperthin --skill deid

安装后在 Claude Code 中输入/deid确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
scripts/
deid.mjs
deid.test.mjs

详细介绍

在共享工件中查找某位所有者的数据,使用根据该所有者记录构建的搜索词进行匹配,将每处命中替换为其所起的作用,并报告哪些提交仍包含这些数据。

目标

共享工件(公共仓库、模板、测试夹具集或交付物)不包含任何属于某个人或某个组织的内容,同时仍能正常工作:每个泄露值都替换为其所起的作用,或替换为能运行相同代码的占位符;如果某个值已经公开,则说明理由后保留。工作树仅通过已记录的决策文件进行更改,因此重新运行时会重放相同的决策。这里绝不会重写历史记录:运行结果会列出内容或消息中包含搜索词的提交,并指出所有者需要对此做出的决定。

范围由人类指定:一个工件和一位所有者。运行过程绝不会自行选择目标,也不会扩大范围。

工作流

  1. 锁定制品和所有者。 指明文件夹或仓库,以及必须从中移出数据的那位个人或组织。如果用户没有指明所有者,就询问;如果涉及多个所有者,则每位所有者分别运行一次。
  2. 根据所有者自己的记录构建匹配项。 以只读方式查看用户指定的记录(身份和登录文件、个人资料、业务和收款设置、客户名单、账本、消息导出文件);如果用户没有指定任何记录,就向其索取,并编写一个匹配项文件:包含 { "label": "...", "value": "...", "ci": true, "regex": true } 行的 JSON 数组,其中 ci 和 regex 为可选项,每个标签都必须唯一,并且命名值的类型(client-phone、owner-name-ko),绝不能是值本身,因为标签会被打印出来。按每种书写形式拼出每个值(姓名在每种文字和顺序下的写法、带或不带分隔符且带国家代码的电话号码、大小写不同的电子邮件、带或不带前缀的 ID);较短或常见的词应使用带单词边界的正则表达式,因为脚本会拒绝少于三个字符的普通匹配项。将文件保存在制品之外,或使用已被 git 忽略的本地文件名,并且绝不打印任何值:后续每一步都通过标签引用匹配项。
  3. 列出匹配结果。 在此技能的文件夹中运行 node scripts/deid.mjs scan <root> --needles <file> [--decisions <file>] [--no-git] [--json]。在 git 工作树中,它会读取 git 未忽略的每个文件;--no-git 会读取根目录下的每个文件。它会将每个匹配结果打印为文件、行、列和标签,绝不打印值;退出代码 0 表示没有匹配,3 表示有匹配,2 表示用法错误或匹配项文件损坏。非 UTF-8 文本文件会在不报告行号的情况下列出,且绝不会被改写。
  4. 判断每个匹配结果并记录决定。 在上下文中查看匹配处,但不要回显包含该值的周围行,并判断以下三种情况之一。由所有者选择公开的值(仓库自身地址、已发布的作者署名、制品引用的公开个人资料)保留,并说明理由。出现在散文中的值替换为其所扮演的角色(操作人员、客户、公司)。代码、测试或夹具中的值替换为形状相同且仍能测试同一分支的占位符:电子邮件使用保留的示例域名,电话号码使用明显为虚构且位数相同的号码,姓名使用虚构姓名;检查所有读取该值的断言。编写决定文件,即包含 { "needle": "<label>", "replace": "..." } 或 { "needle": "<label>", "keep": "<reason>" } 行的 JSON 数组,可选包含 "paths": [globs],用于匹配仓库相对路径;第一个同时满足匹配项和路径条件的行将决定如何处理,因此应将限定范围的行放在通用规则之前。脚本会拒绝本身包含匹配项的替换内容。将此文件保存在匹配项文件旁边。
  5. 说明发现的严重程度,然后应用处理。 进行任何更改前,告知用户发现了哪些类型的数据(身份信息、联系方式、凭据、客户记录、业务数字、平台 ID)以及数量,只提供标签和计数,因为他们选择的补救方式取决于这些信息。然后运行 node scripts/deid.mjs apply <root> --needles <file> --decisions <file> [--json]。它只会改写文本发生变化的文件,重叠匹配项按最长匹配项处理,并保留没有匹配到任何决定的结果;退出代码 3 表示仍有未处理的匹配。重复步骤 4 和 5,直到带有 --decisions 的 scan 以 0 退出,然后运行制品自身的测试和检查;如果失败,应在决定文件中使用更合适的占位符处理,绝不能手动编辑。
  6. 以只读方式扫描历史记录。 在 git 仓库中运行 node scripts/deid.mjs history <root> --needles <file> [--decisions <file>] [--rev <rev>]... [--json];除非指定了 --rev,否则它会读取每个引用。它会按匹配项标签列出每个在文件补丁中添加该匹配项的提交,以及提交消息中包含该匹配项的提交,并且只显示提交 ID,不做任何更改。添加匹配项的提交就是它进入历史的位置;所有后续提交都会保留该匹配项,直到之后的提交将其移除,这就是为什么内容改写要从该提交开始。
  7. 报告结果并将历史记录交由所有者处理。 报告工作树结果(已改写的文件、保留的值及理由、尚未处理的匹配项)以及历史记录结果。对于包含匹配项的提交消息,告知用户对列出的提交运行 /re0-git。对于过去的文件内容,只说明只有所有者才能做出的决定,不要实际执行:使用内容改写工具改写所有列出的提交及其后续提交,对每个引用执行强制推送,并接受克隆、副本和托管平台可能会继续提供旧提交,直到这些提交被清除;重建仓库是另一种选择。

规则

  • 每次运行仅处理一个产物和一个所有者,两者均由人指定;运行范围绝不会扩大。
  • 针尖的值绝不会进入输出、报告、提交或产物;标签、保留理由以及拼出该值的路径也不会进入其中。针尖文件和决策文件必须放在产物之外,或使用会被 gitignore 忽略的本地名称;脚本绝不会将它们作为目录树的一部分来读取。
  • 只读取所有者的记录,不写入。
  • 工作树只能通过 apply 和决策文件来更改;手动编辑的内容必须写回决策文件,以便下一次运行重放。
  • 替换内容绝不借用其他真实个人或公司的数据;只能使用表示角色的名词,或一眼就能看出是合成内容的值。
  • 保留项必须附带理由。“已经公开”是指所有者选择将其公开,而不是仅仅可以找到。
  • 只读取历史记录。重写过去的内容、强制推送以及请求托管平台清除内容,均由所有者决定,并在报告中说明,但绝不执行;提交消息通过 /re0-git 交给人,由其重写消息并保持内容原样。
  • 非 UTF-8 文本文件会报告给人工处理,绝不重写。
  • 如果一轮检查未发现针尖,则不做任何更改,并明确说明。

验证

完成前,请确认:

  1. 使用决策文件运行 scan,在工作树上以 0 状态码退出;并且在执行 apply 后,产物自身的测试和检查均通过。
  2. 任何针尖值都没有出现在本轮运行打印的内容、写入产物的内容或报告中。
  3. 决策文件中的每个保留项都说明了理由。
  4. 报告历史检查结果,并说明两个交接事项:将消息交给 /re0-git 处理;所有者决定是否重写内容,但不执行任何操作。
  5. 如果脚本有更改,其测试必须通过指向该 skill 文件夹的联接或符号链接调用 CLI,并且测试通过。

评论

支持 Markdown