gabriel / muse public
feat BREAKING auth task/auth-keygen-hd #1 / 1
gabriel · 161 days ago · Apr 15, 2026 · Diff

feat(auth): muse auth keygen --hd — BIP39/SLIP-0010 HD identity key

Phase 1 of HD wallet integration.

keypair.py generate_hd_keypair(hostname, seed) — derives identity key via derive_identity_key(seed) over SLIP-0010 Ed25519 and writes PEM to the same path as a JBOK key. Deterministic from seed; never random.

identity.py IdentityEntry gains three optional HD provenance fields: key_source = 'hd' mnemonic = '<bip39 words>' hd_path = 'm/1075233755'/0'/0'/0'/0'/0'' _dump_identity serialises these fields when present; JBOK entries are unchanged (backwards compatible).

auth.py — muse auth keygen --hd New flags: --hd, --strength BITS (128/160/192/224/256, default 128), --language LANG (default english). HD path: generate mnemonic → derive seed → generate_hd_keypair → print mnemonic to stderr with safety warning → emit JSON (no mnemonic in stdout). JBOK path unchanged for existing users. Passphrase intentionally omitted from CLI (avoids shell history leak).

Tests: 38 cases — unit (IdentityEntry, _dump_identity, generate_hd_keypair), integration (CLI flags, PEM, permissions, word count, language, JSON shape), E2E (re-derivation round-trip, sign+verify), security, performance, docstrings. All 70 existing auth tests passing.

