fix(issue-12): scrub-secrets selects only records with a stored password
Review of4176d75(planner-reviewer-claude-01, N1): _cmd_scrub_secrets chose records by the presence of broker.password, not by its value. The old to_registry_block wrote "password": null even for an unauthenticated broker, so on this repo's registry (901 of 903 records carry the null key, none a real password) --dry-run reported "would scrub 901 record(s)" and a real run would rewrite every one of them while holding the registry lock. - registry.py: select on broker.get("password"); an empty key is no secret, and _atomic_write_record drops it on the record's next write anyway - tests: the migration test gains a legacy "password": null record that must be neither listed nor rewritten (fails on4176d75with "would scrub 2") - VERSIONS.md v4.4.4 item 2 and registry.md now describe the stored-value rule Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HCGpJXhSZasJLU38ksDghe
This commit is contained in:
1 parent
4176d7570f
commit
0fedae2f46
4 files changed
+23
-5
No files matched your search
@@ -79,12 +79,22 @@ def test_scrub_secrets_cli_migrates_a_registry(mam_sandbox, monkeypatch):
|
||||
rec["broker"]["password"] = "leaked-earlier"
|
||||
dirty_path.write_text(json.dumps(rec))
|
||||
clean_before = (Path(rd) / f"{clean}.json").read_text()
|
||||
# What the old to_registry_block wrote for every unauthenticated job: the key
|
||||
# with a null value. No secret, so the migration must neither report nor
|
||||
# rewrite it (a real PoC registry held ~900 of these and no password at all).
|
||||
empty = registry.register_job("empty-key", "claude-code", "herdr:claude", registry_dir=rd)
|
||||
empty_path = Path(rd) / f"{empty}.json"
|
||||
rec_empty = json.loads(empty_path.read_text())
|
||||
rec_empty["broker"]["password"] = None
|
||||
empty_path.write_text(json.dumps(rec_empty))
|
||||
empty_before = empty_path.read_text()
|
||||
|
||||
env = dict(os.environ, PYTHONPATH=f"{SKILLS}:{os.environ.get('PYTHONPATH', '')}")
|
||||
dry = subprocess.run([sys.executable, str(REGISTRY_PY), "--registry-dir", rd, "scrub-secrets", "--dry-run"],
|
||||
capture_output=True, text=True, env=env, cwd=str(mam_sandbox))
|
||||
assert dry.returncode == 0, dry.stderr
|
||||
assert f"would scrub 1 record(s)" in dry.stdout and dirty in dry.stdout
|
||||
assert empty not in dry.stdout, "an empty password key is not a stored secret"
|
||||
assert "leaked-earlier" in dirty_path.read_text(), "--dry-run must not write"
|
||||
|
||||
res = subprocess.run([sys.executable, str(REGISTRY_PY), "--registry-dir", rd, "scrub-secrets"],
|
||||
@@ -95,3 +105,4 @@ def test_scrub_secrets_cli_migrates_a_registry(mam_sandbox, monkeypatch):
|
||||
assert "password" not in scrubbed["broker"]
|
||||
assert scrubbed["prompt"] == "dirty" and scrubbed["auth_token"] == rec["auth_token"]
|
||||
assert (Path(rd) / f"{clean}.json").read_text() == clean_before, "untouched records are not rewritten"
|
||||
assert empty_path.read_text() == empty_before, "a null password key is left for the record's next write"
|
||||
Reference in new issue
Block a user