How do we migrate the data we already have?
- Date
- By
- CipherStash Team
Add an encrypted mirror column next to the plaintext one. Dual-write new changes, backfill history with the CLI, check coverage, build indexes, then move reads over. The plaintext column stays authoritative until you drop it, which makes every earlier stage reversible. Nothing is rewritten in place.
It is a real migration, and it takes more than one deploy. If someone tells you a production table with years of data gets encrypted with a flag flip, they are describing something else. What we can say is that the procedure is written down, the backfill is a resumable CLI command, and the source column is never touched until you decide to drop it.
The eight steps
- Add nullable encrypted columns next to the plaintext ones, typed for the queries you need.
name_encrypted public.eql_v3_text_eq,date_of_birth_encrypted public.eql_v3_date_ord. - Dual-write. Every insert and update writes plaintext and ciphertext in the same statement.
- Deploy and verify that new rows are landing in both columns.
- Backfill history with
npx stash encrypt backfill --table patients --column name. It runs in chunks and resumes if interrupted. - Run the coverage query from the guide to confirm no row has a plaintext value without a ciphertext.
- Build indexes on the encrypted columns.
- Move reads to the encrypted column.
- Soak, then
stash encrypt dropgenerates the migration that removes the plaintext column.
stash encrypt status and stash encrypt plan tell you where a table is in this sequence.
Rolling back
Until step 8 the plaintext column is still the source of truth, so rolling back any earlier stage means pointing reads or writes at it again. After the drop, the guide is explicit that you restore from an approved backup or run a decrypting migration. Plan the soak period with that in mind.
What the docs do not give you
There is no single "decrypt everything and leave" command in the CLI reference today. The SDK has bulk decrypt methods and decryption is never charged, so the work is yours to script rather than ours to bill, but it is a script you write. The exit note covers what else applies.