-
Notifications
You must be signed in to change notification settings - Fork 0
Server Implementation
- Introduction
- Application Architecture
- Flask Application Structure
- Route Management System
- Configuration Management
- Storage Backend Implementation
- Session Management
- Request Validation and Security
- Payload Processing and Decoding
- Scalability Considerations
- Security Architecture
- Troubleshooting Guide
- Conclusion
The Post-Quantum WebAuthn Platform server is a Flask-based implementation designed to demonstrate post-quantum cryptographic WebAuthn authentication. The server provides comprehensive support for both classical and post-quantum cryptographic algorithms, with robust storage backends, session management, and security controls. This documentation covers the complete server architecture, focusing on the Flask application structure, route handlers, configuration management, and security implementations.
The server follows a modular Flask architecture with clear separation of concerns across multiple layers:
graph TB
subgraph "Application Layer"
App[Flask Application]
Config[Configuration Manager]
Routes[Route Handlers]
end
subgraph "Business Logic Layer"
Auth[Authentication Services]
Storage[Storage Services]
Session[Session Management]
Metadata[Metadata Services]
end
subgraph "Data Access Layer"
LocalStore[Local File Storage]
CloudStore[Google Cloud Storage]
SessionStore[Session Metadata Store]
end
subgraph "External Dependencies"
FIDO2[FIDO2 Library]
PQCrypto[Post-Quantum Cryptography]
WebAuthn[WebAuthn Protocol]
end
App --> Config
App --> Routes
Routes --> Auth
Routes --> Storage
Routes --> Session
Routes --> Metadata
Storage --> LocalStore
Storage --> CloudStore
Session --> SessionStore
Auth --> FIDO2
Auth --> PQCrypto
Auth --> WebAuthn
Diagram sources
- app.py
- config.py
Section sources
- app.py
- config.py
The Flask application is initialized through a sophisticated entry point that handles dynamic module loading and configuration resolution:
The application initialization process involves several key steps:
- Project Root Discovery: Automatic detection of the repository root for proper import resolution
- Module Loading: Dynamic loading of route modules to register endpoints
- Configuration Setup: Environment-based configuration with fallback mechanisms
- Dependency Warming: Pre-warming of critical dependencies during startup
sequenceDiagram
participant Main as "Main Entry Point"
participant App as "Flask Application"
participant Config as "Configuration Module"
participant Routes as "Route Modules"
participant Startup as "Startup Validator"
Main->>App : Initialize Flask app
Main->>Config : Load configuration
Config->>App : Apply settings
Main->>Routes : Import route modules
Routes->>App : Register endpoints
Main->>Startup : Warm dependencies
Startup->>Config : Verify metadata bootstrapping
Startup->>Routes : Test storage connectivity
Main->>App : Start server
Diagram sources
- app.py
- startup.py
The server uses a decorator-based approach for route registration, with automatic endpoint discovery:
classDiagram
class FlaskApp {
+dict routes
+dict before_request_funcs
+dict after_request_funcs
+run(host, port, ssl_context)
}
class RouteModule {
+function register_begin()
+function register_complete()
+function authenticate_begin()
+function authenticate_complete()
}
class SimpleRoutes {
+register_begin()
+register_complete()
+authenticate_begin()
+authenticate_complete()
}
class AdvancedRoutes {
+advanced_register_begin()
+advanced_register_complete()
+advanced_authenticate_begin()
+advanced_authenticate_complete()
}
class GeneralRoutes {
+index_html()
+api_get_verified_metadata()
+api_upload_custom_metadata()
+api_codec_payload()
}
FlaskApp --> RouteModule
RouteModule <|-- SimpleRoutes
RouteModule <|-- AdvancedRoutes
RouteModule <|-- GeneralRoutes
Diagram sources
- simple.py
- advanced.py
- general.py
Section sources
- app.py
- simple.py
- advanced.py
- general.py
The server implements a three-tier routing architecture supporting different authentication scenarios:
The simple authentication flow provides basic registration and authentication with minimal configuration requirements:
sequenceDiagram
participant Client as "Web Client"
participant Simple as "Simple Routes"
participant FIDO2 as "FIDO2 Server"
participant Storage as "Storage Backend"
participant Session as "Session Store"
Client->>Simple : POST /api/register/begin
Simple->>FIDO2 : create_fido_server()
FIDO2->>Simple : RegistrationOptions
Simple->>Session : Store state & options
Simple-->>Client : Registration Options
Client->>Simple : POST /api/register/complete
Simple->>FIDO2 : server.register_complete()
FIDO2->>Storage : Store credential
Storage-->>Simple : Credential stored
Simple->>Session : Clear state
Simple-->>Client : Registration Result
Diagram sources
- simple.py
- simple.py
The advanced flow supports extensive customization and configuration options:
flowchart TD
Start([Advanced Request]) --> ValidateInput["Validate Input Parameters"]
ValidateInput --> ParseJSON["Parse JSON Payload"]
ParseJSON --> ExtractFields["Extract Required Fields"]
ExtractFields --> BuildOptions["Build Registration Options"]
BuildOptions --> ApplyCustomizations["Apply Custom Algorithm Selection"]
ApplyCustomizations --> GenerateChallenge["Generate Challenge"]
GenerateChallenge --> StoreState["Store Session State"]
StoreState --> ReturnOptions["Return Options to Client"]
ReturnOptions --> End([End])
Diagram sources
- advanced.py
The general routes provide administrative and utility functions:
| Endpoint | Method | Purpose | Security Level |
|---|---|---|---|
/ |
GET | Main application entry point | Public |
/index.html |
GET | HTML interface rendering | Public |
/api/mds/metadata/base |
GET | Retrieve verified metadata | Public |
/api/mds/metadata/custom |
GET/POST/DELETE | Manage custom metadata | Admin |
/api/codec |
POST | Encode/decode payloads | Public |
/api/deletepub |
POST | Delete public credentials | Admin |
/api/downloadcred |
GET | Download credential data | Admin |
Section sources
- simple.py
- advanced.py
- general.py
The configuration system provides flexible environment-based settings with comprehensive validation and fallback mechanisms:
The server supports extensive configuration through environment variables:
| Configuration Category | Environment Variables | Purpose |
|---|---|---|
| Secret Management |
FIDO_SERVER_SECRET_KEY, FIDO_SERVER_SECRET_KEY_FILE
|
Session encryption keys |
| Relying Party |
FIDO_SERVER_RP_NAME, FIDO_SERVER_RP_ID
|
RP entity configuration |
| Storage Backend |
FIDO_SERVER_GCS_ENABLED, FIDO_SERVER_GCS_BUCKET
|
Cloud storage configuration |
| Attestation | FIDO_SERVER_TRUSTED_ATTESTATION_CA_SUBJECTS |
Trusted CA configuration |
| Metadata | FIDO_SERVER_MDS_BOOTSTRAPPED |
Metadata bootstrap control |
The secret key resolution follows a priority order with automatic generation:
flowchart TD
Start([Secret Key Request]) --> CheckEnv["Check FIDO_SERVER_SECRET_KEY"]
CheckEnv --> EnvFound{"Environment Variable<br/>Found?"}
EnvFound --> |Yes| UseEnv["Use Environment Value"]
EnvFound --> |No| CheckFile["Check FIDO_SERVER_SECRET_KEY_FILE"]
CheckFile --> FileFound{"File Specified?<br/>File Exists?"}
FileFound --> |Yes| ReadFile["Read File Content"]
FileFound --> |No| CheckStored["Check Stored Key"]
ReadFile --> UseFile["Use File Content"]
CheckStored --> StoredFound{"Stored Key<br/>Exists?"}
StoredFound --> |Yes| UseStored["Use Stored Key"]
StoredFound --> |No| Generate["Generate New Key"]
Generate --> Store["Store Generated Key"]
Store --> UseGenerated["Use Generated Key"]
UseEnv --> End([Return Secret])
UseFile --> End
UseStored --> End
UseGenerated --> End
Diagram sources
- config.py
The RP configuration supports dynamic resolution with fallback mechanisms:
classDiagram
class RPConfiguration {
+string rp_name
+string rp_id
+string rp_origin
+validate_rp_id()
+build_entity()
}
class RPResolver {
+determine_rp_id()
+build_rp_entity()
+validate_origin()
}
class FIDO2Server {
+PublicKeyCredentialRpEntity entity
+create_fido_server()
}
RPConfiguration --> RPResolver
RPResolver --> FIDO2Server
Diagram sources
- config.py
Section sources
- config.py
The storage system implements a pluggable architecture supporting both local file storage and Google Cloud Storage:
graph TB
subgraph "Storage Interface"
StorageInterface[IStorage Interface]
end
subgraph "Local Storage"
LocalFS[Local File System]
LocalDir[Session Credentials Directory]
end
subgraph "Cloud Storage"
GCS[Google Cloud Storage]
BlobName[Blob Naming]
BucketOps[Bucket Operations]
end
subgraph "Session Metadata"
MetaStore[Metadata Store]
SessionDir[Session Directories]
Cleanup[Cleanup Scheduler]
end
StorageInterface --> LocalFS
StorageInterface --> GCS
LocalFS --> LocalDir
GCS --> BlobName
GCS --> BucketOps
StorageInterface --> MetaStore
MetaStore --> SessionDir
MetaStore --> Cleanup
Diagram sources
- storage.py
- cloud_storage.py
- session_metadata_store.py
Local storage provides a straightforward file-based solution with automatic directory management:
sequenceDiagram
participant App as "Application"
participant Storage as "Storage Module"
participant FileSystem as "File System"
participant Session as "Session Manager"
App->>Storage : savekey(name, data)
Storage->>Session : resolve_session_id()
Session-->>Storage : session_id
Storage->>FileSystem : create directory if needed
Storage->>FileSystem : write pickle data
FileSystem-->>Storage : write complete
Storage-->>App : save complete
App->>Storage : readkey(name)
Storage->>FileSystem : read pickle data
FileSystem-->>Storage : raw data
Storage->>Storage : unpickle data
Storage-->>App : credential data
Diagram sources
- storage.py
The cloud storage implementation provides enterprise-grade reliability with automatic retry mechanisms:
| Feature | Implementation | Retry Strategy |
|---|---|---|
| Upload Operations | upload_bytes() |
Exponential backoff (3 attempts) |
| Download Operations | download_bytes() |
Exponential backoff (3 attempts) |
| Blob Listing | list_blob_names() |
No retry (read-only) |
| Deletion Operations | delete_blob() |
No retry (idempotent) |
| Existence Checks | blob_exists() |
No retry (read-only) |
The session metadata store provides specialized handling for temporary session data:
classDiagram
class SessionMetadataStore {
+ensure_session(id)
+list_sessions()
+touch_last_access(id)
+list_files(id)
+read_file(id, name)
+write_file(id, name, data)
+delete_file(id, name)
+delete_session(id)
+prune_session(id)
}
class LocalSessionStore {
+_local_session_directory()
+_local_touch_last_access()
+_local_maybe_cleanup()
}
class GCSSessionStore {
+_session_blob()
+_metadata_prefix()
+_last_access_blob()
}
SessionMetadataStore <|-- LocalSessionStore
SessionMetadataStore <|-- GCSSessionStore
Diagram sources
- session_metadata_store.py
Section sources
- storage.py
- cloud_storage.py
- session_metadata_store.py
The session management system handles multi-step authentication processes with state persistence and cleanup:
stateDiagram-v2
[*] --> InitiateRegistration
InitiateRegistration --> StoreState : Save session state
StoreState --> WaitClientResponse : Send options to client
WaitClientResponse --> ValidateResponse : Receive client response
ValidateResponse --> ProcessRegistration : Complete registration
ProcessRegistration --> CleanupState : Clear session state
CleanupState --> [*]
InitiateRegistration --> StoreState : Authenticate flow
StoreState --> WaitClientResponse : Send assertion options
WaitClientResponse --> ValidateResponse : Receive assertion response
ValidateResponse --> ProcessAuthentication : Complete authentication
ProcessAuthentication --> CleanupState : Clear session state
CleanupState --> [*]
Session state is maintained across HTTP requests using Flask's session mechanism with custom serialization:
sequenceDiagram
participant Client as "Web Client"
participant Session as "Session Handler"
participant Storage as "Storage Backend"
participant State as "Session State"
Client->>Session : First request (begin)
Session->>State : Store registration state
State->>Storage : Serialize to session
Storage-->>State : Store complete
State-->>Session : State saved
Session-->>Client : Response with state
Client->>Session : Second request (complete)
Session->>State : Retrieve registration state
State->>Storage : Deserialize from session
Storage-->>State : State restored
State-->>Session : State available
Session->>Session : Process completion
Session->>State : Clear state
State-->>Session : State cleared
Session-->>Client : Final response
Section sources
- simple.py
- advanced.py
The server implements comprehensive request validation and security measures:
flowchart TD
Request[Incoming Request] --> ContentType["Check Content-Type"]
ContentType --> JSONValidation["Validate JSON Structure"]
JSONValidation --> FieldValidation["Validate Required Fields"]
FieldValidation --> TypeValidation["Validate Data Types"]
TypeValidation --> RangeValidation["Validate Value Ranges"]
RangeValidation --> EncodingValidation["Validate Encoding"]
EncodingValidation --> SecurityCheck["Security Validation"]
SecurityCheck --> ProcessRequest["Process Request"]
ContentType --> |Invalid| ErrorResponse["Return 400 Bad Request"]
JSONValidation --> |Invalid| ErrorResponse
FieldValidation --> |Missing| ErrorResponse
TypeValidation --> |Wrong Type| ErrorResponse
RangeValidation --> |Out of Range| ErrorResponse
EncodingValidation --> |Invalid| ErrorResponse
SecurityCheck --> |Security Violation| ErrorResponse
ProcessRequest --> Success["Return Success Response"]
The server implements multiple layers of security protection:
| Security Layer | Implementation | Purpose |
|---|---|---|
| CSRF Protection | Flask-WTF integration | Prevent cross-site request forgery |
| Input Sanitization | Custom validation functions | Prevent injection attacks |
| Session Security | Secure cookie configuration | Protect session integrity |
| Rate Limiting | Middleware implementation | Prevent abuse |
| Certificate Validation | X.509 chain verification | Ensure authenticator authenticity |
classDiagram
class ErrorHandler {
+handle_validation_error()
+handle_authentication_error()
+handle_storage_error()
+handle_security_error()
+log_error()
+return_error_response()
}
class ValidationError {
+string message
+int status_code
+dict details
}
class AuthenticationError {
+string error_type
+string error_message
+dict context
}
class SecurityError {
+string violation_type
+string evidence
+dict mitigation
}
ErrorHandler --> ValidationError
ErrorHandler --> AuthenticationError
ErrorHandler --> SecurityError
Section sources
- simple.py
- advanced.py
- general.py
The server provides comprehensive payload processing capabilities for WebAuthn-related data:
graph TB
subgraph "Input Processing"
Input[Raw Payload]
Base64Decode[Base64 Decode]
CBORDecode[CBOR Decode]
JSONParse[JSON Parse]
end
subgraph "Structure Analysis"
TypeDetection[Type Detection]
FieldExtraction[Field Extraction]
Validation[Schema Validation]
end
subgraph "Output Generation"
StructuredOutput[Structured Output]
HexDump[Hex Dump]
HumanReadable[Human Readable]
end
Input --> Base64Decode
Base64Decode --> CBORDecode
Base64Decode --> JSONParse
CBORDecode --> TypeDetection
JSONParse --> TypeDetection
TypeDetection --> FieldExtraction
FieldExtraction --> Validation
Validation --> StructuredOutput
StructuredOutput --> HexDump
StructuredOutput --> HumanReadable
Diagram sources
- decode.py
- encode.py
The decoder supports various WebAuthn payload formats:
| Payload Type | Description | Output Format |
|---|---|---|
| Attestation Object | Authenticator attestation data | Structured JSON with hex dumps |
| Authenticator Data | Authentication data | Bitfield analysis with flags |
| Client Data JSON | Client challenge data | Formatted challenge details |
| Public Key Credential | Credential information | COSE key structure |
| X.509 Certificates | Attestation certificates | Certificate details with extensions |
The encoder converts structured data back to WebAuthn-compatible formats:
sequenceDiagram
participant Client as "Web Client"
participant Encoder as "Encoder Service"
participant Validator as "Format Validator"
participant Converter as "Format Converter"
Client->>Encoder : Submit structured data
Encoder->>Validator : Validate input format
Validator-->>Encoder : Validation result
Encoder->>Converter : Convert to target format
Converter-->>Encoder : Converted payload
Encoder-->>Client : Encoded result
Diagram sources
- encode.py
Section sources
- decode.py
- encode.py
The server architecture incorporates several scalability features for handling multiple concurrent authentications:
graph TB
subgraph "Load Balancer"
LB[Load Balancer]
end
subgraph "Application Tier"
App1[App Instance 1]
App2[App Instance 2]
App3[App Instance 3]
end
subgraph "Storage Tier"
SharedStorage[Shared Storage]
Cache[Redis Cache]
end
subgraph "Session Tier"
SessionStore[Session Store]
MetadataStore[Metadata Store]
end
LB --> App1
LB --> App2
LB --> App3
App1 --> SharedStorage
App2 --> SharedStorage
App3 --> SharedStorage
App1 --> Cache
App2 --> Cache
App3 --> Cache
App1 --> SessionStore
App2 --> SessionStore
App3 --> SessionStore
App1 --> MetadataStore
App2 --> MetadataStore
App3 --> MetadataStore
The server handles concurrent authentications through:
- Thread-Safe Storage: Atomic operations for credential storage
- Session Isolation: Separate session spaces for different users
- Connection Pooling: Efficient database connection management
- Memory Management: Garbage collection of temporary data
| Optimization Technique | Implementation | Benefit |
|---|---|---|
| Lazy Loading | Metadata loaded on demand | Reduced startup time |
| Connection Pooling | Reused database connections | Improved throughput |
| Caching | Redis for frequently accessed data | Reduced latency |
| Compression | Gzip for large payloads | Bandwidth savings |
| Async Processing | Background tasks for heavy operations | Better responsiveness |
The server implements a comprehensive security architecture focused on WebAuthn compliance and post-quantum protection:
graph TB
subgraph "Algorithm Support"
PQCAlgorithms[Post-Quantum Algorithms]
ClassicalAlgorithms[Classical Algorithms]
end
subgraph "Algorithm Detection"
MLDSA[ML-DSA Family]
Kyber[Kyber KEM]
BIKE[BIKE KEM]
Frodo[Frodo KEM]
end
subgraph "Security Validation"
SignatureVerify[Signature Verification]
KeyExchange[Key Exchange Validation]
CertificateChain[Certificate Chain Validation]
end
PQCAlgorithms --> MLDSA
PQCAlgorithms --> Kyber
PQCAlgorithms --> BIKE
PQCAlgorithms --> Frodo
MLDSA --> SignatureVerify
Kyber --> KeyExchange
BIKE --> KeyExchange
Frodo --> KeyExchange
SignatureVerify --> CertificateChain
KeyExchange --> CertificateChain
The server performs comprehensive attestation validation:
sequenceDiagram
participant Client as "Authenticator"
participant Server as "WebAuthn Server"
participant Metadata as "FIDO Metadata"
participant TrustAnchor as "Trust Anchor"
Client->>Server : Registration Request
Server->>Server : Extract attestation data
Server->>Metadata : Lookup authenticator metadata
Metadata-->>Server : Authenticator details
Server->>TrustAnchor : Verify certificate chain
TrustAnchor-->>Server : Chain validation result
Server->>Server : Validate attestation signature
Server->>Server : Check RP ID hash
Server->>Server : Verify AAGUID match
Server-->>Client : Registration result
Diagram sources
- attestation.py
| Control Type | Implementation | Purpose |
|---|---|---|
| Algorithm Whitelisting | Allowed algorithm lists | Prevent weak algorithms |
| Certificate Pinning | SHA-256 fingerprint validation | Prevent MITM attacks |
| Challenge Binding | Unique per-request challenges | Prevent replay attacks |
| RP ID Validation | Domain-specific RP ID checking | Prevent cross-site attacks |
| User Verification | UV requirement enforcement | Ensure user presence |
Section sources
- attestation.py
- config.py
Common issues and their solutions:
Problem: Cloud storage connection failures Solution: Verify GCS credentials and bucket permissions
Problem: Local storage permission errors Solution: Check directory permissions and disk space
Problem: Registration timeouts Solution: Increase timeout values and check network connectivity
Problem: Attestation validation failures Solution: Verify authenticator metadata and certificate chains
Problem: Slow response times Solution: Enable caching and optimize database queries
Problem: Memory leaks Solution: Monitor session cleanup and garbage collection
Section sources
- storage.py
- cloud_storage.py
- startup.py
The Post-Quantum WebAuthn Platform server demonstrates a robust, scalable, and secure implementation of modern authentication protocols. The modular architecture supports both classical and post-quantum cryptographic algorithms while maintaining compatibility with existing WebAuthn infrastructure. Key strengths include:
- Flexible Storage Backends: Support for both local and cloud storage
- Comprehensive Security: Multi-layered security with post-quantum protection
- Scalable Design: Horizontal scaling capabilities and concurrency management
- Developer-Friendly: Extensive configuration options and debugging tools
The server serves as an excellent foundation for production deployments requiring advanced authentication capabilities with future-proof cryptographic support.