[11.x] Adds command to re-encrypt table columns #50321
Closed
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.
What?
This PR introduces a command to automatically re-encrypt table columns after a key rotation. The only requirement is to have a primary key on the table, and the
APP_PREVIOUS_KEYS
filled with at least one valid key.Why?
Basically makes the data valid even if the developer doesn't have the previous key. The developer can push the key into the shell as environment variable temporarily, and call the command, without editing the
.env
file or the server variables.This works as a more permanent solution for the Laravel Encryption class that will cycle through each key to decrypt the data.
How?
By default, it only needs the "targets" (
table:column,column...
). It assumes the new key to encrypt the data is the APP_KEY, and the old data is encrypted with one of theAPP_PREVIOUS_KEYS
, using the same ciphers.Because sometimes the command or the database may fail for any reason, the re-encryption may stop mid-progress. To avoid leaving the table partially unusable, the command creates a column called
encrypted_at
for all rows successfully re-encrypted, which is removed at the end.If the user doesn't want that behaviour, the
--flag-column=false
can be used.The operation is done using
lazyById
to avoid memory problems on large rows and/or payloads. The connection, chunk size, and ID are configurable.