gabriel / muse public
feat patch auth dev
AI Agent gabriel · 148 days ago · Apr 25, 2026 · Diff

feat(auth): Phase 5 — PEM cleanup and security-check commands

muse auth cleanup-keys - Overwrites each ~/.muse/keys/*.pem with os.urandom bytes of equal length, fsyncs, then unlinks — no key material survives on disk - JSON: {destroyed: [...paths], count: N}

muse auth security-check - Four invariant checks: mnemonic in keychain, no PEM files, no key_path in identity.toml, fingerprint matches mnemonic derivation - Exits 1 if any check fails; JSON output for agent consumption - Ran on real identity: 6 stale PEM files destroyed; localhost:10003 and staging.musehub.ai entries flagged (pre-migration, will fix on re-register)

Doc: mark Phases 1-4 complete, Phase 5 in progress → now implemented Tests: 10 new tests (C1-C5, S1-S5) all green

sha256:a1157e1c48b653cabd6ebc9d43abbc7464ea0fc74413e1921c896ad45eb7e9df sha
+65 ~1 symbols
sha256:91938e39dee1e92dd0dc845984da194b0d371018a196aa56d3dd5ad7abdde909 snapshot
+65
symbols added
~1
symbol modified
0
dead code introduced
Semantic Changes 66 symbols
~ docs/key-material-security-audit.md .md 34 symbols added
+ Key Material Security Audit — Muse + MuseHub section Key Material Security Audit — Muse + MuseHub L1–256
+ Current State — What Exists Today section Current State — What Exists Today L32–90
+ py section muse/cli/commands/auth.py L73–82
+ py section muse/core/hdkeys.py L56–63
+ py section muse/core/identity.py L40–49
+ py section muse/core/keychain.py L34–40
+ py section muse/core/keypair.py L49–56
+ py section muse/core/msign.py L63–69
+ py — SigningIdentity section muse/core/transport.py — SigningIdentity L69–73
+ py section musehub/auth/request_signing.py L82–90
+ Files to Delete (Post-Phases 2–4) section Files to Delete (Post-Phases 2–4) L245–256
+ table@L247 section table@L247 L247–256
+ Identified Issues (Ranked by Severity) section Identified Issues (Ranked by Severity) L90–130
+ CRITICAL section CRITICAL L92–101
+ table@L94 section table@L94 L94–100
+ HIGH section HIGH L101–111
+ table@L103 section table@L103 L103–110
+ LOW section LOW L120–130
+ table@L122 section table@L122 L122–127
+ MEDIUM section MEDIUM L111–120
+ table@L113 section table@L113 L113–119
+ Implementation Plan section Implementation Plan L130–223
+ Phase 1 — Fix the Mnemonic Keychain Key (C3) ✅ COMPLETE section Phase 1 — Fix the Mnemonic Keychain Key (C3) ✅ COMPLETE L132–143
+ Phase 2 — Derive and Sign in Memory (C1, C2, H1) ✅ COMPLETE section Phase 2 — Derive and Sign in Memory (C1, C2, H1) ✅ COMPLETE L143–166
+ code@L148 variable variable code@L148 L148–158
+ toml Schema (C4) ✅ COMPLETE section Phase 3 — Remove key_path from identity.toml Schema (C4) ✅ COMPLETE L166–176
+ py CLI Commands (H2, H4) ✅ COMPLETE section Phase 4 — Update auth.py CLI Commands (H2, H4) ✅ COMPLETE L176–187
+ Phase 5 — Orphan PEM Cleanup 🔴 IN PROGRESS section Phase 5 — Orphan PEM Cleanup 🔴 IN PROGRESS L187–203
+ Phase 6 — DerivedKey Zeroing Hardening (M1, M2) section Phase 6 — DerivedKey Zeroing Hardening (M1, M2) L203–212
+ Phase 7 — MuseHub Server Audit (already clean, verify) section Phase 7 — MuseHub Server Audit (already clean, verify) L212–223
+ Migration Path (Zero-Downtime) section Migration Path (Zero-Downtime) L235–245
+ Test Checklist section Test Checklist L223–235
+ The Target Architecture section The Target Architecture L8–32
+ code@L10 variable variable code@L10 L10–29
~ tests/test_cmd_auth_phase5.py .py 27 symbols added
+ TestCleanupKeys class class TestCleanupKeys L86–167
+ test_C1_destroys_pem_files method method test_C1_destroys_pem_files L87–98
+ test_C2_json_output_lists_destroyed_paths method method test_C2_json_output_lists_destroyed_paths L100–114
+ test_C3_no_pem_files_is_not_an_error method method test_C3_no_pem_files_is_not_an_error L116–125
+ test_C4_pem_content_is_overwritten_before_deletion method method test_C4_pem_content_is_overwritten_before_deletion L127–152
+ test_C5_only_pem_files_are_deleted method method test_C5_only_pem_files_are_deleted L154–167
+ TestSecurityCheck class class TestSecurityCheck L175–272
+ test_S1_all_checks_pass_after_clean_keygen_register method method test_S1_all_checks_pass_after_clean_keygen_register L176–193
+ test_S2_fails_when_pem_file_exists method method test_S2_fails_when_pem_file_exists L195–212
+ test_S3_fails_when_key_path_in_identity method method test_S3_fails_when_key_path_in_identity L214–234
+ test_S4_fails_when_fingerprint_mismatches method method test_S4_fails_when_fingerprint_mismatches L236–255
+ test_S5_fails_when_no_mnemonic_in_keychain method method test_S5_fails_when_no_mnemonic_in_keychain L257–272
+ _FIXED_MNEMONIC variable variable _FIXED_MNEMONIC L25–28
+ _HOSTNAME variable variable _HOSTNAME L30–30
+ _HUB variable variable _HUB L29–29
+ _patch_home function function _patch_home L38–46
+ _patch_keychain function function _patch_keychain L49–54
+ _run_keygen_and_register function function _run_keygen_and_register L66–78
+ _write_fake_pem function function _write_fake_pem L57–63
+ CliRunner import import CliRunner L18–18
+ annotations import import annotations L12–12
+ id_module import import id_module L21–21
+ kp_module import import kp_module L20–20
+ os import import os L14–14
+ pathlib import import pathlib L15–15
+ pytest import import pytest L17–17
+ runner variable variable runner L23–23
~ muse/cli/commands/auth.py .py 4 symbols added, 1 symbol modified
+ _CleanupKeysJson class class _CleanupKeysJson L379–383
+ _SecurityCheckJson class class _SecurityCheckJson L386–395
+ run_cleanup_keys function function run_cleanup_keys L1970–2031
+ run_security_check function function run_security_check L2036–2156
← Older Oldest on dev
All commits
Newer → Latest on dev

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:a1157e1c48b653cabd6ebc9d43abbc7464ea0fc74413e1921c896ad45eb7e9df --body "your comment"