-
Notifications
You must be signed in to change notification settings - Fork 0
Session Metadata Store
- Introduction
- System Architecture
- Data Model
- Storage Backends
- Session Management Operations
- Security Implementation
- Integration with Flask
- Performance Considerations
- Troubleshooting Guide
- Best Practices
The session metadata store is a sophisticated component of the post-quantum WebAuthn platform that manages temporary authentication state during WebAuthn registration and authentication ceremonies. It provides a pluggable storage solution that supports both in-memory file-based storage and cloud-based Google Cloud Storage backends, ensuring reliable session persistence while maintaining security and performance standards.
The system is designed to handle the ephemeral nature of WebAuthn ceremonies, where temporary state must be maintained across multiple HTTP requests while preventing session fixation attacks and protecting against replay attacks. It serves as the foundation for managing challenge values, relying party identifiers, user handles, and ceremony timestamps throughout the authentication process.
The session metadata store follows a layered architecture with clear separation of concerns:
graph TB
subgraph "Application Layer"
WebAuthn[WebAuthn Ceremonies]
Flask[Flask Session Management]
end
subgraph "Session Management Layer"
Metadata[Metadata Module]
SessionStore[Session Metadata Store]
end
subgraph "Storage Abstraction Layer"
LocalStorage[Local File Storage]
CloudStorage[Cloud Storage]
GCS[Google Cloud Storage]
end
subgraph "Infrastructure Layer"
FileSystem[File System]
Network[Network Storage]
Config[Configuration]
end
WebAuthn --> Metadata
Flask --> Metadata
Metadata --> SessionStore
SessionStore --> LocalStorage
SessionStore --> CloudStorage
CloudStorage --> GCS
LocalStorage --> FileSystem
CloudStorage --> Network
SessionStore --> Config
Diagram sources
- session_metadata_store.py
- metadata.py
- cloud_storage.py
Section sources
- session_metadata_store.py
- metadata.py
The session metadata store implements a structured data model optimized for WebAuthn ceremony state management:
classDiagram
class SessionMetadataItem {
+string filename
+dict payload
+string legal_header
+MetadataBlobPayloadEntry entry
+string uploaded_at
+string original_filename
+float mtime
}
class SessionRecord {
+string session_id
+dict challenge_data
+string rp_identifier
+string user_handle
+datetime timestamp
+string ceremony_type
}
class StorageBackend {
<<interface>>
+ensure_session(session_id)
+write_file(session_id, filename, data)
+read_file(session_id, filename)
+delete_file(session_id, filename)
+list_files(session_id)
+touch_last_access(session_id)
+resolve_last_access(session_id)
}
class LocalStorage {
+_local_session_directory(session_id)
+_local_touch_last_access(directory)
+_local_resolve_last_access(directory)
+_local_maybe_cleanup()
}
class CloudStorage {
+_using_gcs()
+_user_root_prefix(session_id)
+_metadata_prefix(session_id)
+_last_access_blob(session_id)
}
SessionMetadataItem --> SessionRecord : contains
StorageBackend <|-- LocalStorage : implements
StorageBackend <|-- CloudStorage : implements
SessionRecord --> StorageBackend : stored by
Diagram sources
- metadata.py
- session_metadata_store.py
Each session maintains a comprehensive record of authentication state:
| Field | Type | Description | Security Considerations |
|---|---|---|---|
session_id |
string | Unique identifier for the session | Must be cryptographically secure random value |
challenge_data |
dict | Challenge values and parameters | Encrypted or hashed to prevent tampering |
rp_identifier |
string | Relying Party identifier | Must match RP ID from WebAuthn ceremony |
user_handle |
string | User identifier | Base64-encoded to prevent injection |
timestamp |
datetime | Last activity timestamp | Used for cleanup and expiration |
ceremony_type |
string | Registration/authentication | Prevents cross-ceremony confusion |
Section sources
- metadata.py
- session_metadata_store.py
The session metadata store supports multiple storage backends with automatic failover capabilities:
The default storage backend uses the local filesystem for development and small-scale deployments:
flowchart TD
Start([Session Request]) --> CheckBackend{Using GCS?}
CheckBackend --> |No| LocalPath["Local Path:<br/>SESSION_METADATA_DIR/session_id/"]
LocalPath --> CreateDir["Create Directory<br/>if Not Exists"]
CreateDir --> TouchMarker["Touch .last-access Marker"]
TouchMarker --> Cleanup["Cleanup Inactive Sessions"]
Cleanup --> End([Complete])
CheckBackend --> |Yes| CloudPath["Cloud Path:<br/>user-data/session_id/metadata/"]
CloudPath --> UploadMarker["Upload .last-access Blob"]
UploadMarker --> End
Diagram sources
- session_metadata_store.py
- session_metadata_store.py
For production deployments requiring high availability and scalability:
| Configuration Parameter | Environment Variable | Default Value | Purpose |
|---|---|---|---|
| Bucket Name | FIDO_SERVER_GCS_BUCKET |
None | Target storage bucket |
| Credentials File | FIDO_SERVER_GCS_CREDENTIALS_FILE |
None | Service account credentials |
| Project Override | FIDO_SERVER_GCS_PROJECT |
None | Override default project |
| Prefix | FIDO_SERVER_GCS_USER_FOLDER_PREFIX |
user-data |
Base path prefix |
| Subdirectory | FIDO_SERVER_GCS_USER_METADATA_SUBDIR |
metadata |
Metadata subdirectory |
Section sources
- cloud_storage.py
- session_metadata_store.py
The session metadata store provides a comprehensive set of operations for managing authentication state:
sequenceDiagram
participant Client as Client Browser
participant Flask as Flask App
participant Metadata as Metadata Module
participant Store as Session Store
participant Storage as Storage Backend
Client->>Flask : Start Registration
Flask->>Metadata : ensure_metadata_session_id()
Metadata->>Metadata : _get_metadata_session_id(create=True)
Metadata->>Store : ensure_session(session_id)
Store->>Storage : Create session directory/blob
Storage-->>Store : Confirmation
Store-->>Metadata : Session ready
Metadata-->>Flask : Session ID
Flask-->>Client : Registration options
Note over Client,Storage : WebAuthn Ceremony
Client->>Flask : Registration Response
Flask->>Metadata : save_session_metadata_item()
Metadata->>Store : write_file(filename, data)
Store->>Storage : Store metadata blob
Storage-->>Store : Success
Store-->>Metadata : Complete
Metadata-->>Flask : Item saved
Flask-->>Client : Registration complete
Diagram sources
- metadata.py
- metadata.py
The system implements automatic lifecycle management with configurable policies:
| Operation | Purpose | Trigger | Policy |
|---|---|---|---|
ensure_session() |
Initialize session | First access | Creates directory/blob |
touch_last_access() |
Update activity | Any operation | Updates timestamp |
resolve_last_access() |
Check freshness | Cleanup cycle | Returns timestamp |
list_sessions() |
Enumerate sessions | Maintenance | Lists all sessions |
delete_session() |
Remove session | Manual/expiry | Deletes all data |
prune_session() |
Clean empty sessions | Cleanup | Removes if empty |
Section sources
- session_metadata_store.py
- session_metadata_store.py
- session_metadata_store.py
The session metadata store implements multiple layers of security to protect against common authentication vulnerabilities:
flowchart TD
Start([New Request]) --> CheckExisting{Existing Session?}
CheckExisting --> |Yes| ValidateSession["Validate Session Integrity"]
ValidateSession --> CheckTimestamp{"Timestamp Fresh?<br/>(≤ 14 days)"}
CheckTimestamp --> |Yes| ReuseSession["Reuse Existing Session"]
CheckTimestamp --> |No| GenerateNew["Generate New Session ID"]
CheckExisting --> |No| GenerateNew
GenerateNew --> SetCookie["Set Secure Cookie"]
SetCookie --> UpdateSession["Update Session State"]
ReuseSession --> UpdateSession
UpdateSession --> End([Authenticated])
Diagram sources
- metadata.py
- metadata.py
The session metadata store integrates seamlessly with Flask's CSRF protection mechanisms:
| Security Feature | Implementation | Configuration |
|---|---|---|
| Session Cookie | HttpOnly, Secure, SameSite=Lax | Automatic generation |
| Secret Key | Cryptographically secure random | Generated automatically |
| Expiration Policy | 1-year max age | Configurable |
| Path Isolation | Per-session isolation | Automatic |
The system implements several mechanisms to prevent replay attacks:
- Challenge Binding: Each ceremony binds challenges to specific sessions
- Timestamp Validation: Sessions expire after configurable periods
- Unique Identifiers: Session IDs use cryptographically secure randomness
- Activity Tracking: Last access timestamps prevent stale session reuse
Section sources
- metadata.py
- config.py
The session metadata store integrates deeply with Flask's session management system:
classDiagram
class FlaskApp {
+secret_key : bytes
+session_interface : SessionInterface
+before_request()
+after_request()
}
class MetadataModule {
+_SESSION_METADATA_SESSION_KEY : str
+_SESSION_METADATA_COOKIE_NAME : str
+ensure_metadata_session_id()
+_get_metadata_session_id()
+_schedule_session_cookie()
}
class SessionStore {
+ensure_session(session_id)
+touch_last_access(session_id)
+resolve_last_access(session_id)
}
class FlaskSession {
+permanent : bool
+modified : bool
+new : bool
}
FlaskApp --> MetadataModule : uses
MetadataModule --> SessionStore : delegates to
MetadataModule --> FlaskSession : manages
FlaskApp --> FlaskSession : provides interface
Diagram sources
- metadata.py
- config.py
The system automatically manages session cookies with appropriate security attributes:
| Attribute | Value | Purpose |
|---|---|---|
| Name | fido.mds.session |
Identifies session metadata |
| Max-Age | 1 year | Long-lived session support |
| HttpOnly | True | Prevents JavaScript access |
| Secure | Conditional | HTTPS requirement |
| SameSite | Lax/None | Cross-site protection |
| Path | / |
Global accessibility |
Section sources
- metadata.py
- config.py
The session metadata store is designed with performance and scalability in mind:
| Backend | Latency | Throughput | Scalability | Use Case |
|---|---|---|---|---|
| Local File | Low | Medium | Limited | Development, small deployments |
| Google Cloud Storage | Medium | High | Unlimited | Production, large deployments |
The system implements intelligent cleanup mechanisms to maintain performance:
flowchart TD
Timer[Cleanup Timer] --> CheckInterval{Within Interval<br/>(6 hours)?}
CheckInterval --> |No| UpdateTimer["Update Timer<br/>Mark: Now"]
CheckInterval --> |Yes| Skip["Skip Cleanup"]
UpdateTimer --> ScanSessions["Scan All Sessions"]
ScanSessions --> CheckAge{"Last Access<br/>(≥ 14 days)?"}
CheckAge --> |Yes| DeleteSession["Delete Session"]
CheckAge --> |No| KeepSession["Keep Session"]
DeleteSession --> LogDeletion["Log Deletion"]
KeepSession --> NextSession["Next Session"]
LogDeletion --> NextSession
NextSession --> MoreSessions{More Sessions?}
MoreSessions --> |Yes| CheckAge
MoreSessions --> |No| Complete[Complete]
Skip --> Complete
Diagram sources
- session_metadata_store.py
- metadata.py
The system minimizes memory usage through:
- Lazy Loading: Metadata loaded only when needed
- Streaming: Large files processed in chunks
- Caching: Frequently accessed data cached in memory
- Garbage Collection: Automatic cleanup of unused resources
Section sources
- session_metadata_store.py
- metadata.py
Common issues and their solutions when working with the session metadata store:
Problem: Sessions disappearing unexpectedly Causes:
- Cleanup interval exceeded (14 days inactive)
- Storage backend connectivity issues
- Session cookie not being sent
Solutions:
- Verify storage backend connectivity
- Check session cookie configuration
- Monitor cleanup logs
- Review storage quota limits
Problem: Authentication timeouts not working correctly Causes:
- Clock synchronization issues
- Incorrect session expiration settings
- Network latency affecting timing
Solutions:
- Synchronize system clocks
- Verify timeout configuration
- Adjust for network latency
- Monitor session activity patterns
Problem: Race conditions during session updates Causes:
- Multiple simultaneous requests
- Storage backend limitations
- Improper locking mechanisms
Solutions:
- Implement retry logic
- Use atomic operations
- Add proper error handling
- Monitor concurrency metrics
Section sources
- session_metadata_store.py
- metadata.py
- Environment-Specific Settings: Use different storage backends for development vs production
- Security Hardening: Always use HTTPS in production environments
- Monitoring: Implement logging for session creation and deletion events
- Backup Strategy: Regular backups of session metadata for disaster recovery
- Testing: Use isolated session storage for test environments
- Validation: Always validate session identifiers before use
- Error Handling: Implement graceful degradation for storage failures
- Documentation: Maintain clear documentation of session lifecycle
- Scalability Planning: Design storage backend for expected load
- Security Auditing: Regular security reviews of session handling
- Performance Monitoring: Track session creation and cleanup metrics
- Disaster Recovery: Implement backup and restore procedures
Section sources
- config.py
- cloud_storage.py