sha256:f31d95d7f79b845b7af34e2ae72e2c6eb19ea05655d7be3f1d73bdb60a6428e1 sha
+76 ~4 symbols
sha256:b4121a7a48ff6ea215647313e8e70e33aee79b75540b442089851dc41a040829 snapshot
+76
symbols added
~4
symbols modified
0
dead code introduced
Semantic Changes 80 symbols
~ tests/test_cmd_auth_keygen_hd.py .py 75 symbols added
+ TestDocstrings class class TestDocstrings L580–588
+ test_generate_hd_keypair_has_docstring method method test_generate_hd_keypair_has_docstring L581–583
+ test_run_keygen_mentions_hd method method test_run_keygen_mentions_hd L585–588
+ TestDumpIdentityHdFields class class TestDumpIdentityHdFields L148–209
+ test_hd_fields_round_trip_through_tomllib method method test_hd_fields_round_trip_through_tomllib L182–197
+ test_hd_path_serialised method method test_hd_path_serialised L171–180
+ test_jbok_entry_no_hd_fields method method test_jbok_entry_no_hd_fields L199–209
+ test_key_source_serialised method method test_key_source_serialised L151–158
+ test_mnemonic_serialised method method test_mnemonic_serialised L160–169
+ TestGenerateHdKeypair class class TestGenerateHdKeypair L217–298
+ test_derived_key_matches_hdkeys method method test_derived_key_matches_hdkeys L240–255
+ test_deterministic_same_seed method method test_deterministic_same_seed L279–287
+ test_different_from_jbok method method test_different_from_jbok L289–298
+ test_fingerprint_is_sha256_hex method method test_fingerprint_is_sha256_hex L230–238
+ test_pem_file_written method method test_pem_file_written L257–265
+ test_pem_is_valid_ed25519_key method method test_pem_is_valid_ed25519_key L267–277
+ test_returns_pub_b64_and_fingerprint method method test_returns_pub_b64_and_fingerprint L220–228
+ TestIdentityEntryHdFields class class TestIdentityEntryHdFields L111–145
+ test_hd_path_field_accepted method method test_hd_path_field_accepted L136–145
+ test_key_source_field_accepted method method test_key_source_field_accepted L114–123
+ test_mnemonic_field_accepted method method test_mnemonic_field_accepted L125–134
+ TestKeygenHdCli class class TestKeygenHdCli L306–443
+ test_exits_zero method method test_exits_zero L309–313
+ test_force_overwrites_existing method method test_force_overwrites_existing L426–433
+ test_json_output_has_hd_path method method test_json_output_has_hd_path L400–407
+ test_json_output_has_key_source method method test_json_output_has_key_source L392–398
+ test_json_output_has_mnemonic_word_count method method test_json_output_has_mnemonic_word_count L409–415
+ test_json_output_no_mnemonic_in_stdout method method test_json_output_no_mnemonic_in_stdout L382–390
+ test_json_output_standard_fields method method test_json_output_standard_fields L417–424
+ test_language_spanish method method test_language_spanish L367–380
+ test_mnemonic_in_stderr method method test_mnemonic_in_stderr L330–335
+ test_mnemonic_is_12_words_by_default method method test_mnemonic_is_12_words_by_default L337–350
+ test_no_force_rejects_existing method method test_no_force_rejects_existing L435–443
+ test_pem_permissions_600 method method test_pem_permissions_600 L322–328
+ test_pem_written method method test_pem_written L315–320
+ test_strength_256_produces_24_words method method test_strength_256_produces_24_words L352–365
+ TestKeygenHdEndToEnd class class TestKeygenHdEndToEnd L451–504
+ test_derived_key_reproducible_from_stored_mnemonic method method test_derived_key_reproducible_from_stored_mnemonic L454–488
+ test_pem_loads_and_signs method method test_pem_loads_and_signs L490–504
+ TestKeygenHdPerformance class class TestKeygenHdPerformance L558–572
+ test_keygen_hd_under_2s method method test_keygen_hd_under_2s L561–572
+ TestKeygenHdSecurity class class TestKeygenHdSecurity L512–550
+ test_mnemonic_not_in_json_stdout method method test_mnemonic_not_in_json_stdout L515–521
+ test_pem_mode_is_600 method method test_pem_mode_is_600 L543–550
+ test_unsupported_language_exits_nonzero method method test_unsupported_language_exits_nonzero L533–541
+ test_unsupported_strength_exits_nonzero method method test_unsupported_strength_exits_nonzero L523–531
+ _keygen_hd function function _keygen_hd L97–103
+ _patch_home function function _patch_home L86–94
+ CliRunner import import CliRunner L62–62
+ DOMAIN_IDENTITY import import DOMAIN_IDENTITY L67–67
+ ENTITY_HUMAN import import ENTITY_HUMAN L67–67
+ IdentityEntry import import IdentityEntry L65–65
+ MUSE_PURPOSE import import MUSE_PURPOSE L67–67
+ ROLE_SIGN import import ROLE_SIGN L67–67
+ STRENGTH_PARANOID import import STRENGTH_PARANOID L66–66
+ _dump_identity import import _dump_identity L65–65
+ annotations import import annotations L49–49
+ base64 import import base64 L51–51
+ derive_identity_key import import derive_identity_key L67–67
+ hashlib import import hashlib L52–52
+ id_module import import id_module L64–64
+ json import import json L53–53
+ kp_module import import kp_module L63–63
+ load_pem_private_key import import load_pem_private_key L60–60
+ master_key import import master_key L75–75
+ mnemonic_to_seed import import mnemonic_to_seed L76–76
+ muse_path import import muse_path L67–67
+ os import import os L54–54
+ pathlib import import pathlib L55–55
+ pytest import import pytest L59–59
+ stat import import stat L56–56
+ time import import time L57–57
+ validate_mnemonic import import validate_mnemonic L66–66
+ word_count import import word_count L66–66
+ runner variable variable runner L78–78
~ muse/cli/commands/auth.py .py 2 symbols modified
~ muse/core/identity.py .py 2 symbols modified
~ muse/core/keypair.py .py 1 symbol added
+ generate_hd_keypair function function generate_hd_keypair L238–296
← Older Oldest on task/auth-keygen-hd
All commits
Newer → Latest on task/auth-keygen-hd

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