muse verify reports INVALID for commits signed with rotated keys
Ed25519 signature verification fails for commits signed with rotated keys
Background
muse verify reports "Ed25519 signature INVALID" for commits that were signed
with a key that is no longer the active identity key. This surfaces after a key
rotation or after ~/.muse/secrets/ is regenerated — the old signing key
(d526dbdee171d299 in the observed case) is gone, so the verifier cannot
check the signature even though the commit was legitimately produced.
The commits are not tampered with. The content, DAG structure, and object hashes are all intact. The failure is purely a key-lookup miss: the verifier finds a signature but cannot resolve the public key that produced it.
Problem
The current verifier treats "can't verify" as "INVALID", which is misleading. A signature from a retired key is not evidence of tampering — it is evidence of a key lifecycle event. Logging it at the same severity as a genuine integrity violation creates false-positive noise and may erode trust in the audit trail.
There are two related questions to resolve:
Should
muse verifysweep prior HD-derived key paths when the current active key doesn't match the embeddedsigner_public_key? A commit signed at HD indexnis still verifiable if we re-derive the key at that index from the root mnemonic. This would allow full provenance verification across key rotations without any schema changes.Should the error message be tiered? A signature whose public key is simply not found (key retired / mnemonic unavailable) should read differently from a signature whose public key is found but the bytes don't match (genuine tampering). The former is an audit gap; the latter is a security alert.
Goal
muse verify produces accurate, actionable output:
- Commits signed with any key derivable from the current root mnemonic → ✅ verified
- Commits signed with a key from a mnemonic that is gone (e.g. fresh keygen
with
--destroy-mnemonic) → ⚠️ unverifiable (key not available), not ❌ INVALID - Commits where the key is present but the signature bytes don't match → ❌ INVALID (tampered)
Acceptance criteria
- Running
muse verifyon a repo with commits from a rotated-but-still-derivable key returns ✅ for those commits (HD sweep finds the right key). - Commits from a destroyed/unavailable key show a distinct warning level, not
the same
INVALIDmessage used for genuine signature mismatches. - Genuine tampered commits (bytes modified post-sign) still show ❌ INVALID.
muse verify --strictflag (or equivalent) can be used to treat unverifiable-key commits as failures for CI/compliance contexts.
Out of scope
- Re-signing old commits with the new key (would change commit IDs)
- Storing retired public keys in the identity repo (future hardening)