Authentication
The authentication system manages both authenticated users and anonymous sessions. It uses Flask-Login for session management and supports two authentication methods:
- Helmholtz AAI (primary) - OAuth2/OIDC authentication via Helmholtz Authentication and Authorization Infrastructure
- Legacy email/password - Traditional authentication for backward compatibility
Authentication Technologies
Flask-Login
The application uses Flask-Login for managing user sessions and authentication state. Flask-Login provides:
- Session-based user tracking
- User loader for retrieving user objects from the database
- Login/logout functionality
- Session protection in “strong” mode to prevent session hijacking
- “Remember Me” functionality for persistent logins
Helmholtz AAI
Helmholtz Authentication and Authorization Infrastructure (AAI) provides enterprise-grade authentication for Helmholtz research centers and external partners. For more information, see the Helmholtz AAI documentation.
Key Features:
- Single Sign-On (SSO) across Helmholtz Cloud services
- Cross-institutional access for Helmholtz users and invited partners
- No password management - users authenticate with their home institution credentials
- Minimal data transfer - passwords never leave the home institution
- Virtual Organizations (VO) support for group management and resource sharing
- Compliance with GDPR and international standards (AARC blueprint, EOSC compatibility)
How It Works:
- User clicks “Helmholtz ID” login button
- User selects their home institution
- User authenticates with home institution credentials
- Helmholtz AAI provides only the unique subject identifier (
sub) - Application creates or updates user account with the subject ID and logs them in
Features
- Helmholtz AAI OAuth2/OIDC authentication for Helmholtz users
- Legacy email/password authentication (for backward compatibility)
- Session-based user tracking for anonymous users
- Automatic run migration: if a user logs in or registers after running pipelines as a guest, all previous runs are migrated to their account
- User-specific data directories for storing runs and configuration files
- Token revocation on logout for OAuth sessions
Authentication Workflow
1. Anonymous Sessions
When a visitor accesses the app without logging in:
- The
assign_session_idhook assigns a uniquesession_id(UUID) to the Flask session - A directory is created under:
user_data/anon/<session_id> - Any runs started in this state are linked to the
session_idin MongoDB (runscollection)
2. Helmholtz AAI Login (OAuth2/OIDC)
Endpoint: GET /login
Flow:
- User is redirected to Helmholtz AAI authorization endpoint
- User selects home institution and authenticates
- Helmholtz AAI redirects back to
/auth/callbackwith authorization code - Application exchanges code for access token
- Application fetches user info from Helmholtz AAI userinfo endpoint
- Only the unique subject identifier (
sub) is received from Helmholtz AAI - User document is created or updated in MongoDB with:
helmholtz_sub: Unique subject identifier from Helmholtz AAI (the only field provided)
- User is logged in via Flask-Login
- User data directory is created if needed
- Any anonymous session data is migrated to the authenticated user
3. Legacy Email/Password Login
Endpoint: POST /login
Payload:
{
"email": "user@example.com",
"password": "plaintextpassword",
"remember_me": true
}
Process:
- Validate email/password
- Look up user in MongoDB
userscollection - Verify password hash using Werkzeug security
- Log user in via Flask-Login
- Ensure user data directory exists
- Run migration: Migrate any anonymous session runs to the authenticated user
4. Legacy Registration
Endpoint: POST /register
Payload:
{
"email": "user@example.com",
"password": "plaintextpassword"
}
Process:
- Validate email/password
- Check if email already exists
- Hash password using Werkzeug security
- Insert new user document in
userscollection - Create user-specific directory:
user_data/<user_id> - Log user in via Flask-Login
5. Check Authentication Status
Endpoint: GET /api/check_auth
Returns:
For authenticated users:
{
"authenticated": true,
"user": {
"id": "user_id",
"email": "user@example.com", // null for Helmholtz AAI users
"name": "User Name", // null for Helmholtz AAI users
"role": "user"
}
}
For unauthenticated users:
{
"authenticated": false
}
Note: For Helmholtz AAI users, email and name will be null since Helmholtz AAI only provides the subject identifier.
6. Logout
Endpoint: POST /logout
Process:
- For OAuth sessions: Revokes access token with Helmholtz AAI
- Logs out user via Flask-Login
- Clears session data
User Schema
Helmholtz AAI Users
{
"_id": ObjectId,
"helmholtz_sub": "unique-subject-id-from-helmholtz", // Only field received from Helmholtz AAI
"email": null, // Not provided by Helmholtz AAI
"name": null, // Not provided by Helmholtz AAI
"role": "user" // Default role
}
Note: Helmholtz AAI only provides the unique subject identifier (sub). Email and name fields are not included in the userinfo response and will be null in the database.
Legacy Users
{
"_id": ObjectId,
"email": "user@example.com",
"password": "hashed_password", // Werkzeug hash
"role": "user"
}
Why Session-Based Management Matters
- Pipeline continuity: Users can start pipelines without an account
- Seamless upgrade: If users register or log in later, all runs are automatically linked to their account
- Consistent history: No runs are lost when moving from anonymous to authenticated mode
- Better tracking: Each anonymous user has an isolated data space, avoiding collisions between guest runs
Directory Structure
user_data/
│
├── <user_id>/ # Authenticated user data
│ └── ... # Runs, configs, outputs
│
└── anon/
└── <session_id>/ # Anonymous user data
Implementation Details
Flask-Login Configuration
- User Loader: Loads users from MongoDB by ObjectId
- Session Protection: Enabled in “strong” mode
- Remember Me: Supported for persistent logins
- Login Required Decorator:
@login_requiredfor protected routes
OAuth2/OIDC Configuration
- Provider: Helmholtz AAI (
login.helmholtz.de) - Flow: Authorization Code flow
- Token Storage: Access tokens stored in Flask session for revocation
- User Info: Only the unique subject identifier (
sub) is received from Helmholtz AAI userinfo endpoint - User Identification: Users are identified solely by
helmholtz_sub(thesubfield from OAuth response)
Security
- Password Hashing: Werkzeug security for legacy authentication
- Session Security: Flask-Login strong session protection
- Token Revocation: OAuth tokens revoked on logout
- CSRF Protection: Flask session-based CSRF protection