Safeguard
Security Guides•

How do you rotate the Laravel APP_KEY without breaking sessions?

Rotate the Laravel APP_KEY by setting a new key and listing the old one in APP_PREVIOUS_KEYS. Here is what breaks, what does not, and how to retire old keys.

Safeguard Security Team
3 min read

To rotate the Laravel APP_KEY without logging users out, generate a new key, set it as APP_KEY, and put the old key in APP_PREVIOUS_KEYS. Laravel encrypts with the current key and tries previous keys when decrypting, so existing sessions and encrypted data keep working during the changeover.

What the APP_KEY protects

Laravel uses APP_KEY as the encryption key behind its encrypter. Per the documentation, encrypted values use OpenSSL with AES and are signed with a message authentication code, so tampering is detected. Because Laravel encrypts every cookie, including the session cookie, the key matters for more than the Crypt facade.

If you simply replace the key, two things happen. All authenticated sessions are logged out, and any data encrypted with the old key can no longer be decrypted.

The graceful rotation

Generate the new key with the framework command, not by hand, since it uses PHP's secure random bytes generator:

php artisan key:generate --show

Then update your environment:

APP_KEY="base64:NEW_KEY_VALUE"
APP_PREVIOUS_KEYS="base64:OLD_KEY_VALUE"

The value of APP_PREVIOUS_KEYS is a comma delimited list, so you can keep several old keys. Laravel always encrypts with the current key. On decrypt it tries the current key first, then each previous key until one works.

Steps

  1. Decide why you are rotating: routine hygiene, or a suspected leak. The urgency differs.
  2. Generate a new key with key:generate --show.
  3. Copy the current APP_KEY into APP_PREVIOUS_KEYS, appending if the variable already exists.
  4. Deploy the new APP_KEY to every web server and every queue worker.
  5. Restart workers so they load the new environment.
  6. Re-encrypt stored data over time so it no longer depends on the old key.
  7. Remove the old key from APP_PREVIOUS_KEYS once nothing depends on it.

A leak is not a routine rotation

The graceful path keeps the old key working. That is the opposite of what you want if the old key was exposed. If an attacker holds the old key and it stays listed as a previous key, values made with it will still decrypt. In a suspected leak, plan a short window, re-encrypt stored values, then drop the old key quickly, accepting that some sessions will end.

SituationApproach
Scheduled rotationUse APP_PREVIOUS_KEYS, retire old key after a set period
Key exposed in a repo or logRotate, re-encrypt, remove the old key fast, accept logouts
Several servers or workersRoll out the same values everywhere before restarting

What to check after

Sign in with a test account that was logged in before the change and confirm the session survives. Decrypt a sample of stored encrypted values. Watch your error tracker for DecryptException, which Laravel throws when a value cannot be decrypted.

Quick check

Does Laravel re-encrypt old data automatically?

The documentation describes decryption falling back to previous keys. It does not describe automatic re-encryption of stored values, so plan that step yourself.

Where should the key live?

In the environment of each server, not in version control. The Laravel configuration docs advise against committing the .env file.

Safeguard's compliance and evidence automation can help you keep a dated record of when keys were rotated. A free scan is at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.