Application Key Analyzer
| Analyzer ID | Category | Severity | Time To Fix |
|---|---|---|---|
app-key | 🛡️ Security | Critical | 5 minutes |
What This Checks
Validates that Laravel's APP_KEY encryption key is properly configured and secure in your .env file and config/app.php. Checks for:
- Missing or empty APP_KEY in
.env - Placeholder/example values (e.g., "your-key-here")
- Weak key formats (too short or improperly encoded)
- Duplicate APP_KEY definitions in
.env - Hardcoded keys in
config/app.php(should useenv()) - Insecure cipher algorithms
Why It Matters
- Security Risk: HIGH - The APP_KEY is used for all encryption in Laravel (sessions, cookies, encrypted data)
- Data Loss: If APP_KEY changes, all encrypted data becomes permanently unreadable
- Session Security: Weak or default keys allow attackers to forge sessions and impersonate users
- CSRF Protection: Laravel's CSRF tokens depend on APP_KEY for cryptographic signing
How to Fix
Quick Fix (1 minute)
Scenario 1: Missing or Empty APP_KEY
bash
# Generate a secure key
php artisan key:generate
# This updates your .env file with a secure base64-encoded key
# APP_KEY=base64:RANDOM_32_BYTE_STRING_HEREScenario 2: Placeholder Value (from .env.example)
bash
# Remove the placeholder and generate a real key
php artisan key:generate --forceScenario 3: Configuration is Cached
bash
# Clear the cache to allow .env changes to take effect
php artisan config:clear
# After making changes, recache for production
php artisan config:cacheProper Fix (5 minutes)
Implement comprehensive APP_KEY security across all environments:
1. Generate and Store Keys Securely
bash
# Generate key for each environment
php artisan key:generate
# For production, store in environment variables
# Laravel Forge/Vapor:
# - Add APP_KEY to environment variables in dashboard
# Traditional servers:
# - Add to web server environment config
# - Or use encrypted .env files2. Environment-Specific Key Management
bash
# Development (.env) - Use a unique key for local development
APP_KEY=base64:LOCAL_DEV_KEY_HERE
# Production/Staging - Manage through deployment process
# - Use CI/CD environment variables
# - Use secrets managers (AWS Secrets Manager, Vault, etc.)
# - Use platform environment config (Laravel Forge, Vapor, etc.)
# Important: Production and staging should typically use the SAME key
# if you share encrypted data between them (e.g., database backups)3. Never Commit Real Keys to Git
ini
# .env.example - Use placeholders only
APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:your-key-here
APP_DEBUG=false
APP_URL=https://yourapp.com4. Handle Key Rotation Carefully
php
// If you must rotate keys, decrypt with old key and re-encrypt with new key
// Don't do this unless absolutely necessary (security breach, etc.)
use Illuminate\Support\Facades\Crypt;
use Illuminate\Encryption\Encrypter;
// 1. Backup database first!
// 2. Create encrypter with old key
$oldEncrypter = new Encrypter(
base64_decode(substr('base64:OLD_KEY', 7)),
config('app.cipher')
);
// 3. Decrypt and re-encrypt each encrypted field
$users = DB::table('users')->select('id', 'encrypted_field')->get();
foreach ($users as $user) {
$decrypted = $oldEncrypter->decrypt($user->encrypted_field);
$reencrypted = Crypt::encrypt($decrypted); // Uses new key from config
DB::table('users')
->where('id', $user->id)
->update(['encrypted_field' => $reencrypted]);
}5. Validate Key Format
Ensure your key matches Laravel's expected format:
php
// Valid formats:
// Base64-encoded (recommended - generated by key:generate)
APP_KEY=base64:/AvmHMmBChdiKxwxReS4zWfHKXAfl0vsbJIf2fT3gHA=
// Raw 32-character string (legacy, not recommended)
APP_KEY=SomeRandomStringWith32Characters!
// The base64 format should decode to at least 16 bytes (AES-128)
// or 32 bytes (AES-256)6. Production Deployment Checklist
bash
# Before deploying to production:
# 1. Verify APP_KEY is set
php artisan tinker
>>> config('app.key')
// Should output a key, not null
# 2. Verify key length
>>> strlen(base64_decode(substr(config('app.key'), 7)))
// Should be 16 (AES-128) or 32 (AES-256)
# 3. Test encryption/decryption
>>> encrypt('test')
>>> decrypt(encrypt('test'))
// Should return 'test'
# 4. Check cache status
>>> app()->configurationIsCached()
// Should be true in production
# 5. If cached, verify cached key matches .env
cat bootstrap/cache/config.php | grep 'key'ShieldCI Configuration
This analyzer is automatically skipped in CI environments ($runInCI = false).
Why skip in CI?
- CI environments typically use test/placeholder keys for running tests
- Real production keys should never be in the repository or CI environment
- Prevents false failures in CI pipelines where placeholder keys are expected
When to run this analyzer:
- ✅ Local development: Ensures developers have proper keys configured
- ✅ Staging/Production servers: Validates environment-specific keys are secure
- ❌ CI/CD pipelines: Skipped automatically (test keys are expected)
References
- Laravel Encryption Documentation
- Laravel Configuration Documentation
- Artisan key:generate Command
- OWASP Cryptographic Storage Cheat Sheet
Related Analyzers
- Environment File Analyzer - Checks .env file permissions and .gitignore
- Configuration Caching Analyzer - Ensures config is cached in production
- Debug Mode Analyzer - Validates debug mode is disabled in production
- Session Driver Configuration Analyzer - Validates session driver for scalability