Security - v2.0.2
Troubleshooting Guide
Solutions to common issues when using the ArtisanPack Security package.
Table of Contents
- Installation Issues
- Authentication Issues
- Two-Factor Authentication Issues
- Session Issues
- API Token Issues
- RBAC Issues
- CSP Issues
- File Upload Issues
- Performance Issues
- Migration Issues
Installation Issues
Package not found
Problem: Package artisanpackui/security not found
Solution:
- Check your
composer.jsonhas the correct repository configured - Clear composer cache:
composer clear-cache
composer update
- Verify you have access to the package repository
Configuration not published
Problem: Config file not found at config/artisanpack/security.php
Solution:
php artisan vendor:publish --provider="ArtisanPackUI\Security\SecurityServiceProvider" --tag="config"
If already published but missing, check:
php artisan vendor:publish --provider="ArtisanPackUI\Security\SecurityServiceProvider" --tag="config" --force
Migrations fail
Problem: Migration errors when running php artisan migrate
Solution:
- Check for table conflicts:
php artisan migrate:status
- If tables already exist, you may need to:
# Reset and re-run (DEVELOPMENT ONLY)
php artisan migrate:fresh
# Or publish migrations to customize
php artisan vendor:publish --provider="ArtisanPackUI\Security\SecurityServiceProvider" --tag="migrations"
- Check database connection and permissions
Authentication Issues
Login always fails
Problem: Valid credentials are rejected
Possible Causes & Solutions:
- Password hashing mismatch:
// Verify password hash
$user = User::where('email', 'test@example.com')->first();
var_dump(Hash::check('password', $user->password));
- Account is locked:
php artisan user:unlock test@example.com
- Rate limiting:
// Clear rate limiting
RateLimiter::clear('login:' . request()->ip());
- Missing authentication guard:
Check config/auth.php has correct guard configuration.
"Account locked" message
Problem: User sees account locked message but shouldn't be locked
Solution:
- Check lockout status:
php artisan security:check-user user@example.com
- Manually unlock:
php artisan user:unlock user@example.com
- Verify lockout configuration:
// config/artisanpack/security.php
'lockout' => [
'threshold' => 5, // Increase if too sensitive
'duration_minutes' => 30,
],
Social login redirect fails
Problem: OAuth redirect returns error
Solutions:
- Verify callback URL matches provider configuration:
# .env
GOOGLE_CALLBACK_URL=https://yourapp.com/auth/google/callback
- Check provider credentials:
php artisan tinker
>>> config('services.google')
-
Ensure HTTPS in production (required by most providers)
-
Clear config cache:
php artisan config:clear
SSO/SAML issues
Problem: SAML authentication fails
Solutions:
- Verify certificates are correct:
# Check certificate validity
openssl x509 -in /path/to/cert.pem -text -noout
-
Check SAML metadata matches IDP configuration
-
Enable SAML debugging:
'saml' => [
'debug' => true,
],
- Verify clock sync between SP and IDP
Two-Factor Authentication Issues
QR code not displaying
Problem: 2FA setup shows broken image
Solutions:
- Install required library:
composer require bacon/bacon-qr-code
- Check GD or Imagick extension is enabled:
php -m | grep -E 'gd|imagick'
- Verify the route returns correct content type
TOTP codes not accepted
Problem: Valid TOTP codes are rejected
Solutions:
- Server time sync:
# Check server time
date
# Sync with NTP
sudo ntpdate -s time.nist.gov
- Increase time window:
'totp' => [
'window' => 2, // Allow codes from adjacent periods
],
- Check secret key:
// Verify stored secret
$user->two_factor_secret // Should be base32 encoded
Recovery codes exhausted
Problem: User has no recovery codes left
Solution:
# Regenerate recovery codes
php artisan 2fa:regenerate-recovery user@example.com --show
Or programmatically:
use ArtisanPackUI\Security\Facades\TwoFactor;
$codes = TwoFactor::regenerateRecoveryCodes($user);
2FA enforced unexpectedly
Problem: Users required to set up 2FA when they shouldn't be
Solution:
Check enforcement configuration:
'enforcement' => [
'mode' => 'optional', // Not 'required'
'required_roles' => ['admin'], // Check user's role
],
Session Issues
Sessions expiring too quickly
Problem: Users logged out unexpectedly
Solutions:
- Check session configuration:
// config/session.php
'lifetime' => 120, // Minutes
// config/artisanpack/security.php
'timeouts' => [
'idle_minutes' => 30,
'absolute_minutes' => 480,
'extend_on_activity' => true,
],
-
Ensure AJAX requests include session cookies
-
Check session driver:
SESSION_DRIVER=database # More reliable than file
Session binding violations
Problem: Legitimate users getting logged out with "Session invalid" errors
Solutions:
- Mobile users with changing IPs:
'binding' => [
'ip_address' => [
'strictness' => 'none', // Or 'subnet'
],
],
- Users behind load balancers:
Ensure X-Forwarded-For header is trusted:
// In TrustProxies middleware
protected $proxies = '*';
- Browser updates changing user agent:
'user_agent' => [
'strictness' => 'browser_only', // Not 'exact'
],
Too many sessions terminated
Problem: Users constantly logging out other devices
Solution:
Increase concurrent session limit:
'concurrent_sessions' => [
'max_sessions' => 10, // Increase from default
],
API Token Issues
Token not authenticating
Problem: API requests return 401 Unauthorized
Solutions:
- Verify token format in header:
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" https://api.example.com/user
- Check token hasn't expired:
$token = PersonalAccessToken::findToken('your-token');
$token->expires_at; // Check expiration
- Verify token abilities match route requirements:
Route::middleware('token.ability:read')->get('/posts', ...);
Token abilities not working
Problem: Token can access routes it shouldn't
Solutions:
- Ensure middleware is applied:
Route::middleware(['auth:sanctum', 'token.ability:write'])->...
- Check token was created with correct abilities:
$token = $user->createApiToken('name', ['read']); // Only read ability
RBAC Issues
Permissions not updating
Problem: User has new role but old permissions
Solution:
Clear the RBAC cache:
php artisan security:clear-cache --roles
Or programmatically:
use ArtisanPackUI\Security\Facades\RBAC;
RBAC::clearCache();
hasPermission always returns false
Problem: $user->hasPermission('something') always returns false
Solutions:
- Verify permission exists:
php artisan permission:list
- Check permission is assigned to role:
php artisan role:list --with-permissions
- Verify user has the role:
$user->roles->pluck('name');
- Check permission name spelling (case-sensitive)
Super admin not bypassing permissions
Problem: Super admin still denied access
Solution:
Verify super admin role is configured:
'rbac' => [
'super_admin_role' => 'super-admin', // Check this matches
],
And user has this exact role:
$user->hasRole('super-admin'); // Must match exactly
CSP Issues
Scripts/styles blocked
Problem: Console shows CSP violations, functionality broken
Solutions:
- Add nonce to inline scripts:
<script nonce="{{ cspNonce() }}">
// Your code
</script>
- Add external domains to CSP:
'directives' => [
'script-src' => ["'self'", "'nonce'", 'https://cdn.example.com'],
],
- Use report-only mode to debug:
'csp' => [
'report_only' => true,
],
CSP breaking third-party widgets
Problem: Google Analytics, Stripe, etc. not working
Solution:
Add required sources. See CSP Framework Guide for common configurations.
Example for Google Analytics:
'script-src' => [
"'self'", "'nonce'",
'https://www.google-analytics.com',
'https://www.googletagmanager.com',
],
Livewire not working with CSP
Problem: Livewire components fail with CSP enabled
Solution:
Ensure nonces are applied to Livewire scripts:
// Livewire v3 handles this automatically with nonces
// For v2, you may need:
'script-src' => ["'self'", "'nonce'", "'unsafe-eval'"], // unsafe-eval for Alpine
File Upload Issues
All uploads rejected
Problem: Every file upload fails validation
Solutions:
- Check allowed MIME types:
'allowedMimeTypes' => [
'image/jpeg', 'image/png', // Ensure your types are here
],
- Check file size limits:
'maxFileSize' => 10 * 1024 * 1024, // 10MB
- Also check PHP limits:
; php.ini
upload_max_filesize = 10M
post_max_size = 10M
False positive malware detection
Problem: Clean files flagged as malware
Solutions:
- Check scanner configuration
- Use async scanning with manual review:
'malwareScanning' => [
'async' => true,
'quarantinePath' => storage_path('app/quarantine'),
],
- Review and release from quarantine:
php artisan files:scan-quarantine --list
php artisan files:scan-quarantine --release=file_id
Signed URLs not working
Problem: File download URLs return 403
Solutions:
- Check URL hasn't expired:
'serving' => [
'signedUrlExpiration' => 60, // Increase if needed
],
-
Verify route is configured correctly
-
Check file exists in storage
Performance Issues
Slow page loads
Problem: Pages load slowly after adding security middleware
Solutions:
- Enable caching:
'rbac' => [
'cache' => true,
'cache_ttl' => 3600,
],
- Reduce logging verbosity:
'logging' => [
'events' => [
'authentication' => true,
'authorization' => false, // Disable verbose logging
],
],
- Use async scanning for files:
'malwareScanning' => [
'async' => true,
],
High memory usage
Problem: Memory exhaustion with security features
Solutions:
- Reduce metrics retention:
'metrics' => [
'retention_days' => 30, // Reduce from 90
],
- Run cleanup regularly:
php artisan security:metrics-cleanup --days=30
php artisan compliance:cleanup
- Use Redis for sessions/cache:
SESSION_DRIVER=redis
CACHE_DRIVER=redis
Migration Issues
Upgrading from older version
Problem: Errors after package upgrade
Solutions:
- Clear all caches:
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan security:clear-cache --all
- Run new migrations:
php artisan migrate
- Re-publish configuration (backup first):
cp config/artisanpack/security.php config/artisanpack/security.php.bak
php artisan vendor:publish --tag="config" --force
- Merge your customizations back into new config
Debugging Tips
Enable debug mode
For development only:
// config/artisanpack/security.php
'debug' => env('SECURITY_DEBUG', false),
SECURITY_DEBUG=true
Check logs
tail -f storage/logs/security.log
Run diagnostics
php artisan security:check-config
php artisan security:audit --check=config
Test in isolation
// Temporarily disable middleware
Route::withoutMiddleware(['csp', 'security.headers'])->group(...);
Getting Help
If you can't resolve an issue:
- Check the FAQ
- Search existing issues on GitHub
- Create a new issue with:
- Laravel version
- Package version
- PHP version
- Steps to reproduce
- Error messages/logs