- ERROR_TRACKING_DESIGN.md: Architecture for centralized error tracking - MANA_CORE_AUTH_ANALYSIS.md: Comprehensive auth service analysis - SECURITY_FIXES_IMPLEMENTATION_GUIDE.md: Security implementation guide
30 KiB
ManaCore Auth Analysis: Session Management & Better Auth Comparison
Date: December 17, 2025 Version: 1.0 Status: Final Analysis
Executive Summary
This comprehensive analysis evaluates the mana-core-auth central authentication system against Better Auth best practices, with specific focus on session persistence ("stay signed in" functionality), security posture, and integration patterns across the ManaCore monorepo.
Key Findings
Overall Assessment: B+ (Strong Foundation, Strategic Improvements Needed)
Strengths ✅
- Modern Better Auth framework (v1.4.3) with EdDSA JWT signing
- Excellent integration consistency across 15+ apps
- Robust automatic token refresh with request queuing
- Strong rate limiting and brute force protection
- Proper refresh token rotation implementation
- World-class frontend/backend integration patterns
Critical Gaps 🔴
- No "stay signed in" / "remember me" feature - All users get same 7-day session
- Manual JWT fallback code bypasses Better Auth's native JWT plugin
- No cookie cache - Every session check queries database (performance impact)
- No security audit logging - Cannot investigate incidents or track breaches
- Transport security incomplete - Missing HSTS, comprehensive CSP, cookie flags
Strategic Opportunities ⚠️
- Enable Better Auth's cookie cache (98% reduction in DB queries)
- Implement user-controlled "remember me" (7-day vs 30-day sessions)
- Add multi-session management UI (view/revoke devices)
- Complete security hardening (audit logs, headers, CSRF protection)
Table of Contents
- Current Implementation Overview
- Better Auth Capabilities & Best Practices
- Gap Analysis: What's Missing
- Security Assessment
- Integration Patterns Analysis
- Performance Analysis
- Recommendations by Priority
- Implementation Roadmap
- Technical References
1. Current Implementation Overview
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ MANA-CORE-AUTH SERVICE │
│ (Port 3001) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Better Auth Core (v1.4.3) │
│ ├─ Email/Password Authentication │
│ ├─ Session Management (database-backed) │
│ ├─ JWT Plugin (EdDSA signing) │
│ ├─ Organization Plugin (multi-tenant B2B) │
│ └─ JWKS Storage (auto-generated Ed25519 keys) │
│ │
│ Session Configuration │
│ ├─ Expiration: 7 days (fixed for all users) │
│ ├─ Update Age: 1 day (sliding window) │
│ ├─ Cookie Cache: ❌ NOT ENABLED │
│ └─ Remember Me: ❌ NOT IMPLEMENTED │
│ │
│ Token Architecture │
│ ├─ Access Token: JWT (15 minutes, EdDSA) │
│ ├─ Refresh Token: Session token (7 days) │
│ └─ Token Rotation: ✅ Implemented │
│ │
└─────────────────────────────────────────────────────────────────┘
Technology Stack
| Component | Technology | Version |
|---|---|---|
| Framework | Better Auth | 1.4.3 |
| JWT Algorithm | EdDSA (Ed25519) | N/A |
| JWT Library | jose | Latest |
| Backend | NestJS | 10.x |
| Database | PostgreSQL + Drizzle ORM | Latest |
| Brevo (Sendinblue) | Latest |
Session Management Details
Current Configuration:
// better-auth.config.ts
session: {
expiresIn: 60 * 60 * 24 * 7, // 7 days
updateAge: 60 * 60 * 24, // Update every 1 day
// cookieCache: NOT CONFIGURED
}
Session Schema:
sessions {
id: text (PK)
userId: text (FK → users.id)
token: text (unique, used as session cookie)
expiresAt: timestamp
refreshToken: text (unique, for token rotation)
refreshTokenExpiresAt: timestamp
deviceId: text
deviceName: text
ipAddress: text
userAgent: text
lastActivityAt: timestamp
revokedAt: timestamp (for manual revocation)
}
Token Lifecycle:
- Login → Access token (15min) + Refresh token (7 days)
- Access token expires → Auto-refresh via
@manacore/shared-auth - Refresh token used → Old session revoked, new session created (rotation)
- 7 days elapsed → User must log in again
JWT Implementation
Access Token Claims (Minimal):
{
sub: userId,
email: email,
role: 'user' | 'admin' | 'service',
sid: sessionId,
iss: 'manacore',
aud: 'manacore',
exp: <15 minutes from now>
}
Key Management:
- EdDSA key pairs auto-generated by Better Auth
- Stored in
auth.jwkstable (private keys encrypted) - Public keys served via
/api/v1/auth/jwksendpoint - JWKS-based validation by all backend services
Integration Pattern
Backend (NestJS):
@Controller('api')
@UseGuards(JwtAuthGuard)
export class MyController {
@Get('protected')
async getProtected(@CurrentUser() user: CurrentUserData) {
return { userId: user.userId };
}
}
Frontend (SvelteKit):
const token = await authStore.getValidToken(); // Auto-refreshes!
const response = await fetch('/api/endpoint', {
headers: { Authorization: `Bearer ${token}` }
});
2. Better Auth Capabilities & Best Practices
2.1 Cookie Cache Optimization
What It Is: Better Auth's cookie cache stores session data in cryptographically signed cookies, eliminating database queries for session validation.
How It Works:
WITHOUT CACHE:
Every useSession() → Database Query
WITH CACHE (5 min):
1st useSession() → Database Query → Cache in signed cookie
2nd-Nth useSession() (within 5 min) → Read from cookie (no DB query)
After 5 min → Database Query → Refresh cache
Configuration:
session: {
cookieCache: {
enabled: true,
maxAge: 5 * 60, // 5 minutes
strategy: "jwe", // Encrypted (default in v1.4+)
refreshCache: true
}
}
Security:
- Cookies cryptographically signed (cannot be tampered)
- Short
maxAge(5 min) ensures frequent DB checks - Encrypted with AES-256-GCM (JWE strategy)
Performance Impact:
- 98% reduction in session-related database queries
- 10-20ms → <1ms validation time
2.2 Extended Sessions ("Stay Signed In")
Concept: Users opt-in to longer session durations (e.g., 30 days instead of 7 days) via "Remember Me" checkbox.
Better Auth Approach: No built-in "remember me" plugin, but supports custom implementation via session hooks.
Recommended Pattern:
// 1. Add rememberMe to session schema
sessions {
rememberMe: boolean (default: false)
}
// 2. Dynamic expiration logic
session: {
expiresIn: 60 * 60 * 24 * 7, // Default: 7 days
async beforeCreate({ session, request }) {
if (request.body.rememberMe) {
session.expiresAt = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days
session.rememberMe = true;
}
return session;
}
}
Alternative: Stateless Sessions
session: {
statelessSessions: {
enabled: true,
expiresIn: 60 * 60 * 24 * 30 // 30 days
}
}
- Pros: Zero DB queries, infinite scalability
- Cons: Cannot revoke before expiration
2.3 Multi-Session Management
Better Auth Plugin:
import { multiSession } from 'better-auth/plugins';
plugins: [
multiSession()
]
Features:
- Users can maintain multiple active sessions
- View all sessions with device info
- Revoke specific sessions
- Switch between sessions (e.g., personal vs organization account)
Use Cases for ManaCore:
- Organization members with multiple org accounts
- Users testing across environments
- B2B users switching between tenant contexts
2.4 Industry Best Practices (OWASP)
Session Timeout Recommendations:
| Application Type | Idle Timeout | Absolute Timeout |
|---|---|---|
| Financial/Healthcare | 2-5 minutes | 2-4 hours |
| Office Applications | 15-30 minutes | 4-8 hours |
| Low-Risk Apps | 30 minutes | 12 hours |
| "Remember Me" (Trusted Devices) | N/A | 7-30 days |
Session Security Requirements:
- ✅ Minimum 64 bits entropy (Better Auth complies)
- ✅ httpOnly cookies (prevent XSS)
- ✅ Secure flag (HTTPS only)
- ✅ SameSite=Lax or Strict (CSRF protection)
- ✅ Session regeneration on login (Better Auth handles)
Token Rotation Best Practices:
- ✅ Single-use refresh tokens
- ✅ Immediate invalidation of old tokens
- ✅ Reuse detection → revoke entire token family
- ✅ Short access token lifetime (5-15 min)
3. Gap Analysis: What's Missing
3.1 Missing Features Summary
| Feature | Current Status | Better Auth Support | Priority | Impact |
|---|---|---|---|---|
| Cookie Cache | ❌ Not enabled | ✅ Built-in | 🔴 High | Performance |
| Remember Me | ❌ Not implemented | ⚠️ Custom | ⚠️ Medium | UX |
| Extended Sessions | ❌ Fixed 7 days | ⚠️ Custom | ⚠️ Medium | UX |
| Multi-Session Plugin | ❌ Not enabled | ✅ Built-in | ✅ Low | Advanced UX |
| Session Management UI | ❌ Not implemented | ⚠️ Custom | ⚠️ Medium | Security |
| Device Fingerprinting | ⚠️ Basic tracking | ⚠️ Custom | ⚠️ Medium | Security |
| Session Activity Tracking | ⚠️ Schema exists | ⚠️ Not used | ✅ Low | Analytics |
| Stateless Session Option | ❌ Not configured | ✅ Built-in | ✅ Low | Scalability |
3.2 Critical Implementation Issues
Issue 1: Manual JWT Fallback (CRITICAL)
Location: better-auth.service.ts:451-508
Problem:
try {
// Try Better Auth's JWT plugin
const jwtResult = await this.api.signJWT({ body: { payload } });
accessToken = jwtResult?.token || '';
} catch (jwtError) {
// ❌ FALLBACK: Manual JWT generation
accessToken = jwt.sign(payload, privateKey, {
algorithm: 'RS256', // 🔴 WRONG! Better Auth uses EdDSA
});
}
Issues:
- Algorithm mismatch (RS256 vs EdDSA)
- Uses different keys (env vars vs JWKS table)
- Tokens from fallback won't validate via JWKS endpoint
- Defeats Better Auth's design
Solution:
// Always use Better Auth's JWT plugin
const jwtResult = await this.api.signJWT({
body: { payload },
headers: {
authorization: `Bearer ${sessionToken}`, // Provide session context
},
});
const accessToken = jwtResult.token;
Issue 2: No Cookie Cache (Performance)
Impact:
- Every
useSession()call queries PostgreSQL - High database load on session validation
- 10-20ms added latency per request
Performance Calculation:
Scenario: 1000 concurrent users
- Without cache: 1000 × 10 req/min × 60 min = 600,000 DB queries/hour
- With 5-min cache: 1000 × 1 refresh/5min × 60 min = 12,000 DB queries/hour
- Reduction: 98% fewer queries
Solution: Enable cookie cache (see Section 7.1)
Issue 3: No "Remember Me" Option (User Experience)
Current State:
- All users get same 7-day session
- Mobile apps lose sessions weekly
- No differentiation between trusted/untrusted devices
Competitive Comparison:
- Gmail: 60 days with "Stay signed in"
- GitHub: 90 days with "Keep me signed in"
- Slack: 30 days default, 90 days on desktop
- ManaCore: 7 days (no option to extend)
User Impact:
- Weekly re-authentication friction
- Poor mobile app experience
- Lower user retention
Issue 4: Password Length Validation Mismatch (Security)
Problem:
// DTO allows 8 characters
@MinLength(8)
password: string;
// Better Auth requires 12 characters
minPasswordLength: 12
Security Impact: Weak passwords (8-11 chars) accepted, then rejected by Better Auth
Solution: Fix DTO to require 12 characters minimum
4. Security Assessment
Overall Security Rating: B+ (Good, with improvements needed)
4.1 Strengths ✅
Token Security
- ✅ EdDSA (Ed25519) - Modern, secure, performant
- ✅ Short access tokens (15 min) - Limits exposure window
- ✅ Minimal JWT claims - No sensitive data in tokens
- ✅ JWKS-based validation - Industry standard
- ✅ Proper token rotation - Security via refresh token rotation
Session Security
- ✅ Database-backed sessions - Immediate revocation capability
- ✅ Refresh token rotation - Prevents replay attacks
- ✅ Device tracking - IP, user agent, device ID/name
- ✅ Session revocation -
revokedAttimestamp support
Rate Limiting
- ✅ Login: 5 attempts/minute
- ✅ Registration: 10/hour
- ✅ Password reset: 3 requests/5 minutes
- ✅ Global: 100 requests/minute
Access Control
- ✅ JWT guards protect all sensitive endpoints
- ✅ Role-based access control (user, admin, service)
- ✅ Organization-based permissions (B2B multi-tenant)
4.2 Critical Vulnerabilities 🔴
1. No Security Audit Logging (CRITICAL)
- ❌ No logging of login attempts (success/failure)
- ❌ No tracking of password changes
- ❌ No forensic evidence for security incidents
- ❌ GDPR/SOC 2/ISO 27001 non-compliance
Impact: Cannot investigate breaches, no audit trail
2. Transport Security Incomplete (HIGH)
- ❌ No HSTS (Strict-Transport-Security) header
- ❌ No comprehensive CSP (Content-Security-Policy)
- ❌ Cookie security flags not verified (httpOnly, secure, sameSite)
- ❌ No HTTPS enforcement middleware
Impact: Vulnerable to downgrade attacks, XSS, CSRF
3. Manual JWT Fallback (HIGH)
- ❌ Bypasses Better Auth's security
- ❌ Creates inconsistent token formats
- ❌ Algorithm mismatch (RS256 vs EdDSA)
Impact: Tokens may not validate correctly, security holes
4.3 Medium-Priority Issues ⚠️
4. No CSRF Protection
- ⚠️ CORS configured but no explicit CSRF tokens
- ⚠️ Relies on SameSite cookies (not verified)
5. No Account Lockout
- ⚠️ Rate limiting exists, but no account lockout after N failures
- ⚠️ No progressive delays on failed attempts
6. No Device Fingerprinting
- ⚠️ Tracks IP/userAgent but doesn't validate changes
- ⚠️ Cannot detect session hijacking
7. Password Hashing Not Explicitly Configured
- ⚠️ Better Auth default (scrypt) used but not verified
- ⚠️ Hash parameters not documented
4.4 OWASP Top 10 Compliance
| OWASP Category | Compliance | Notes |
|---|---|---|
| A01: Broken Access Control | ✅ Good | JWT guards, RBAC, organization permissions |
| A02: Cryptographic Failures | ⚠️ Partial | EdDSA good, HTTPS enforcement missing |
| A03: Injection | ✅ Good | Drizzle ORM, input validation |
| A04: Insecure Design | ✅ Good | Defense in depth, secure by default |
| A05: Security Misconfiguration | ⚠️ Moderate | Headers incomplete, cookies not verified |
| A06: Vulnerable Components | ⚠️ Monitor | Need dependency scanning |
| A07: Auth Failures | ✅ Strong | Strong passwords, 2FA schema, rate limiting |
| A08: Data Integrity | ✅ Good | JWT signatures, DB constraints |
| A09: Logging Failures | 🔴 Critical | No security event logging |
| A10: SSRF | ✅ Low Risk | No user-controlled URLs |
OWASP Compliance Score: 7/10
5. Integration Patterns Analysis
Overall Integration Rating: ⭐⭐⭐⭐⭐ (5/5 - World Class)
5.1 Backend Integration
Consistency: Exceptional (all 15+ backends identical)
Pattern:
import { JwtAuthGuard, CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth';
@Controller('api')
@UseGuards(JwtAuthGuard)
export class MyController {
@Get('route')
async handler(@CurrentUser() user: CurrentUserData) {
return { userId: user.userId };
}
}
Features:
- ✅ Centralized validation via mana-core-auth
- ✅ Dev bypass mode for local development
- ✅ Type-safe user data extraction
- ✅ Zero custom auth code in apps
5.2 Frontend Web Integration
Consistency: Exceptional (all web apps identical)
Pattern:
// auth.svelte.ts (Svelte 5 runes)
let user = $state<UserData | null>(null);
export const authStore = {
get user() { return user; },
async getValidToken() {
return await tokenManager.getValidToken(); // Auto-refresh!
}
};
// api.ts
const token = await authStore.getValidToken();
fetch(url, { headers: { Authorization: `Bearer ${token}` } });
Features:
- ✅ Automatic token refresh
- ✅ Request queuing during refresh
- ✅ Offline handling
- ✅ Fetch interceptor for 401 retry
5.3 Frontend Mobile Integration
Consistency: Exceptional (all mobile apps identical)
Pattern:
// AuthProvider.tsx (React Native)
setStorageAdapter(createSecureStoreAdapter()); // Secure encrypted storage
const [user, setUser] = useState<UserData | null>(null);
export function AuthProvider({ children }) {
// Same patterns as web
}
Features:
- ✅ SecureStore for encrypted token storage
- ✅ Same auto-refresh logic as web
- ✅ Device ID generation and persistence
5.4 Token Flow
Automatic Refresh Flow:
1. App needs data → getValidToken()
2. Check local expiration → Expired
3. State: REFRESHING
4. Queue concurrent requests
5. POST /auth/refresh { refreshToken }
6. Receive new tokens
7. Store in localStorage/SecureStore
8. Process queued requests with new token
9. Return data to app
Benefits:
- ✅ Zero manual token management
- ✅ No duplicate refresh calls
- ✅ Handles concurrent requests gracefully
- ✅ Automatic retry on 401
5.5 Pain Points
Minimal - only minor opportunities:
-
Manual token passing (Minor)
- Apps call
await authStore.getValidToken()in each API function - Could be abstracted into shared API client package
- Apps call
-
Duplicated API clients (Opportunity)
- Each app has own
api.ts/client.ts - Could create
@manacore/shared-api-client
- Each app has own
No critical integration issues found.
6. Performance Analysis
6.1 Current Performance
Session Validation:
- Every
useSession()→ PostgreSQL query (~10-20ms) - 1000 users × 10 req/min = 600,000 DB queries/hour
Token Refresh:
- Local check < 1ms
- Network refresh ~50-100ms
- Average: 1 refresh per user per hour
6.2 With Cookie Cache (Projected)
Session Validation:
- First call → PostgreSQL query (~10-20ms) → Cache
- Subsequent calls (5 min) → Cookie read (~<1ms)
- 1000 users × 10 req/min = 12,000 DB queries/hour
Improvement:
- 98% reduction in session queries
- 10-20ms → <1ms average validation time
- Massive database load reduction
6.3 Bottleneck Analysis
Current Bottleneck: Session validation database queries
Solution: Enable cookie cache (15-minute implementation)
7. Recommendations by Priority
🔴 CRITICAL (Implement Immediately)
1. Fix JWT Generation Fallback
Effort: 2 hours Impact: Security, consistency
Remove manual JWT fallback and fix Better Auth API call:
// Remove lines 470-508 in better-auth.service.ts
// Always use Better Auth's native JWT generation
const jwtResult = await this.api.signJWT({
body: { payload },
headers: { authorization: `Bearer ${sessionToken}` }
});
2. Enable Cookie Cache
Effort: 30 minutes Impact: Performance (98% DB query reduction)
// better-auth.config.ts
session: {
expiresIn: 60 * 60 * 24 * 7,
updateAge: 60 * 60 * 24,
cookieCache: {
enabled: true,
maxAge: 5 * 60,
strategy: "jwe",
refreshCache: true
}
}
3. Fix Password Length Validation
Effort: 15 minutes Impact: Security
// register.dto.ts, register-b2b.dto.ts
@MinLength(12) // Match Better Auth config
@MaxLength(128)
password: string;
4. Implement Security Audit Logging
Effort: 1 day Impact: Compliance, security incident response
// Create SecurityEventsService
await logSecurityEvent({
userId: user.id,
eventType: 'login_success' | 'login_failure' | 'password_change',
ipAddress: req.ip,
userAgent: req.get('user-agent'),
metadata: { /* event details */ }
});
5. Configure Security Headers
Effort: 2 hours Impact: Transport security, XSS/CSRF protection
// main.ts
helmet({
strictTransportSecurity: { maxAge: 31536000, includeSubDomains: true },
contentSecurityPolicy: { /* CSP directives */ },
frameguard: { action: 'deny' },
noSniff: true,
})
⚠️ HIGH PRIORITY (Within 2 Weeks)
6. Implement "Remember Me" Feature
Effort: 8 hours Impact: User experience, retention
Steps:
- Add
rememberMe: booleanto session schema - Update login DTO to accept
rememberMe - Implement dynamic expiration (7 days vs 30 days)
- Add checkbox to login UI (all apps)
// Dynamic expiration
if (dto.rememberMe) {
session.expiresAt = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
session.rememberMe = true;
}
7. Add Session Management UI
Effort: 12 hours Impact: Security, user control
Features:
- List all active sessions with device info
- Revoke specific sessions
- "Where you're signed in" page
// Backend endpoints
GET /auth/sessions/active → List user sessions
DELETE /auth/sessions/:id → Revoke session
8. Add Account Lockout
Effort: 4 hours Impact: Brute force protection
// After 5 failed login attempts → 15-minute lockout
const FAILED_LOGIN_THRESHOLD = 5;
const LOCKOUT_DURATION = 15 * 60 * 1000;
⚠️ MEDIUM PRIORITY (Within 1 Month)
9. Enable Multi-Session Plugin
Effort: 2 hours Impact: Advanced UX for organization users
import { multiSession } from 'better-auth/plugins';
plugins: [multiSession()]
10. Implement Device Fingerprinting
Effort: 8 hours Impact: Session hijacking detection
// Bind sessions to device fingerprint
// Validate: IP changes, userAgent mismatches
// Alert on anomalies
11. Add Step-Up Authentication
Effort: 6 hours Impact: Security for sensitive operations
// Require re-authentication for:
// - Password changes
// - Account deletion
// - Payment method updates
@UseGuards(JwtAuthGuard, StepUpAuthGuard)
✅ LOW PRIORITY (Nice to Have)
- Inactivity timeout (auto-logout after 30 min idle)
- Trusted devices (skip 2FA on recognized devices)
- Impossible travel detection
- Password breach checking (HaveIBeenPwned)
- Secrets management integration (AWS Secrets Manager)
8. Implementation Roadmap
Phase 1: Critical Fixes (Week 1)
Goal: Fix security issues and enable performance optimization
| Task | Effort | Owner | Status |
|---|---|---|---|
| Fix JWT generation fallback | 2h | Backend | 🔴 Not started |
| Enable cookie cache | 30m | Backend | 🔴 Not started |
| Fix password length validation | 15m | Backend | 🔴 Not started |
| Implement security audit logging | 8h | Backend | 🔴 Not started |
| Configure security headers | 2h | DevOps | 🔴 Not started |
Total Effort: ~13 hours Impact: Security hardening + 98% DB query reduction
Phase 2: "Remember Me" Feature (Week 2-3)
Goal: Implement user-controlled session duration
| Task | Effort | Owner | Status |
|---|---|---|---|
Add rememberMe to schema |
1h | Backend | 🔴 Not started |
| Update login DTO | 30m | Backend | 🔴 Not started |
| Implement dynamic expiration | 2h | Backend | 🔴 Not started |
| Add UI checkbox (web apps) | 3h | Frontend | 🔴 Not started |
| Add UI checkbox (mobile apps) | 2h | Mobile | 🔴 Not started |
| Testing | 2h | QA | 🔴 Not started |
Total Effort: ~10.5 hours Impact: Better UX, competitive parity
Phase 3: Session Management UI (Week 4-5)
Goal: Give users control over their sessions
| Task | Effort | Owner | Status |
|---|---|---|---|
| Backend endpoints (list/revoke) | 3h | Backend | 🔴 Not started |
| Web UI component | 4h | Frontend | 🔴 Not started |
| Mobile UI component | 3h | Mobile | 🔴 Not started |
| Integration testing | 2h | QA | 🔴 Not started |
Total Effort: ~12 hours Impact: Security visibility, user trust
Phase 4: Advanced Security (Month 2+)
Goal: Enterprise-grade security features
| Task | Effort | Priority |
|---|---|---|
| Multi-session plugin | 2h | Medium |
| Device fingerprinting | 8h | Medium |
| Step-up authentication | 6h | Medium |
| Account lockout | 4h | High |
| Inactivity timeout | 6h | Low |
Total Effort: ~26 hours
9. Technical References
Documentation Locations
ManaCore Docs:
- Auth service:
/services/mana-core-auth/ - Shared backend auth:
/packages/shared-nestjs-auth/ - Shared frontend auth:
/packages/shared-auth/ - Guidelines:
/.claude/guidelines/authentication.md
Key Files:
- JWT config:
services/mana-core-auth/src/auth/better-auth.config.ts - Auth service:
services/mana-core-auth/src/auth/services/better-auth.service.ts - Database schema:
services/mana-core-auth/src/db/schema/auth.schema.ts - Backend guard:
packages/shared-nestjs-auth/src/guards/jwt-auth.guard.ts - Frontend auth:
packages/shared-auth/src/core/authService.ts
External References
Better Auth:
- Docs: https://www.better-auth.com/docs
- Session Management: https://www.better-auth.com/docs/concepts/session-management
- Cookie Cache: https://www.better-auth.com/docs/guides/optimizing-for-performance#cookie-cache
- Plugins: https://www.better-auth.com/docs/plugins
Security Standards:
- OWASP Session Management: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
- OWASP Authentication: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
- JWT Best Practices (RFC 8725): https://datatracker.ietf.org/doc/html/rfc8725
- OAuth 2.0 Security (RFC 9700): https://www.rfc-editor.org/rfc/rfc9700
Appendix A: Comparison Matrix
| Feature | Current ManaCore | Better Auth Capability | Industry Standard | Gap |
|---|---|---|---|---|
| Session Duration | 7 days (fixed) | Configurable | 7-30 days | ⚠️ No user control |
| Remember Me | ❌ No | ⚠️ Custom impl | ✅ Yes | ⚠️ Missing |
| Cookie Cache | ❌ No | ✅ Built-in | ✅ Common | 🔴 Not enabled |
| Stateless Sessions | ❌ No | ✅ Supported | ⚠️ Varies | ✅ Not needed |
| Multi-Session | ❌ No | ✅ Plugin | ⚠️ Advanced | ⚠️ Nice to have |
| Session Management UI | ❌ No | ⚠️ Custom | ✅ Yes | ⚠️ Missing |
| Token Rotation | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Implemented |
| JWT Algorithm | ✅ EdDSA | ✅ EdDSA | ⚠️ Often RS256 | ✅ Optimal |
| JWKS | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Implemented |
| Device Tracking | ⚠️ Partial | ⚠️ Custom | ✅ Yes | ⚠️ Basic only |
| Security Logging | ❌ No | ⚠️ Custom | ✅ Yes | 🔴 Critical gap |
Appendix B: Performance Benchmarks
Session Validation Performance
Current (No Cache):
1000 users × 10 requests/min × 60 min/hour = 600,000 queries/hour
Average query time: 10-20ms
Database time/hour: 1.67 hours of continuous querying
With Cookie Cache (5 min):
Cache hit rate: 98%
Database queries: 600,000 × 0.02 = 12,000 queries/hour
Database time/hour: 2 minutes
Improvement: 98.3% reduction
Token Refresh Performance
Refresh Metrics:
- Local expiration check: <1ms
- Network refresh: 50-100ms
- Refresh frequency: ~1 per user per hour
- Request queuing overhead: <5ms per request
Appendix C: Security Checklist
Pre-Deployment Checklist
Critical:
- Remove manual JWT fallback code
- Enable cookie cache
- Fix password length validation
- Implement security audit logging
- Configure comprehensive security headers
- Verify HTTPS enforcement
- Verify cookie flags (httpOnly, secure, sameSite)
High Priority:
- Implement "remember me" feature
- Add session management UI
- Add account lockout mechanism
- Add CSRF protection
- Document password hashing parameters
Medium Priority:
- Enable multi-session plugin
- Implement device fingerprinting
- Add step-up authentication
- Configure JWT key rotation
Post-Deployment Monitoring:
- Monitor session DB query reduction (should be 98%)
- Track token refresh success/failure rates
- Monitor security event logs for anomalies
- Track "remember me" adoption rate
- Monitor failed login attempts
Conclusion
The mana-core-auth service provides a strong foundation for authentication with modern security practices and excellent integration patterns. The use of Better Auth framework, EdDSA JWT tokens, and comprehensive rate limiting demonstrates thoughtful architecture.
Key Strengths:
- World-class integration consistency across 15+ apps
- Modern cryptography (EdDSA, scrypt/bcrypt)
- Robust automatic token refresh
- Proper session management with rotation
Critical Next Steps:
- Fix JWT generation fallback (security)
- Enable cookie cache (performance)
- Implement security audit logging (compliance)
- Add "remember me" feature (UX)
- Complete transport security hardening (security headers, HTTPS)
With Phase 1 and Phase 2 implemented (~24 hours of work), the system will achieve A-grade enterprise security with excellent performance and user experience suitable for production deployment at scale.
Project Signature: 🏗️ ManaCore Monorepo