Problem/Motivation
I'm sure we all can agree that periodically rotating encryption keys is good for security, and sometimes rotating a key is mandatory (lost private key, migrating to more secure algorithms, etc)
While the Encrypt module can not be expected to know about how the data it encrypts is stored I believe that the Encrypt module should be responsible for providing the base framework to allow encrypt profile rotation. By providing a standard framework we make it easier for sites to rotate encryption keys.
Steps to reproduce
N/A
Proposed resolution
The ideal design would in my opinion be to have Encrypt notify its consumers that a key roation is necessary. Consumers shall implement their own internal methods to re-wrap the data.
Consumers may choose to support both the source profile and the destination profile while the re-wrap is in progress, or may choose to not function until rotation is complete, this is a discussion for consumers to determine what is best for their application. Upon completion of a profile migration consumers should modify their configuration to adopt the new profile.
Encrypt can provide tools to make it easier and provide some safety interlocks.
To avoid loops and avoid expecting plugins to to manage multiple sequential re-wraps the Encrypt module will not emit a triggering event when the source profile is currently being utilized as the destination profile for an in progress rotation.
Remaining tasks
Discuss if this concept is acceptable.
Continue working on patch to move it from an outline to functional code.
User interface changes
UI additions to support migrating profiles.
API changes
New Events that Consumers must implement
Optional new Interfaces that EncyrptionProviders may opt into.
Data model changes
TBD
Summary of new design
New Events:
Emitted:
EncryptEvents::ROTATE_PROFILE : Emitted by Encrypt module upon request to rotate profiles globally. Used when all consumers need to rotate their data Should provide a source profile and a destination profile. May omit the destination profile if the source profile internally supports rotation and wishes to rewrap the data internally.
Event Listeners:
EncryptEvents::REQUEST_PROFILE_ROTATION_START: Emitted by contrib when a module wishes to rotate profiles for its own use (not rotating globaly), shall include the source profile and destination profile, module name, and a job ID. Used to validate that the source profile is not a destination in an existing in progress rotation. Encrypt will not approve a request where the source profile is the destination for an in-progress migration.
EncryptEvents::PROFILE_ROTATION_START: Emitted when a module utilizing Encrypt starts rotating keys, either in response to ENCRYPT_KEY_ROTATION or if the module needs/wants to rotate keys. Shall include the module name, the source profile, destination profile, and a module provided job id.
EncryptEvents::PROFILE_ROTATION_PROGRESS: Emitted by a module to provide an update on progress. Includes the module name, job id, and progress.
EncryptEvents::PROFILE_ROTATION_COMPLETE: Emitted when a module completes rotation of the key. Includes module name and job id.
Plugin Changes:
Encryption Providers are not mandated to be modified to provide any new methods, though they may opt in to a new EncryptionReWrapInterface if they are able to internally handle the decryption and subsequent encryption of the data, this is useful for external cryptography systems like Vault to avoid transferring the plaintext across the network.
Consumer Changes:
In order for this framework to work Consumers (modules like TFA, webform_encrypt, file_encrypt, etc) will need to be updated to listen for EncryptEvents::ROTATE_PROFILE events, process the data they store and emit progress update events. Some consumers may have more work than others to adopt this system depending upon how easy it is for them to obtain all data that needs to be re-wraped.
A EncryptEvents::SUPPORT_ROTATION event to determine if a module supports rotation. A warning will be displayed for modules that do not support rotation so that users are made aware of the ongoing limitation. This can be used to allow this to be implemented in 8.x-3.x. without making this a breaking API change.
Consumers may leverage any helper services in encrypt to rotate profiles without the profile being rotated globally.