Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[11.x] Adds command to re-encrypt table columns #50321

Closed
wants to merge 1 commit into from
Closed

[11.x] Adds command to re-encrypt table columns #50321

wants to merge 1 commit into from

Conversation

DarkGhostHunter
Copy link
Contributor

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.

APP_PREVIOUS_KEY=base64:4Fs6Ra...
php artisan crypt:re-encrypt users:notes,credit-card-number 

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 the APP_PREVIOUS_KEYS, using the same ciphers.

php artisan crypt:re-encrypt users:notes,credit-card-number 

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.

php artisan crypt:re-encrypt users:notes,credit-card-number --flag-column=false

The operation is done using lazyById to avoid memory problems on large rows and/or payloads. The connection, chunk size, and ID are configurable.

php artisan crypt:re-encrypt users:notes,credit-card-number
    --connection=pgsql \
    --chunk=100 \
    --id=uuid

@taylorotwell
Copy link
Member

I think this should be built as a nice package first so we can proof of concept it before building it directly into the framework, but I think this will be valuable to have soon. 👍 For example, there may be ways to distribute the work across job batches, etc.

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.

2 participants