Skip to content

feat(validator): use manual transaction encryption key rotation - #2382

Merged
huitseeker merged 10 commits into
jmunoz-tx-encryption-key-rotationfrom
narrow-pr2373-manual-key-rotation
Jul 28, 2026
Merged

feat(validator): use manual transaction encryption key rotation#2382
huitseeker merged 10 commits into
jmunoz-tx-encryption-key-rotationfrom
narrow-pr2373-manual-key-rotation

Conversation

@huitseeker

@huitseeker huitseeker commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Changes transaction encryption key rotation from automatic to manual. Operators configure a previous key, a current key, and an optional next key when each validator starts. Keys activate only at epoch boundaries, which supports repeated planned rotations with a one-epoch grace period.

  • Validators sign the current key and optional next key as one schedule. The signature covers the network, activation blocks, and signing epoch. Clients reject stale or changed schedules.
  • Key providers own opaque key IDs and secret keys. They enforce premature, current, grace, expired, and unknown key rules. Expired previous keys can be removed after the grace period.
  • This removes automatic key derivation, the rotation worker, secret key export, and the SQLite key archive.

Schedule refreshes share one task, have fixed timeouts, and back off after errors or panics w/o treating cancellation as failure.

@huitseeker huitseeker added the no changelog This PR does not require an entry in the `CHANGELOG.md` file label Jul 27, 2026

@juan518munoz juan518munoz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks! Left some minor comments.

Comment thread bin/validator/src/commands/mod.rs
Comment thread docs/external/src/network-operator/validator.md Outdated
three keys.

Production deployments should not pass the secret in plaintext. Instead, wrap it with a symmetric AWS KMS key
At a rotation boundary, all validators must restart with the same schedule. For example, a restart that activates key B

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think "must restart at a rotation boundary" can be a bit ambiguous here - I'd say that the restarts must happen when changing the configured keys, and that keys automatically activate at epoch boundaries

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded. Restarts happen when the configured keys change; activation happens at epoch boundaries

Comment thread bin/validator/src/server/validator_service/mod.rs
Comment on lines +311 to +312
let chain_tip = *self.committed_tip.borrow();
let epoch = chain_tip.block_epoch();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a race from reading this snapshot outside the loop? By the time the mutex gets acquired another request could move the cache to the new attestation (then for the first request, cached.attested.epoch == epoch would fail and the cache would get rolled back).
If this could even happen it still seems like it would be a very low impact (if any) problem, as it would fail for a single request at most.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this race was possible. The tip is now read under the cache lock, with a regression test for this ordering

@huitseeker
huitseeker merged commit a55f6fa into jmunoz-tx-encryption-key-rotation Jul 28, 2026
21 of 22 checks passed
@huitseeker
huitseeker deleted the narrow-pr2373-manual-key-rotation branch July 28, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no changelog This PR does not require an entry in the `CHANGELOG.md` file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants