fix(auth): rotate atomically syncs hub — register new key, deregister old
Bug: muse auth rotate only incremented the local HD index in identity.toml. It never registered the new key with the hub or deregistered the old one, leaving local and remote in an inconsistent state after every rotation.
Fix: run_rotate now performs a four-step atomic sequence: 1. Derive new key at index+1 2. Register new key with hub via challenge-response (_post_challenge/_post_verify) 3. Deregister old key via DELETE /api/auth/keys/{handle}/{key_id} (_hub_delete) 4. Update identity.toml only after hub confirms the new key
If hub registration fails (step 2), identity.toml is not touched — local and remote stay in sync. _hub_delete failure is non-fatal (warns and continues) since the hub may have already expired or revoked the old key.
Also adds _compute_key_id() to derive the hub key_id from identity_id and public_key_b64, mirroring musehub.core.genesis.compute_key_id.
auth.py: _json_post_raw now loads the local dev CA cert for localhost HTTPS so muse auth register works against the local hub without system-wide cert install.
tests/conftest.py: _isolate_muse_home autouse fixture now uses muse_dir() from muse.core.paths instead of raw '/.muse/' string construction.
tests/test_auth_rotate.py: - isolated fixture stubs _json_post_raw + _hub_delete (hub-safe by default) - IV: hub-sync integration tests (register, deregister, toml-after-hub, fail-fast) - muse_dir() replaces raw '/.muse/' strings throughout
0 comments
muse hub commit comment sha256:83386cdb9b53a8cb4e40d39838e89ed0788fc033cc9f746085b6fe289395f686 --body "your comment"
No comments yet. Be the first to start the discussion.