fix: delete orphaned SignatureKeyPair when clearing a self_update commit#197
Merged
Merged
Conversation
When self_update() stores a new SignatureKeyPair before creating a pending commit, and that commit is then rolled back via clear_pending_commit(), the new keypair previously remained in storage indefinitely — accumulating unreachable private key material with each failed publish attempt. clear_pending_commit() now detects self-update commits (using the same update_path_leaf_node heuristic as merge_pending_commit), extracts the new leaf's public key, and calls SignatureKeyPair::delete() after the rollback, as required by the OpenMLS documentation. Two new tests cover this: - test_self_update_then_merge_no_orphan: verifies the happy path leaves the new key in storage as the active signer after a successful merge - test_self_update_then_clear_removes_orphaned_keypair: verifies the orphaned key is deleted after a clear, and the group can retry
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR addresses orphaned private key material accumulation by enhancing the clear_pending_commit function to detect self_update commits, extract the newly-stored signing key's public key, and delete the associated orphaned SignatureKeyPair from storage. Related tests verify the cleanup behavior works correctly. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
✅ Coverage: 91.04% → 91.08% (+0.04%) |
✅ Coverage: 91.04% → 91.09% (+0.05%) |
dannym-arx
approved these changes
Feb 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When
self_update()creates a pending commit, it eagerly stores a newSignatureKeyPairin the provider before calling OpenMLS. If the Kind:445 publish fails andclear_pending_commit()is called to roll back, the MLS group reverts to the old signer — but the new keypair previously remained in storage indefinitely.This violates the OpenMLS documentation, which explicitly states that the application is responsible for deleting the new keypair when discarding a self-update commit. In persistent storage (SQLite), repeated failed self-update publishes would accumulate unreachable private key material.
Changes
clear_pending_commit: Before clearing, detects whether the pending commit is a self-update (using the sameupdate_path_leaf_nodeheuristic asmerge_pending_commit). If so, captures the new leaf's public key and callsSignatureKeyPair::delete()after the rollback.test_self_update_then_merge_no_orphan: Verifies the happy path — afterself_update+merge_pending_commit, the new keypair is present before merge and remains present after (it is now the active signer).test_self_update_then_clear_removes_orphaned_keypair: Verifies the fix — afterself_update+clear_pending_commit, the new keypair is present before clearing and absent after. Also verifies the group can successfully retryself_update+merge_pending_commit.