密钥卫生与历史重写
Secrets hygiene & history rewriting
Find leaked secrets, rotate them in test systems and purge them from git history safely.
20 条本项目编写的提案 · 分类 v1.1 · 新增基准运行 0 次。下方验证方式与部分得分规则是设计,不是执行结果。
- 典型应用
- git · git-filter-repo · gitleaks
- 小类 GUI 需求标签
CL· CLI 足够
任务提案 · 20
展开查看完整原文与建议检查方式;两种界面均保留提案英文原文。
R03.05.01.06-T01 Triage a gitleaks scan and allowlist false positives
原始指令
Run gitleaks over the full history of ~/repos/webshop. Of the findings, 3 are known test fixtures listed in docs/fixtures.md. Add a .gitleaks.toml that extends the default config and allowlists exactly those 3 (by path + regex, not by disabling rules), and write the remaining true findings to ~/out/true_leaks.json (commit, file, rule).
- 平台
lin· Linuxmac· macOS- 应用
- gitleaks · git
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP12· 答案 / 决策- 条件
- 未声明
- 提案难度
- 2 / 5
建议验证方式
Grader runs gitleaks with the agent's config: exactly the 5 seeded true leaks remain; config keeps [extend] useDefault and no rule is disabled; true_leaks.json equals the gold set by (commit, file, RuleID).
建议部分得分
40% allowlist removes exactly the 3 fixtures; 20% no rules disabled; 40% true findings listed correctly
R03.05.01.06-T02 Purge an env file from all history and force-push
原始指令
config/prod.env with live-looking credentials was committed 40 commits ago in ~/repos/api and later deleted. Remove it from every commit on all branches and tags with git-filter-repo, keep everything else byte-identical, and force-push all refs to the test remote 'origin' (Gitea sandbox).
- 平台
lin· Linuxmac· macOS- 应用
- git · git-filter-repo
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
risk· 高风险 / 不可逆- 提案难度
- 3 / 5
建议验证方式
Fresh mirror clone of origin: no blob with the env file's content hashes in any object (git cat-file --batch-all-objects); same branch and tag names; commit count per branch equals original minus commits that only touched that file; every other path's tree content identical per commit.
建议部分得分
45% file absent from all reachable history; 30% other content and refs preserved; 25% remote updated
R03.05.01.06-T03 Redact leaked AWS keys in place across history
原始指令
Two AWS access-key/secret pairs (test values) appear in several source files across history of ~/repos/infra. Replace each occurrence with the literal ***REMOVED*** using git-filter-repo --replace-text, without removing files, and push to the sandbox remote.
- 平台
lin· Linuxmac· macOS- 应用
- git · git-filter-repo
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
risk· 高风险 / 不可逆- 提案难度
- 3 / 5
建议验证方式
Mirror clone: grep over all blobs finds 0 occurrences of the 4 secret strings and N occurrences of ***REMOVED*** equal to original occurrence count; all files still exist at the same paths in every commit; gitleaks over history reports 0 AWS findings.
建议部分得分
50% secrets gone everywhere; 30% replacement count exact and files intact; 20% remote updated
R03.05.01.06-T04 Rotate a leaked Postgres password across Vault and Kubernetes
原始指令
The password of DB role 'orders_app' leaked. In the sandbox: set a new random 32-char password on the Postgres role, update Vault KV secret/orders/db (new version, keep history), update Kubernetes secret orders-db in namespace shop on the kind cluster, and roll the orders deployment so pods use it.
- 平台
lin· Linux- 应用
- psql · vault · kubectl
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP08· 应用 / 系统状态- 条件
risk· 高风险 / 不可逆multiapp· 多应用- 提案难度
- 4 / 5
建议验证方式
Old password fails to authenticate; Vault KV metadata current_version incremented and data equals the working password; k8s secret matches; orders pods restarted after the secret change and /healthz returns 200; password length 32 and not present in shell history files.
建议部分得分
30% DB password rotated; 25% Vault updated with history; 25% k8s secret and rollout; 20% service healthy and no secret in history files
R03.05.01.06-T05 Remove a secret baked into Docker image layers
原始指令
registry.test/shop/api:1.4 contains an .npmrc with an auth token in an intermediate layer (deleted in a later layer). Rebuild the image with a fixed Dockerfile using a BuildKit secret mount, tag it 1.4.1, push to the local registry, and write the leaked layer digest to ~/out/layer.txt.
- 平台
lin· Linux- 应用
- docker · dive · skopeo
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
- 未声明
- 提案难度
- 4 / 5
建议验证方式
layer.txt equals the digest of the layer containing the token; 1.4.1 manifest layers contain no .npmrc and no token string (grader extracts every layer); Dockerfile uses RUN --mount=type=secret; container passes the app smoke test.
建议部分得分
25% leaked layer identified; 45% new image free of token in all layers; 30% secret mount used and app works
R03.05.01.06-T06 Block new secrets with pre-commit and CI
原始指令
In ~/repos/webshop add a pre-commit config running gitleaks (protect --staged) and a GitLab CI job 'secrets-scan' that runs gitleaks on the MR diff and fails on findings. Prove both: a test commit with a fake Stripe test key must be blocked locally, and a pushed branch with one must fail the CI job.
- 平台
lin· Linuxmac· macOS- 应用
- pre-commit · gitleaks · GitLab CI
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
- 未声明
- 提案难度
- 3 / 5
建议验证方式
Grader installs hooks in a fresh clone and attempts a commit with a seeded key: rejected; clean commit accepted; CI job on a grader-pushed leaking branch fails, on a clean branch passes; .pre-commit-config.yaml pins a gitleaks rev.
建议部分得分
40% pre-commit blocks and allows correctly; 40% CI job fails and passes correctly; 20% pinned versions
R03.05.01.06-T07 Purge a secret from a submodule's history and update the superproject
原始指令
Superproject ~/repos/platform pins submodule libs/billing-sdk, whose history contains keys/stripe_test.pem. Purge that file from the submodule's history and push it to its sandbox remote, then update the superproject tips of main, release/1.x and release/2.x so each points at the rewritten equivalent of its pinned submodule commit, and push.
- 平台
lin· Linuxmac· macOS- 应用
- git · git-filter-repo
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
risk· 高风险 / 不可逆- 提案难度
- 5 / 5
建议验证方式
Submodule remote has no blob of the .pem; for main and release/1.x, release/2.x tips, the gitlink equals the rewritten commit mapped from the original via filter-repo's commit-map; `git submodule update --init` succeeds on each; superproject other content unchanged.
建议部分得分
40% submodule history purged and pushed; 45% three superproject tips repointed via commit-map; 15% clean checkout works
R03.05.01.06-T08 Purge a blob from a GitLab-hosted repo including MR refs
原始指令
A test API key was committed to platform/api on gitlab.test and is still reachable via merge-request refs. Rewrite history locally with git-filter-repo, push, then use GitLab's Repository cleanup (upload commit-map) and 'Remove blobs' settings to drop the old objects and refs/merge-requests copies; confirm the blob is gone server-side.
- 平台
web· 任意系统(网页)lin· Linux- 应用
- git-filter-repo · GitLab
- 交互表面
term· 终端brow· 浏览器- GUI 需求 · 任务设定
HY· 混合- GUI 需求 · 普通权限
HY· 混合- 交互原语
code· 代码与命令click· 指向与点击- 工作产物
WP06· 代码 / 工程- 条件
risk· 高风险 / 不可逆multiapp· 多应用- 提案难度
- 5 / 5
建议验证方式
Server-side (grader rails runner): repository has no object with the blob id; refs/merge-requests/*/head no longer reference old commits; GitLab housekeeping ran (prune) after the cleanup upload. Fresh clone + MR refs fetch contains no secret string.
建议部分得分
30% local rewrite pushed; 35% repository cleanup with commit-map; 35% blob unreachable server-side
R03.05.01.06-T09 Strip notebook outputs carrying tokens from history
原始指令
Jupyter notebooks under analysis/ in ~/repos/research saved cell outputs that print a Hugging Face test token. Rewrite history so every committed .ipynb has outputs and execution counts stripped (code cells unchanged), and add nbstripout as a git filter for future commits.
- 平台
lin· Linuxmac· macOS- 应用
- git-filter-repo · nbstripout · git
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
- 未声明
- 提案难度
- 4 / 5
建议验证方式
For every commit, every .ipynb parses as JSON with empty outputs and null execution_count, and code cell sources equal the original; token string absent from all blobs; .gitattributes + .git/config filter for nbstripout present and a test commit gets stripped.
建议部分得分
45% outputs stripped in all history; 25% sources unchanged; 30% future-commit filter works
R03.05.01.06-T10 Rewrite author emails that leak personal addresses
原始指令
Commits in ~/repos/site were authored with personal emails. Using a mailmap with git-filter-repo, rewrite the 3 personal addresses in fixtures/emails.csv to the given noreply addresses (author and committer), leave other identities unchanged, and add a .mailmap for future logs.
- 平台
lin· Linuxmac· macOSwin· Windows- 应用
- git · git-filter-repo
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
- 未声明
- 提案难度
- 2 / 5
建议验证方式
git log --format='%ae %ce' over all refs contains none of the 3 personal emails; mapped counts equal original counts; other identities and commit messages unchanged; trees identical to original per commit.
建议部分得分
60% emails rewritten everywhere; 25% others untouched; 15% .mailmap added
R03.05.01.06-T11 Leak timeline report for an incident ticket
原始指令
For the incident ticket, produce ~/out/leak_timeline.csv for ~/repos/mobile listing each secret introduction: commit SHA, author date (ISO UTC), author email, file, gitleaks RuleID, and whether the secret is still present at HEAD of main. Sort by date.
- 平台
lin· Linuxmac· macOS- 应用
- gitleaks · git
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP02· 记录 / 表格- 条件
- 未声明
- 提案难度
- 2 / 5
建议验证方式
Grader gold: 8 introductions (one secret moved between files counts once per introduction commit); CSV compared row by row; still_present boolean checked against HEAD.
建议部分得分
50% introduction set correct; 30% metadata columns exact; 20% still-present flags
R03.05.01.06-T12 Rotate a leaked Gitea token used by CI
原始指令
The token 'ci-deploy' of bot user 'deployer' on git.test leaked. Revoke it, create a new token with only write:repository scope, update the Gitea Actions secret DEPLOY_TOKEN in org 'apps', and re-run the last failed 'deploy' workflow to prove it works.
- 平台
web· 任意系统(网页)lin· Linux- 应用
- Gitea · Gitea Actions
- 交互表面
brow· 浏览器term· 终端- GUI 需求 · 任务设定
HY· 混合- GUI 需求 · 普通权限
AP· API 足够- 交互原语
click· 指向与点击code· 代码与命令- 工作产物
WP08· 应用 / 系统状态- 条件
risk· 高风险 / 不可逆- 提案难度
- 3 / 5
建议验证方式
Old token returns 401; deployer has one new token with scopes exactly write:repository; org secret updated (grader decrypts via admin); workflow re-run succeeds and its log shows authentication with the new token's id.
建议部分得分
30% old token revoked; 25% new token scoped correctly; 20% secret updated; 25% workflow passes
R03.05.01.06-T13 Remove secret remnants from reflog, stash and dangling objects
原始指令
In ~/repos/tools a secret was committed, amended away, and also stashed. HEAD is clean, but the local repo still holds it. Make the local repository free of the secret in every form (reflog, stash, dangling and packed objects) without losing the 4 other stashes or any branch.
- 平台
lin· Linuxmac· macOS- 应用
- git
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
- 未声明
- 提案难度
- 3 / 5
建议验证方式
git cat-file --batch-all-objects --batch | grep secret -> nothing; git fsck --unreachable shows no objects containing it; stash list has the 4 other stashes with identical content; all branch tips unchanged.
建议部分得分
50% secret unreachable in any object; 30% other stashes preserved; 20% branches unchanged
R03.05.01.06-T14 Leaked SSH deploy key: purge, revoke and redeploy
原始指令
deploy/id_ed25519 was committed to ~/repos/ops. Purge it from history and push; remove its public key from authorized_keys on hosts web1, web2, web3 (test containers); generate a new ed25519 key, install it on all three, and store the private key at ~/.ssh/deploy_2026 (mode 600).
- 平台
lin· Linux- 应用
- git-filter-repo · ssh · ssh-keygen
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP08· 应用 / 系统状态- 条件
risk· 高风险 / 不可逆- 提案难度
- 4 / 5
建议验证方式
Remote mirror has no blob of the old key; old key cannot log in to any host; new key logs in to all three; authorized_keys on each host otherwise unchanged; new key file mode 600 and not committed anywhere.
建议部分得分
30% history purged; 30% old key revoked on all hosts; 30% new key works everywhere; 10% file permissions
R03.05.01.06-T15 Classify findings as verified or unverified with trufflehog
原始指令
Run trufflehog against ~/repos/payments with verification pointed at the local mock endpoints (fixtures/endpoints.env redirects detectors to mock.test). Write ~/out/verified.json listing only secrets the mocks confirm as live (detector, file, commit) and ~/out/unverified_count.txt.
- 平台
lin· Linux- 应用
- trufflehog · git
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP12· 答案 / 决策- 条件
- 未声明
- 提案难度
- 3 / 5
建议验证方式
Mocks accept 3 of 9 seeded credentials; verified.json equals those 3 by (detector, file, commit); unverified_count equals 6; grader's mock logs show the agent's verification requests went only to mock.test.
建议部分得分
60% verified set exact; 20% unverified count; 20% no external verification calls
R03.05.01.06-T16 Rebase in-flight branches onto rewritten history
原始指令
origin/main of ~/repos/app was already rewritten with filter-repo to remove secrets (commit-map in fixtures/commit-map). Two local feature branches, feat/cart and feat/search, are still based on the old history. Move them onto the new history so their own commits are preserved and the removed file is not reintroduced, and push them.
- 平台
lin· Linuxmac· macOS- 应用
- git
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
risk· 高风险 / 不可逆- 提案难度
- 5 / 5
建议验证方式
Each pushed branch: merge-base with new main equals the commit-map image of its old base; patch-ids of its own commits equal the originals (5 and 3 commits); the purged file and secret string absent from all reachable objects of both branches.
建议部分得分
40% both branches rebased onto mapped bases; 30% own commits preserved by patch-id; 30% secret not reintroduced
R03.05.01.06-T17 Encrypt remaining config with sops and age
原始指令
After the purge, ~/repos/api still needs config/prod.yaml in the repo. Encrypt it with sops using the age recipient in fixtures/age.pub (only values under 'secrets:' encrypted), add a .sops.yaml creation rule for config/*.yaml, commit the encrypted file and ensure the plaintext is git-ignored.
- 平台
lin· Linuxmac· macOS- 应用
- sops · age · git
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
- 未声明
- 提案难度
- 3 / 5
建议验证方式
Committed config/prod.yaml has sops metadata with that age recipient and encrypted_regex limiting to secrets; grader decrypts with the private key to the original; non-secret keys readable in plaintext; no plaintext version in any commit; .gitignore covers the plaintext path.
建议部分得分
40% decrypts to original with right recipient; 25% only secrets encrypted; 20% creation rule; 15% plaintext never committed
R03.05.01.06-T18 Rotate a payment-provider test key and update a GitHub secret
原始指令
A Stripe-style test API key for the mock payment provider at pay.test leaked in a PR comment. Use the provider's sandbox API to roll the key (old key expires immediately), update the GitHub Actions secret PAY_KEY in sandbox repo acme-sbx/checkout with gh, and delete the PR comment.
- 平台
lin· Linuxweb· 任意系统(网页)- 应用
- curl · gh · GitHub
- 交互表面
term· 终端api· API / SDK- GUI 需求 · 任务设定
AP· API 足够- GUI 需求 · 普通权限
AP· API 足够- 交互原语
code· 代码与命令- 工作产物
WP08· 应用 / 系统状态- 条件
risk· 高风险 / 不可逆- 提案难度
- 3 / 5
建议验证方式
Mock provider: old key returns 401, exactly one active key; repo secret PAY_KEY updated_at after rotation and grader workflow using it gets 200 from pay.test; PR comment deleted (API 404).
建议部分得分
40% key rolled; 35% secret updated and working; 25% comment removed
R03.05.01.06-T19 Helm values leak: purge, rotate and move to sealed-secrets
原始指令
charts/shop/values-prod.yaml in ~/repos/deploy held the Redis password for 30 commits. Purge that value from history (replace with a placeholder), rotate the Redis password on the kind cluster, and replace the plain value with a SealedSecret (kubeseal against the cluster's controller) referenced by the chart.
- 平台
lin· Linux- 应用
- git-filter-repo · kubectl · kubeseal · helm
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP06· 代码 / 工程- 条件
risk· 高风险 / 不可逆multiapp· 多应用- 提案难度
- 5 / 5
建议验证方式
No blob contains the old password; Redis rejects old password and accepts the new one; SealedSecret in the chart decrypts in-cluster to a Secret used by the shop deployment; helm upgrade succeeds and pods connect (readiness true).
建议部分得分
30% history purged; 25% password rotated; 30% SealedSecret wired into the chart; 15% deployment healthy
R03.05.01.06-T20 Label 120 scanner findings as true or false positives
原始指令
fixtures/findings.json has 120 gitleaks findings from the monorepo. Using docs/secrets_policy.md (test fixtures, revoked keys, example placeholders count as false positives), label each finding TP or FP with a one-line reason and write ~/out/labels.csv (id,label,reason).
- 平台
lin· Linuxmac· macOS- 应用
- gitleaks · git · jq
- 交互表面
term· 终端- GUI 需求 · 任务设定
CL· CLI 足够- GUI 需求 · 普通权限
CL· CLI 足够- 交互原语
code· 代码与命令- 工作产物
WP02· 记录 / 表格- 条件
- 未声明
- 提案难度
- 4 / 5
建议验证方式
Labels compared to gold: precision and recall on TP must both be >= 0.9 for full credit; grader spot-checks reasons only for format (non-empty).
建议部分得分
50% TP recall >= 0.9; 40% TP precision >= 0.9; 10% all 120 rows present
已有研究映射
以下沿用研究目录中的基准与小类映射,不是逐题标注、执行记录或产品背书。