7.8 KiB
NextAuth Session Duration: 30 Days vs 4 Hours - Security Analysis
Current Configuration
Current Setting (app/api/auth/options.ts:190):
session: {
strategy: "jwt",
maxAge: 30 * 24 * 60 * 60, // 30 days (2,592,000 seconds)
}
Proposed Setting:
session: {
strategy: "jwt",
maxAge: 4 * 60 * 60, // 4 hours (14,400 seconds)
}
Security Analysis
✅ Why 4 Hours is Better for Security
-
Reduced Attack Window:
- 30 days: If session is compromised, attacker has 30 days of access
- 4 hours: If session is compromised, attacker has maximum 4 hours of access
- Risk Reduction: 99.4% reduction in maximum exposure time
-
Industry Best Practices:
- NIST Guidelines: Recommend session timeouts of 2-8 hours for high-security applications
- OWASP: Recommends session timeouts based on risk level (typically 2-8 hours)
- Common Practice: Most enterprise applications use 4-8 hour sessions
-
Device Security:
- 30 days: Device left unattended = 30 days of potential unauthorized access
- 4 hours: Device left unattended = maximum 4 hours of potential access
- Better for: Shared devices, public computers, unattended workstations
-
Compliance:
- Many security standards (ISO 27001, SOC 2) require reasonable session timeouts
- 30 days is often considered too long for compliance
- 4 hours aligns better with security compliance requirements
-
Stolen Session Cookie:
- If session cookie is stolen (XSS, MITM), shorter duration limits damage
- 4 hours gives attacker limited time to exploit
- 30 days gives attacker extensive time to exploit
⚠️ Considerations & Trade-offs
-
User Experience Impact:
- 30 days: Users rarely need to re-authenticate (convenient)
- 4 hours: Users need to re-authenticate every 4 hours (less convenient)
- Impact: Moderate - users will need to log in more frequently
-
Token Refresh Behavior:
- Good News: Your code already handles token refresh automatically
- How it works:
- When NextAuth session expires (4 hours), JWT callback runs
- If
accessTokenis expired, it callsrefreshAccessToken() - Uses
refreshTokento get new tokens from Keycloak - Session is automatically renewed (if refresh token is still valid)
- Result: Users may not notice the 4-hour expiration if they're active
-
Keycloak Refresh Token Lifetime:
- Important: Keycloak refresh tokens typically last 7-30 days
- What this means:
- NextAuth session expires after 4 hours
- But refresh token is still valid (e.g., 7 days)
- NextAuth automatically refreshes tokens
- User stays logged in seamlessly (if active)
- Only expires if: User is inactive for longer than refresh token lifetime
-
Keycloak Session Alignment:
- Current Issue: Keycloak sessions typically expire in 30 minutes to a few hours
- With 4-hour NextAuth session:
- Better alignment with Keycloak session timeouts
- Reduces session mismatch issues
- Iframe applications will have more consistent session state
How It Will Work
Session Lifecycle with 4-Hour maxAge
User logs in
↓
NextAuth creates JWT session (expires in 4 hours)
↓
User is active for 2 hours
↓
User makes request → NextAuth checks session
↓
Session still valid (< 4 hours) → Continue
↓
User is active for 3 hours
↓
User makes request → NextAuth checks session
↓
Session still valid (< 4 hours) → Continue
↓
User is active for 4.5 hours (session expired)
↓
User makes request → NextAuth checks session
↓
Session expired → JWT callback runs
↓
Checks accessToken expiration
↓
If accessToken expired → Calls refreshAccessToken()
↓
Uses refreshToken to get new tokens from Keycloak
↓
If refreshToken still valid → New session created (another 4 hours)
↓
User continues seamlessly (no re-authentication needed)
↓
If refreshToken expired → User must re-authenticate
When User Must Re-authenticate
User must re-authenticate if:
- Inactive for longer than refresh token lifetime (typically 7-30 days)
- Refresh token is revoked (logout, admin action, security event)
- Keycloak session is invalidated (logout from another application)
User does NOT need to re-authenticate if:
- Active within refresh token lifetime (automatic token refresh)
- Session expires but refresh token is valid (automatic renewal)
Recommendations
✅ Recommendation: Implement 4-Hour Session
Reasons:
- ✅ Significantly better security (99.4% reduction in exposure window)
- ✅ Aligns with industry best practices (NIST, OWASP)
- ✅ Better compliance (meets security standards)
- ✅ Better alignment with Keycloak sessions
- ✅ Minimal UX impact (automatic token refresh handles renewal)
- ✅ Code already supports it (token refresh mechanism exists)
⚠️ Important Considerations
-
Verify Keycloak Refresh Token Lifetime:
- Check Keycloak configuration for refresh token lifetime
- Ensure it's longer than 4 hours (typically 7-30 days)
- If shorter, users will need to re-authenticate frequently
-
Monitor User Experience:
- Track how often users need to re-authenticate
- If too frequent, consider increasing to 6-8 hours
- Balance security with usability
-
Consider Activity-Based Extension:
- Current implementation: Fixed 4-hour expiration
- Alternative: Extend session on activity (sliding window)
- Requires additional implementation (activity tracking)
-
Keycloak Session Configuration:
- Consider aligning Keycloak SSO session timeout with NextAuth
- Or ensure Keycloak session is longer than NextAuth session
- Prevents session mismatch issues
📋 Implementation Checklist
Before implementing:
- Verify Keycloak refresh token lifetime (should be > 4 hours)
- Test token refresh flow with 4-hour session
- Monitor user re-authentication frequency
- Consider user feedback on session duration
- Document the change for users (if needed)
- Update security documentation
Comparison Table
| Aspect | 30 Days | 4 Hours | Winner |
|---|---|---|---|
| Security | Low (long exposure window) | High (short exposure window) | ✅ 4 Hours |
| User Convenience | High (rare re-authentication) | Medium (automatic refresh) | ✅ 30 Days |
| Compliance | Poor (too long) | Good (meets standards) | ✅ 4 Hours |
| Risk Reduction | Low | High (99.4% reduction) | ✅ 4 Hours |
| Keycloak Alignment | Poor (mismatch) | Good (better alignment) | ✅ 4 Hours |
| Token Refresh | Works | Works (same mechanism) | ✅ Tie |
Conclusion
Recommendation: Change to 4 hours
Why:
- Significantly better security posture
- Aligns with industry best practices
- Better compliance with security standards
- Minimal UX impact (automatic token refresh)
- Better alignment with Keycloak session timeouts
- Code already supports it
Implementation:
- Simple change:
maxAge: 4 * 60 * 60 - No code changes needed (token refresh already works)
- Monitor user experience and adjust if needed
Alternative Consideration:
- If 4 hours is too aggressive, consider 6-8 hours as a middle ground
- Still provides significant security improvement over 30 days
- Better user experience than 4 hours
Final Verdict
✅ Yes, change to 4 hours - This is a good security practice that:
- Significantly reduces security risk
- Aligns with industry standards
- Has minimal UX impact (automatic refresh)
- Works with existing code
- Better aligns with Keycloak sessions
The only trade-off is slightly more frequent re-authentication for inactive users, but this is a reasonable security trade-off.