Skip to content

fix(secrets): never re-encrypt secrets that fail to decrypt - #315

Open
Minitour wants to merge 1 commit into
developfrom
fix/secret-migration-305
Open

Minitour wants to merge 1 commit into
developfrom
fix/secret-migration-305

Conversation

@Minitour

@Minitour Minitour commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Summary

The at-rest migration re-encrypted any enc:v1: value it couldn't decrypt, on every database open. A process that ever started with the wrong master key (restored or swapped master.key, a different HOME, a key-store bug) re-wrapped every stored secret under that key. After that, restoring the right key no longer recovered them. Closes #305.

Stack 1/5: base develop, next #316. Merge top-down: #319 into #318, ... #316 into #315, then #315 into develop.

What changed

  • canonicalizeStoredSecret only encrypts plaintext. Ciphertext that doesn't decrypt is left byte-identical and flagged.
  • migrateSecretsAtRest returns how many stored secrets are undecryptable, and the database exposes it as undecryptableSecrets.
  • That count is reported in three places:
    • a warning when the server starts;
    • secretStorage.undecryptable in /health;
    • a line in capa status.

Test plan

  • New test: a database written under key A and opened with key B keeps every value byte-identical and reports 3 undecryptable secrets. Reopened with key A, everything decrypts again.
  • Existing at-rest tests: plaintext rows are still migrated.
  • bunx tsc --noEmit

Checklist

  • Tests added or updated
  • bunx tsc --noEmit passes
  • Docs updated (if user-facing): not needed

🤖 Generated with Claude Code

The at-rest migration re-encrypted any enc:v1 value it couldn't decrypt.
A process started with the wrong master key (restored or swapped
master.key, different HOME, key-store bug) re-wrapped every stored
secret under that key, so restoring the right key later couldn't
recover them.

Values that don't decrypt are now left byte-identical. The count is
reported: a warning when the server starts, secretStorage.undecryptable
in /health, and a line in capa status. Only plaintext is migrated.

Closes #305
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant