Repository navigation
fix(release): publish the key nodes enforce, and verify every release signature against it - #276
Conversation
… signature against it fda30ed rotated the embedded release key on 2026-03-24 but not sign/release-signing-key.pub, so every release since has failed to verify against the key the release notes point users to (confirmed on v0.23.1). Regenerate the file from RELEASE_SIGNING_KEY, which is unchanged; add a unit test holding the two equal; have the sign job verify each .sig against the file and fail the release on a mismatch; attach the key to each release. Closes V2-1802 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaidSafe-Hermes
left a comment
There was a problem hiding this comment.
APPROVE — reviewed head a8321ff (base 5413030). No blocking defects found in the three changed paths. The signing job uses the same archive patterns as its signing loop, fails on an empty archive set or any failed/missing signature, then includes the verified public key in the signed artifact and final release upload. The unit test binds the checked-in key bytes to the key embedded in node verification.
Verification: 2/2 independent seats reviewed (sol-1 gpt-6.1-sol xhigh; glm-1 z-ai/glm-5.3); both seats agree after checking their initial workflow-context questions against the full PR workflow. GitHub CI Gate and test/build jobs succeeded. Security Audit fails on RUSTSEC-2026-0387 (crypto-bigint 0.5.5); Cargo.lock is unchanged by this PR, so this is not introduced here and remains a separate merge gate. The focused local cargo test attempt timed out; no local test pass is claimed.
Non-blocking security note: a public key downloaded only from the same release as the artifact does not independently authenticate the release. Users still need a trusted way to establish that key (for example, compare it with the key in a trusted source checkout or an independently published fingerprint).
Brings in main up to 360d472: OS-assigned ports for e2e test nodes (WithAutonomi#281) and devnet nodes (WithAutonomi#282), release-key and signature checks (WithAutonomi#276), the third-party notices and audit-regression CI gates (WithAutonomi#274, WithAutonomi#275), the 10 s DHT request timeout for test nodes (WithAutonomi#277), and the 0.24.0 release (WithAutonomi#283). One conflict, in tests/e2e/harness.rs: main removed the network bring-up retry on a fresh port range together with NETWORK_START_ATTEMPTS and its `warn` import, and this branch had added two helpers next to them (POSSESSION_PENALTY_TRUST_RATIO and parseable_single_node_proof). The resolution keeps both helpers and takes main's removal.
Linear issue
Closes V2-1802
The release notes tell users to verify downloads with
ant-keygen verify --key release-signing-key.pub …. Butsign/release-signing-key.pubhasn't been the release key since 2026-03-24:src/upgrade/signature.rs.Nodes verify upgrades against the embedded key, so auto-upgrade was unaffected. Anyone verifying by hand would have seen every release since 03-24 fail.
Confirmed against v0.23.1 on dev2, using ant-keygen 0.1.0 (the latest release, which release.yml downloads) and ant-node's own
verify_binary_signature*:sign/release-signing-key.pubon main.pubfrom this PRant-node-cli-linux-x64.tar.gzant-node-cli-windows-x64.zipThe changes:
sign/release-signing-key.pubis regenerated byte for byte fromRELEASE_SIGNING_KEY: it starts55 ed f3 e1, sha256163f903d…6643. The embedded key, which is what nodes trust, is not changed.test_published_key_file_matches_embedded_key:include_bytes!of the.pubmust equalRELEASE_SIGNING_KEY. A rotation now has to change both copies. I kept the Rust array as the source rather than embedding the file withinclude_bytes!, so that a change to the key nodes trust stays a readable source diff, not "Binary file not shown".signjob: after signing, it verifies every archive's.sigwithant-keygen verify --key sign/release-signing-key.pub. The release fails on a mismatch, or if there are no archives. With the test above, this also shows nodes will accept the archives. Until now nothing checked the signatures the job produced. The job gets a sparse checkout ofsign/for this..pubis attached to each GitHub release, and the notes say it's attached and is the key nodes verify upgrades against. Before, users had to find it in the repo.Not in scope: V2-1749 (release.yml downloads ant-keygen unpinned;
verify-keydoesn't verify).Risk tier
T0 because the node's code and its embedded key are unchanged. This changes the published key file, a unit test and the release workflow. The reviewer should confirm, since it sits next to the upgrade mechanism.
Compatibility
Semver impact
Test evidence
On dev2 (Linux, stable 1.99.1):
.pubverifies with bothant-keygen verify(the release.yml command) and ant-node'sverify_binary_signature_with_key, and the old one is rejected.cargo fmt --all -- --check,cargo clippy --all-targets --all-features -- -D warnings,RUSTDOCFLAGS=-D warnings cargo doc --all-features --no-depsandcargo check --lib --no-default-features --lockedare all clean.cargo test --lib --features test-utils upgrade::signature: 13 passed..pubrestored,test_published_key_file_matches_embedded_keyfails with "sign/release-signing-key.pub is not RELEASE_SIGNING_KEY; regenerate the file from the embedded key (or rotate both)".actionlint .github/workflows/release.yml: clean. The new verify step first runs on the next release, or on adry_rundispatch, which runssigntoo.New dependency
none
ADR
n/a
Mitigation / rollback
Revert the PR. Nodes are unaffected either way, because the embedded key doesn't change. If the new verify step fails a release, it means a signature doesn't match the key nodes enforce. That release shouldn't ship.
🤖 Generated with Claude Code