feat: add muse auth show --public-key to recover a registered public key
muse#100. muse sign verify --public-key-b64 needs the raw base64url Ed25519 public key (no ed25519: prefix). The only time that value was ever printed was at keygen/register time -- muse auth whoami/show/key list all expose only the one-way fingerprint, which can't be reversed back to the public key bytes. The only recovery path was re-deriving it from the keychain mnemonic via internal Python modules.
Adds --public-key (+ --agent-id for agent identities) to muse auth show. Resolves via the exact same path muse sign itself uses (get_signing_identity + sign.py's own _public_key_info) rather than a parallel reimplementation -- guarantees the printed value is always byte-identical to what muse sign verify actually expects, never a plausible-looking but subtly different derivation. Text mode prints just the raw key (scriptable: muse sign verify --public-key-b64 "$(muse auth show --hub URL --public-key)"); --json wraps it with hub/handle/fingerprint.
Tests: new tests/test_auth_show_public_key.py, 6 tests -- unit test proving byte-identical output to sign.py's own _public_key_info, no-identity returns None cleanly, CLI text/json round-trips, clean structured error (no crash) when no identity is registered, and a full end-to-end round trip through the real build_msign_header/verify_msign_header functions. All green.
Fixed 4 pre-existing tests in test_auth_show_migrate.py that broke from this change: they stand up `ns = MagicMock()` for run_show's argparse Namespace without setting the new public_key/agent_id attributes -- MagicMock auto-creates any attribute access as a truthy MagicMock rather than raising AttributeError, so getattr(args, "public_key", False) never hit the False default and accidentally routed into the new code path. Explicitly setting ns.public_key = False / ns.agent_id = None in these tests (matching how they already explicitly set ns.hub) fixes this -- same hazard will resurface for any future boolean flag added to run_show unless tests move off bare MagicMock for argparse stand-ins.
Verified against a real registered identity (muse-dev, staging.musehub.ai): printed public key's derived fingerprint matches muse sign header's own reported fingerprint exactly; a header signed with muse sign header and verified with muse sign verify --public-key-b64 using the exact value this command printed returns {"valid": true} -- the ticket's acceptance criterion, proven end-to-end with a real identity, not just mocked tests.
Semantic Changes
36 symbols
Files Changed
+1
~2
1212 in snapshot
0 comments
muse hub commit comment sha256:78acbed7a7a67d36a9080f3f2bf851be873e69fe8851cdd29b7bd59827504cbc --body "your comment"
No comments yet. Be the first to start the discussion.