Rotating the app key
APP_KEY encrypts every tenant’s PowerSchool and SMTP credentials, and it signs sessions and cloud setup links. If it leaks, or on a schedule, rotate it in three steps: add a new key while keeping the old one, re-encrypt the stored secrets, then drop the old key. Nothing breaks until the last step, which signs everyone out.
Who this is for
Section titled “Who this is for”Server administrators of a self-hosted install.
Before you start
Section titled “Before you start”- Take a backup of the database and
.env. - Keep
APP_KEYonly in your host’s secret store (or the.envfile with restricted permissions). Don’t commit it or share it.
Rotate the key
Section titled “Rotate the key”-
Generate a new key:
Terminal window php artisan key:generate --showOn Docker, run it as
docker compose exec app php artisan key:generate --show. On a VM, run it assudo -u tidal php /var/www/tidal-ptc/artisan key:generate --show. The command prints the key and changes nothing. -
In
.env, set the new key asAPP_KEYand move the old key toAPP_PREVIOUS_KEYS. If there’s already a value there, separate the keys with commas.APP_KEY=base64:NEW_KEYAPP_PREVIOUS_KEYS=base64:OLD_KEYApply the change (see Applying a change). Existing secrets, sessions and links keep working, because the app can still decrypt with the old key.
-
Re-encrypt the tenant secrets with the new key:
Terminal window php artisan key:reencryptUse the same Docker or VM prefix as in step 1. This rewrites each tenant’s encrypted PowerSchool (
sis_config) and SMTP (smtp_config) settings and prints how many tenants it updated, for example “Re-encrypted secrets for 1 tenant(s).” -
Remove
APP_PREVIOUS_KEYSfrom.envand apply the change again. Everyone is signed out. In the cloud edition, unused setup links stop working; reissue them withphp artisan tenant:setup-link.
The PowerSchool plugin
Section titled “The PowerSchool plugin”The registration key inside the PowerSchool plugin is derived from APP_KEY. An installed, enabled plugin keeps working after a rotation, because its credentials are stored on the tenant. If you later reinstall or re-enable the plugin in PowerSchool, download a fresh copy from the tenant settings page first, so its registration key matches the new APP_KEY.
If there’s no key at all
Section titled “If there’s no key at all”php artisan key:check generates an app key only if none is set. It does nothing when APP_KEY already has a value, so it is not a way to rotate.