-
Notifications
You must be signed in to change notification settings - Fork 0
Description
We use the APP_SECRET variable for a couple of things:
- to encrypt data before saving in the database
- to hash (HMAC) sensitive data that is used for checking uniqueness (for example, IP addresses in Hyvor Talk)
How to rotate
If our app secret is leaked, we need to be ready to rotate it. This is done in two steps.
Before rotation, we have this:
APP_SECRET=key1As the first step, we set APP_SECRET to the new key and APP_SECRET_PREVIOUS to the old key.
APP_SECRET=key2
APP_SECRET_PREVIOUS=key1How we handle encryption and hashing is explained below when we have two keys.
Then, we run the following command on one of the servers:
bin/console rotate:keyIt emits the following event:
class RotateAppSecretKeyEvent
{
public function __construct(
public string $newKey,
public string $previousKey,
public OutputInterface $output, // to log messages to the console (such as what's being handled)
) {}
}App-side handling
On the app side, we have to handle things carefully to support rotating:
1. Encryption
We should always use the current APP_SECRET when encrypting.
2. Decryption
We should try to decrypt by both keys if APP_SECRET_PREVIOUS is present:
(we might need a helper for encrypting in the internal lib)
try {
return decryptBySecretKey($payload);
} catch (DecryptionFailedException) {
return decryptBySecretKeyPrevious($payload);
}3. Hashing (HMAC)
Similarly to encrypting, always use the current APP_SECRET when hashing.
4. Hash Verifying
(For example, in a query like WHERE ip_hash = :hash)
We should check with both keys if they are present:
WHERE ip_hash = :hashWithAppSecret
WHERE ip_hash = :hashWithAppSecretPrevious
If we find at least one, we have that record in the database.
5. Rotating keys
bin/console rotate:key dispatches the RotateAppSecretKeyEvent but it does not do anything by itself. The app should have listeners that actually handles the rotation. You need to
- get all encrypted data, decrypt them using the old key, re-encrypt them from the new key
- get all hashed data