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
@@ -345,13 +345,19 @@ def _build_parser() -> argparse.ArgumentParser:
|
||||
|
||||
def _cmd_scrub_secrets(args) -> int:
|
||||
"""Issue #12: strip broker.password from records written before
|
||||
to_registry_block stopped persisting it. Every other field is kept."""
|
||||
to_registry_block stopped persisting it. Every other field is kept.
|
||||
|
||||
Only a stored value counts. The old rule wrote `"password": null` even
|
||||
for an unauthenticated broker; that empty key is no secret, and
|
||||
_atomic_write_record drops it on the record's next write anyway, so
|
||||
reporting or rewriting it here would list phantom secrets and hold the
|
||||
registry lock over every record in a PoC registry."""
|
||||
rd = args.registry_dir
|
||||
found = []
|
||||
with registry_lock(rd):
|
||||
for record in list(_iter_records(rd)):
|
||||
broker = record.get("broker")
|
||||
if not (isinstance(broker, dict) and "password" in broker):
|
||||
if not (isinstance(broker, dict) and broker.get("password")):
|
||||
continue
|
||||
found.append(record.get("job_id", "?"))
|
||||
if not args.dry_run:
|
||||
|
||||
@@ -57,8 +57,9 @@ Reference implementation: [`./scripts/registry.py`](./scripts/registry.py)
|
||||
overrides toggles like `MQTT_TLS`). It never carries the password (Issue #12):
|
||||
every sub-agent can read the record, so `MQTT_PASSWORD` is layered back from
|
||||
the environment (`.mam.env`) at connect time. Records written before that rule
|
||||
are cleaned on their next write; `registry.py scrub-secrets [--dry-run]` cleans
|
||||
a whole registry at once. `auth_token` and `dispatch_token` stay in the record
|
||||
are cleaned on their next write; `registry.py scrub-secrets [--dry-run]` strips
|
||||
every stored password from a whole registry at once (an empty `null` key left
|
||||
by the old rule is not a secret; it goes on the record's next write). `auth_token` and `dispatch_token` stay in the record
|
||||
because the agent's own `publish_event` needs them to sign and to pin its
|
||||
attempt.
|
||||
- `topic_prefix` → the events topic is `<topic_prefix>/events`.
|
||||
|
||||
Reference in new issue
Block a user