Authentication System
CyberCTF uses OpenID Connect (OIDC) for secure authentication across the platform and related applications.
🔐 Authentication Flow
Sign Up Process
Visit /sign-up to create your account:
- Enter email and password
- Email verification (automatic)
- Account creation in the backend
- Auto-login after signup
- Redirect to Dashboard (
/dashboard)
Sign In Process
Visit /sign-in to access your account:
- Enter credentials (email + password)
- OIDC authentication with the auth server
- Token generation (access, refresh, ID tokens)
- Store in HTTP-only cookies for security
- Redirect to Dashboard or callback URL
Token Types
Access Token:
- Short-lived (15-60 minutes)
- Used for API requests
- Automatically included in GraphQL queries
- Refreshed in the background
Refresh Token:
- Long-lived (days/weeks)
- Used to get new access tokens
- Stored securely in HTTP-only cookies
- Device-specific
ID Token:
- Contains user information (email, username)
- JWT format
- Used for user identification
- Decoded client-side for display
🛡️ Security Features
OIDC Standard
CyberCTF follows OpenID Connect specification:
- OAuth 2.0 base: Industry-standard authorization
- JWT tokens: Secure, stateless authentication
- PKCE flow: Additional security for public clients
- Token rotation: Refresh tokens regularly rotated
Cookie Security
Tokens stored in HTTP-only cookies:
- HttpOnly flag: No JavaScript access
- Secure flag: HTTPS only
- SameSite: CSRF protection
- Automatic expiry: Time-limited validity
Session Management
Active Sessions:
- View in Settings (
/settings) - See device and location
- Logout from specific devices
- Logout from all devices
Automatic Logout:
- After token expiration
- After explicit logout
- On security events
- On password change
🌐 Cross-Application Authentication
Supported Applications
CyberCTF Web Platform
- URL: Main website
- Pages: Dashboard, Labs, Leaderboard, Profile, Stats, Settings
- Authentication: Automatic via cookies
- API: GraphQL endpoint at
/api/proxy/graphql
CyberCTF Launcher
- Type: Native desktop application
- Integration: Deep links (
cyberctf://) - Authentication: Shared token system
- Features: Lab management, Docker integration
GraphQL API
- Endpoint:
/api/proxy/graphql - Auth: Bearer token from cookies
- Public access: Some queries (leaderboard)
- Private access: User-specific data
How It Works
When you login:
- Authentication server validates credentials
- Tokens generated (access, refresh, ID)
- Cookies set with secure flags
- All requests include cookies automatically
- GraphQL API validates tokens
- Launcher uses same authentication
🔑 Account Management
Profile Settings (/settings)
Update Username:
mutation UpdateUser($username: String) {
updateUser(username: $username) {
email
username
}
}View Account Info:
query GetUser {
currentUser {
id
email
username
}
}Password Management
Change Password:
- Via OIDC provider
- Secure reset flow
- Email verification required
Forgot Password:
- Click “Forgot Password” on
/sign-in - Enter your email
- Receive reset link
- Create new password
- Login with new credentials
Account Deletion
- Request via Settings
- Data export available
- Permanent removal
- Cannot be undone
🔄 Token Management
Automatic Refresh
The platform handles token refresh automatically:
// Tokens refresh in background
// No user action needed
// Seamless experience
// Triggered before expirationManual Refresh
API endpoint: /api/auth/refresh
// Called automatically by the app
// Can be called manually if needed
// Returns new access token
// Updates cookiesLogout
API endpoint: /api/auth/logout
// Clears all cookies
// Invalidates tokens
// Redirects to home
// Secure cleanup👥 User Data
Current User Query
query GetCurrentUser {
currentUser {
id
email
username
}
}User Statistics
query GetUserStats {
submissionsByUser {
id
challengeId
status
score
submittedAt
}
lessonProgress {
lessonId
completed
progressPercent
}
}Leaderboard Data
query GetLeaderboard {
usersWithScores {
username
calculated_score
}
}📱 Client-Side Auth
useClientAuth Hook
React hook for authentication state:
const { isAuthenticated, user } = useClientAuth()
// isAuthenticated: boolean
// user: { email, name, picture, ... }Usage Example
if (!isAuthenticated) {
// Redirect to sign-in
router.push('/sign-in')
}
// Use user data
const displayName = user?.name || user?.email🔒 Security Best Practices
For Users
- Strong password: Mix of letters, numbers, symbols
- Unique password: Don’t reuse passwords
- Regular logout: On shared devices
- Monitor sessions: Check Settings regularly
- Report suspicious activity: Contact support
Password Requirements
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
Account Security
- Email verification: Required at signup
- Session timeout: Automatic after inactivity
- Secure cookies: HTTP-only, Secure, SameSite
- HTTPS only: All connections encrypted
🆘 Troubleshooting
Can’t Login
- Check email and password
- Try password reset
- Clear browser cookies
- Use incognito/private mode
- Check internet connection
- Contact support
Session Expired
- Automatic token refresh failed
- Logout and login again
- Check cookie settings in browser
- Ensure cookies are enabled
Token Errors
- Clear cookies and relogin
- Check
/api/auth/sessionendpoint - Verify OIDC configuration
- Check environment variables
📊 Authentication Flow Diagram
1. User → Sign In Page (/sign-in)
2. Enter credentials (email + password)
3. Send to OIDC Provider
4. Provider validates credentials
5. Generate tokens (access, refresh, ID)
6. Set HTTP-only cookies
7. Redirect to Dashboard (/dashboard)
8. All API calls include cookies automatically
9. GraphQL validates token on each request
10. Auto-refresh before expiration🔗 API Endpoints
Authentication
GET /api/auth/session- Current session infoPOST /api/auth/refresh- Refresh access tokenPOST /api/auth/logout- Logout and clear cookies
OAuth/OIDC
GET /api/oidc/authorize- Start OIDC flowGET /api/oidc/callback- Handle callback
User Data
POST /api/proxy/graphql- GraphQL API with authenticationGET /api/me- Current user info
🌍 Multi-Device Support
Synchronization
- Progress syncs across all devices
- Login once, access everywhere
- Same account, multiple sessions
- Real-time updates via GraphQL
Session Limit
- Multiple sessions allowed
- View all active sessions in Settings
- Logout from specific devices
- Security monitoring
Last updated on