gabriel / musehub public
fix patch dev
AI Agent gabriel · 150 days ago · Apr 26, 2026 · Diff

fix: enforce canonical ed25519: prefix in auth key storage and test MSign suite

- b64url_decode: strip 'algo:' prefix before decoding (backward compat) - _seed helper: store public_key_b64 as 'ed25519:<b64url>' (canonical invariant) - Rewrite test_msign.py: correct push path (/push/stream), wire protocol body, and empty-body signing for application/x-muse-wire content type - All 65 MSign tests pass; all 52 crypto tests pass

sha256:82b50f941665621fb2305d1870b1eff3cd6c9700e7ceba8d30b601d21c5d2448 sha
+51 ~31 −23 symbols
sha256:e827969d3633a262172f57c2bb7b276199fc3d3147b1add25e805778fd6c0b3f snapshot
+51
symbols added
~31
symbols modified
−23
symbols removed
0
dead code introduced
Semantic Changes 105 symbols
~ musehub/crypto/keys.py .py 1 symbol modified
~ tests/test_msign.py .py 45 symbols added, 23 symbols removed, 30 symbols modified
TestBuildCanonicalMessageExtra class class TestBuildCanonicalMessageExtra L170–194
test_large_body_sha256_is_hex method method test_large_body_sha256_is_hex L184–189
test_query_string_appears_verbatim_in_fourth_line method method test_query_string_appears_verbatim_in_fourth_line L178–182
test_query_string_included_in_canonical method method test_query_string_included_in_canonical L173–176
test_context_handle_matches_identity_record method async_method test_context_handle_matches_identity_record L608–631
test_401_detail_not_empty method async_method test_401_detail_not_empty L388–402
test_agent_identity_type_sets_is_agent_true method async_method test_agent_identity_type_sets_is_agent_true L362–386
test_identity_not_found_returns_401 method async_method test_identity_not_found_returns_401 L259–273
test_optional_present_invalid_header_returns_401 method async_method test_optional_present_invalid_header_returns_401 L327–337
test_valid_push_request_accepts_and_returns_200 method async_method test_valid_push_request_accepts_and_returns_200 L240–257
test_ed25519_sign_is_fast method method test_ed25519_sign_is_fast L841–852
test_parse_header_under_50_microseconds method method test_parse_header_under_50_microseconds L829–839
test_verification_10_requests_under_2_seconds method async_method test_verification_10_requests_under_2_seconds L854–870
test_401_detail_does_not_leak_key_material method async_method test_401_detail_does_not_leak_key_material L771–792
test_handle_with_quote_injection_rejected method async_method test_handle_with_quote_injection_rejected L794–808
test_timestamp_exactly_at_boundary_accepted method async_method test_timestamp_exactly_at_boundary_accepted L735–750
test_timestamp_one_second_over_boundary_rejected method async_method test_timestamp_one_second_over_boundary_rejected L752–769
test_wrong_scheme_401_includes_www_authenticate method async_method test_wrong_scheme_401_includes_www_authenticate L699–714
test_parse_header_1000_times_completes_quickly method method test_parse_header_1000_times_completes_quickly L517–526
test_repeated_header_parse_with_fresh_timestamps method async_method test_repeated_header_parse_with_fresh_timestamps L474–487
test_two_identities_alternating_requests method async_method test_two_identities_alternating_requests L489–515
TestParseMsignHeaderExtra class class TestParseMsignHeaderExtra L197–228
test_empty_handle_not_parseable method method test_empty_handle_not_parseable L224–228
+ TestBuildCanonicalMessageUnit class class TestBuildCanonicalMessageUnit L303–340
+ test_algorithm_is_first_line method method test_algorithm_is_first_line L337–340
+ test_empty_body_hash_is_blob_id_of_empty method method test_empty_body_hash_is_blob_id_of_empty L331–335
+ test_large_body_sha256_is_hex method method test_large_body_sha256_is_hex L318–325
+ test_query_string_appears_verbatim_in_fourth_line method method test_query_string_appears_verbatim_in_fourth_line L312–316
+ test_query_string_included_in_canonical method method test_query_string_included_in_canonical L306–310
+ test_canonical_prefix_stored_and_verified method async_method test_canonical_prefix_stored_and_verified L799–822
+ test_context_handle_matches_identity_handle method async_method test_context_handle_matches_identity_handle L785–797
+ test_three_decoy_keys_then_correct_key method async_method test_three_decoy_keys_then_correct_key L764–783
+ test_401_response_has_detail method async_method test_401_response_has_detail L563–570
+ test_agent_identity_push_succeeds method async_method test_agent_identity_push_succeeds L551–561
+ test_push_without_auth_returns_401 method async_method test_push_without_auth_returns_401 L620–631
+ test_refs_endpoint_requires_no_auth_for_public_repo method async_method test_refs_endpoint_requires_no_auth_for_public_repo L610–618
+ test_optional_invalid_header_returns_401 method async_method test_optional_invalid_header_returns_401 L515–526
+ test_unknown_identity_returns_401 method async_method test_unknown_identity_returns_401 L467–474
+ test_valid_push_returns_200 method async_method test_valid_push_returns_200 L457–465
+ test_10_full_stack_verifications_under_2_seconds method async_method test_10_full_stack_verifications_under_2_seconds L1050–1066
+ test_ed25519_sign_under_1ms_median method method test_ed25519_sign_under_1ms_median L1037–1048
+ test_parse_header_under_50_microseconds_median method method test_parse_header_under_50_microseconds_median L1024–1035
+ test_future_timestamp_returns_401 method async_method test_future_timestamp_returns_401 L984–1001
+ test_handle_quote_injection_rejected_or_truncated method async_method test_handle_quote_injection_rejected_or_truncated L971–982
+ test_stale_timestamp_returns_401 method async_method test_stale_timestamp_returns_401 L926–944
+ test_timestamp_exactly_at_boundary_does_not_crash method async_method test_timestamp_exactly_at_boundary_does_not_crash L911–924
+ test_wrong_key_returns_401_without_leaking_key_material method async_method test_wrong_key_returns_401_without_leaking_key_material L946–969
+ test_wrong_scheme_returns_401_with_www_authenticate method async_method test_wrong_scheme_returns_401_with_www_authenticate L877–892
+ test_five_pushes_same_identity_all_succeed method async_method test_five_pushes_same_identity_all_succeed L701–712
+ test_parse_header_1000_times_completes_under_50ms method method test_parse_header_1000_times_completes_under_50ms L690–699
+ test_repeated_requests_with_fresh_timestamps_succeed method async_method test_repeated_requests_with_fresh_timestamps_succeed L657–670
+ test_two_identities_alternating_push_requests method async_method test_two_identities_alternating_push_requests L672–688
+ TestMWPFrameEncoderUnit class class TestMWPFrameEncoderUnit L389–440
+ test_envelope_is_valid_msgpack method method test_envelope_is_valid_msgpack L405–411
+ test_magic_bytes_correct method method test_magic_bytes_correct L396–399
+ test_minimal_push_body_ends_with_end_frame method method test_minimal_push_body_ends_with_end_frame L428–440
+ test_minimal_push_body_starts_with_header_frame method method test_minimal_push_body_starts_with_header_frame L422–426
+ test_payload_hash_matches_envelope_id method method test_payload_hash_matches_envelope_id L413–420
+ test_version_byte_is_one method method test_version_byte_is_one L401–403
+ TestParseMsignHeaderUnit class class TestParseMsignHeaderUnit L343–386
+ test_empty_handle_rejected method method test_empty_handle_rejected L370–374
+ test_returns_four_tuple method method test_returns_four_tuple L376–386
+ _encode_mwp_frame function function _encode_mwp_frame L100–125
+ _minimal_push_body function function _minimal_push_body L128–146
+ _push function async_function _push L226–248
+ blob_id import import blob_id L79–79
+ msgpack import import msgpack L73–73
+ struct import import struct L69–69
~ _seed
~ tests/test_musehub_auth_crypto.py .py 6 symbols added
+ TestB64urlDecodeCanonicalPrefix class class TestB64urlDecodeCanonicalPrefix L461–504
+ test_bare_base64url_still_decodes method method test_bare_base64url_still_decodes L470–474
+ test_prefixed_ed25519_key_decodes method method test_prefixed_ed25519_key_decodes L476–481
+ test_prefixed_ed25519_signature_decodes method method test_prefixed_ed25519_signature_decodes L483–488
+ test_round_trip_prefixed_key method method test_round_trip_prefixed_key L497–504
+ test_unknown_prefix_still_decodes_payload method method test_unknown_prefix_still_decodes_payload L490–495
← 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:82b50f941665621fb2305d1870b1eff3cd6c9700e7ceba8d30b601d21c5d2448 --body "your comment"