gabriel / muse public
fix task/223-fix-hub-scoping-uses-rotate-endpoint #1 / 1
AI Agent gabriel · 1 day ago · Sep 18, 2026 · Diff

fix: hub-scoping migration must use the key-rotation endpoint, not fresh registration (musehub#221 follow-up)

Found running the previous fix for real against local musehub: POST /api/auth/verify (fresh registration) correctly rejected the migration with HTTP 409 ("Handle 'gabriel' is already taken or this key is already registered"). That endpoint is for brand-new identities -- hub-scoping migration is a key *rotation* for an already-registered handle, which is a completely different, MSign-authenticated hub flow. `_json_post_raw` also raises SystemExit (not a plain Exception) on HTTP failure, which the previous `except Exception` handler wouldn't have caught either -- a real HTTP error on one hub would have aborted the entire multi-hub migration instead of just marking that hub failed.

`_make_hub_register_fn` now mirrors `muse auth rotate`'s real flow (auth.py's run_rotate, lines ~1414-1514) exactly:

1. Derive both the OLD key (at the entry's current hd_path, pre-mutation) and the NEW hub-scoped key from the seed. 2. Challenge for the new key's fingerprint, sign the nonce with the NEW key. 3. POST /api/auth/keys with the new key's challenge response in the body, MSign-authenticated with the OLD key -- proves account ownership (old key) and new key ownership (challenge signature) in one request. 4. Best-effort DELETE /api/auth/keys/{handle}/{key_id} to deregister the old key, signed with the old key. Non-fatal on failure, matching rotate. 5. Catches (Exception, SystemExit) around the whole network flow so one hub's HTTP failure can't abort a multi-hub live run.

Rewrote all _make_hub_register_fn tests against the real endpoint: correct /api/auth/keys payload, MSign header verified to authenticate as the OLD key (and NOT the new key), new-key challenge signature verified against the new key, old-key deregistration wired up and confirmed non-fatal on failure, and a new SystemExit-from-_json_post_raw regression test reproducing the actual 409 failure mode hit in manual testing.

Verified against real local musehub (localhost:1337, healthy, 6 days uptime) after rebuilding the installed venv from this source: dry-run still correct; live run against --hub localhost still pending re-test with this fix.

Tests: 50/50 in test_migrate_hub_scoping.py, 145/145 across the full migrate/rotate/register targeted set.

sha256:8eee8bc28cbde8210f659eb0beacb6878fe5c740fe78df646db791ad76ba2c1e sha
+7 ~5 −4 symbols
sha256:6cfc9c35ba169720b0b50a1efecc26af40659723909c9f0c4c4017b6bb8c5a6b snapshot
+7
symbols added
~5
symbols modified
−4
symbols removed
0
dead code introduced
Semantic Changes 16 symbols
~ tests/test_migrate_hub_scoping.py .py 7 symbols added, 4 symbols removed, 4 symbols modified
test_hub_http_failure_returns_false_not_raise method method test_hub_http_failure_returns_false_not_raise L703–718
test_sends_correct_challenge_payload method method test_sends_correct_challenge_payload L575–607
test_signature_verifies_against_new_key method method test_signature_verifies_against_new_key L609–648
test_verify_payload_public_key_matches_new_fingerprint method method test_verify_payload_public_key_matches_new_fingerprint L650–677
+ _setup method method _setup L585–598
+ test_delete_failure_is_non_fatal method method test_delete_failure_is_non_fatal L722–742
+ test_deregisters_old_key_after_successful_add method method test_deregisters_old_key_after_successful_add L684–720
+ test_hub_http_failure_from_challenge_returns_false_not_raise method method test_hub_http_failure_from_challenge_returns_false_not_raise L765–777
+ test_new_key_signature_in_payload_verifies_against_new_key method method test_new_key_signature_in_payload_verifies_against_new_key L655–682
+ test_sends_correct_add_key_payload_and_msign_auth method method test_sends_correct_add_key_payload_and_msign_auth L600–653
+ test_systemexit_from_add_key_returns_false_not_raise method method test_systemexit_from_add_key_returns_false_not_raise L779–801
← Older Oldest on task/223-fix-hub-scoping-uses-rotate-endpoint
All commits
Newer → Latest on task/223-fix-hub-scoping-uses-rotate-endpoint

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:8eee8bc28cbde8210f659eb0beacb6878fe5c740fe78df646db791ad76ba2c1e --body "your comment"