NeahNew/SESSION_DURATION_SECURITY_ANALYSIS.md

234 lines
7.8 KiB
Markdown

# NextAuth Session Duration: 30 Days vs 4 Hours - Security Analysis
## Current Configuration
**Current Setting** (`app/api/auth/options.ts:190`):
```typescript
session: {
strategy: "jwt",
maxAge: 30 * 24 * 60 * 60, // 30 days (2,592,000 seconds)
}
```
**Proposed Setting**:
```typescript
session: {
strategy: "jwt",
maxAge: 4 * 60 * 60, // 4 hours (14,400 seconds)
}
```
---
## Security Analysis
### ✅ **Why 4 Hours is Better for Security**
1. **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
2. **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
3. **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
4. **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
5. **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**
1. **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
2. **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 `accessToken` is expired, it calls `refreshAccessToken()`
- Uses `refreshToken` to 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
3. **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
4. **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**:
1. **Inactive for longer than refresh token lifetime** (typically 7-30 days)
2. **Refresh token is revoked** (logout, admin action, security event)
3. **Keycloak session is invalidated** (logout from another application)
**User does NOT need to re-authenticate if**:
1. **Active within refresh token lifetime** (automatic token refresh)
2. **Session expires but refresh token is valid** (automatic renewal)
---
## Recommendations
### ✅ **Recommendation: Implement 4-Hour Session**
**Reasons**:
1.**Significantly better security** (99.4% reduction in exposure window)
2.**Aligns with industry best practices** (NIST, OWASP)
3.**Better compliance** (meets security standards)
4.**Better alignment with Keycloak sessions**
5.**Minimal UX impact** (automatic token refresh handles renewal)
6.**Code already supports it** (token refresh mechanism exists)
### ⚠️ **Important Considerations**
1. **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
2. **Monitor User Experience**:
- Track how often users need to re-authenticate
- If too frequent, consider increasing to 6-8 hours
- Balance security with usability
3. **Consider Activity-Based Extension**:
- Current implementation: Fixed 4-hour expiration
- Alternative: Extend session on activity (sliding window)
- Requires additional implementation (activity tracking)
4. **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.