Simple Authentication Flow Endpoints - FeitianTech/postquantum-webauthn-platform GitHub Wiki
Simple Authentication Flow Endpoints
Table of Contents
- Introduction
- Architecture Overview
- Registration Endpoints
- Authentication Endpoints
- Session Management
- Credential Storage
- Frontend Integration
- Security Considerations
- Error Handling
- Examples
Introduction
The Post-Quantum WebAuthn Platform provides a simplified authentication flow through four core endpoints that enable secure passkey registration and authentication. This simple flow uses default configurations optimized for post-quantum cryptographic algorithms while maintaining compatibility with standard WebAuthn protocols.
The authentication system supports both classical and post-quantum cryptographic algorithms, automatically selecting appropriate COSE algorithm parameters and handling attestation verification for enhanced security. The platform integrates seamlessly with modern browsers' WebAuthn APIs while providing robust session management and credential persistence.
Architecture Overview
The simple authentication flow consists of two main phases: registration and authentication. Each phase involves coordinated interactions between frontend JavaScript, backend API endpoints, and underlying storage systems.
sequenceDiagram
participant Client as "Browser Client"
participant Frontend as "Frontend JS"
participant Backend as "API Server"
participant Storage as "Credential Storage"
participant Authenticator as "Authenticator Device"
Note over Client,Authenticator : Registration Flow
Client->>Frontend : User clicks Register
Frontend->>Backend : POST /api/register/begin
Backend-->>Frontend : Registration Options
Frontend->>Authenticator : WebAuthn Create Request
Authenticator-->>Frontend : Generated Credential
Frontend->>Backend : POST /api/register/complete
Backend->>Storage : Store Credential Data
Storage-->>Backend : Confirmation
Backend-->>Frontend : Registration Success
Note over Client,Authenticator : Authentication Flow
Client->>Frontend : User clicks Authenticate
Frontend->>Backend : POST /api/authenticate/begin
Backend-->>Frontend : Authentication Options
Frontend->>Authenticator : WebAuthn Get Request
Authenticator-->>Frontend : Assertion Response
Frontend->>Backend : POST /api/authenticate/complete
Backend-->>Frontend : Authentication Success
Diagram sources
- server/server/routes/simple.py
- server/server/routes/simple.py
- server/server/static/scripts/simple/auth-simple.js
- server/server/static/scripts/simple/auth-simple.js
Registration Endpoints
/api/register/begin - Registration Initialization
HTTP Method: POST
URL Pattern: /api/register/begin?email={email}
This endpoint initiates the registration process by generating registration options with appropriate COSE algorithm parameters and attestation configurations.
Request Parameters
| Parameter | Type | Location | Description |
|---|---|---|---|
email |
string | Query | User email address for credential association |
credentials |
array | Body | Existing credentials to exclude from registration |
existingCredentials |
array | Body | Alternative parameter name for existing credentials |
Request Schema
{
"credentials": [
{
"credentialId": "base64url_encoded_id",
"aaguid": "base64url_encoded_aaguid",
"publicKey": "base64url_encoded_public_key",
"algorithm": -49,
"signCount": 0
}
]
}
Response Schema
{
"status": "OK",
"publicKey": {
"challenge": "base64url_encoded_challenge",
"rp": {
"id": "example.com",
"name": "Example RP"
},
"user": {
"id": "base64url_encoded_user_id",
"name": "a_user",
"displayName": "A. User"
},
"pubKeyCredParams": [
{
"type": "public-key",
"alg": -49
},
{
"type": "public-key",
"alg": -50
}
],
"timeout": 90000,
"attestation": "none",
"authenticatorSelection": {
"authenticatorAttachment": "cross-platform",
"requireResidentKey": false,
"userVerification": "discouraged"
}
},
"__session_state": "session_state_data"
}
Implementation Details
The registration begin endpoint performs several critical operations:
- Session Management: Stores registration state and public key options in the Flask session
- Algorithm Selection: Filters available COSE algorithms to include only supported post-quantum and classical algorithms
- Existing Credentials: Processes existing credentials to exclude them from the new registration
- RP Configuration: Determines relying party ID and creates appropriate registration options
Section sources
/api/register/complete - Registration Completion
HTTP Method: POST
URL Pattern: /api/register/complete?email={email}
This endpoint completes the registration process by validating the attestation response, performing security checks, and storing the credential data.
Request Parameters
| Parameter | Type | Location | Description |
|---|---|---|---|
email |
string | Query | User email address associated with registration |
response |
object | Body | WebAuthn registration response from authenticator |
__session_state |
object | Body | Session state for validation (optional) |
Request Schema
{
"id": "base64url_encoded_credential_id",
"rawId": "base64url_encoded_credential_id",
"response": {
"attestationObject": "base64url_encoded_attestation_object",
"clientDataJSON": "base64url_encoded_client_data"
},
"type": "public-key",
"clientExtensionResults": {},
"__session_state": {
"challenge": "base64url_encoded_challenge",
"timeout": 90000,
"rpId": "example.com"
}
}
Response Schema
{
"status": "OK",
"algo": "ML-DSA-65 (PQC)",
"attestationFormat": "packed",
"storedCredential": {
"type": "simple",
"email": "[email protected]",
"userName": "[email protected]",
"displayName": "[email protected]",
"credentialId": "base64_encoded_credential_id",
"credentialIdBase64Url": "base64url_encoded_credential_id",
"aaguid": "base64url_encoded_aaguid",
"publicKey": "base64_encoded_public_key",
"publicKeyAlgorithm": -49,
"signCount": 0,
"createdAt": 1640995200.0,
"attestationFormat": "packed",
"properties": {
"attestationSignatureValid": true,
"attestationRootValid": true,
"attestationRpIdHashValid": true,
"attestationAaguidMatch": true
}
},
"relyingParty": {
"attestationFmt": "packed",
"credentialId": "hex_encoded_credential_id",
"publicKeyAlgorithm": -49,
"registrationData": {
"flags": {
"UP": true,
"UV": false,
"AT": true,
"ED": false
},
"signatureCounter": 0
}
}
}
Processing Pipeline
The registration completion endpoint implements a comprehensive validation pipeline:
- State Validation: Verifies session state and challenge integrity
- Attestation Processing: Extracts and validates attestation statements
- Security Checks: Performs signature validation, root certificate verification, and RP ID hash validation
- Credential Storage: Persists credential data with metadata and properties
- Session Cleanup: Removes temporary session data
Section sources
Authentication Endpoints
/api/authenticate/begin - Authentication Initialization
HTTP Method: POST
URL Pattern: /api/authenticate/begin?email={email}
This endpoint initiates the authentication process by retrieving stored credentials and generating authentication options.
Request Parameters
| Parameter | Type | Location | Description |
|---|---|---|---|
email |
string | Query | User email address for credential lookup |
credentials |
array | Body | Stored credentials for authentication |
storedCredentials |
array | Body | Alternative parameter name for stored credentials |
Request Schema
{
"credentials": [
{
"credentialId": "base64url_encoded_id",
"aaguid": "base64url_encoded_aaguid",
"publicKey": "base64url_encoded_public_key",
"algorithm": -49,
"signCount": 0
}
]
}
Response Schema
{
"publicKey": {
"challenge": "base64url_encoded_challenge",
"rpId": "example.com",
"allowCredentials": [
{
"type": "public-key",
"id": "base64url_encoded_credential_id"
}
],
"timeout": 90000,
"userVerification": "discouraged"
},
"__session_state": "session_state_data"
}
Implementation Details
The authentication begin endpoint:
- Credential Retrieval: Fetches stored credentials from session or storage
- Option Generation: Creates authentication options with appropriate challenges
- State Management: Stores authentication state for session validation
- Error Handling: Returns 404 if no credentials are found for the user
Section sources
/api/authenticate/complete - Authentication Completion
HTTP Method: POST
URL Pattern: /api/authenticate/complete?email={email}
This endpoint completes the authentication process by validating the assertion response and updating credential counters.
Request Parameters
| Parameter | Type | Location | Description |
|---|---|---|---|
email |
string | Query | User email address for authentication |
response |
object | Body | WebAuthn assertion response from authenticator |
__session_state |
object | Body | Session state for validation (optional) |
Request Schema
{
"id": "base64url_encoded_credential_id",
"rawId": "base64url_encoded_credential_id",
"response": {
"authenticatorData": "base64url_encoded_authenticator_data",
"clientDataJSON": "base64url_encoded_client_data",
"signature": "base64url_encoded_signature",
"userHandle": "base64url_encoded_user_handle"
},
"type": "public-key",
"clientExtensionResults": {},
"__session_state": {
"challenge": "base64url_encoded_challenge",
"timeout": 90000,
"rpId": "example.com"
}
}
Response Schema
{
"status": "OK",
"authenticatedCredentialId": "base64url_encoded_credential_id",
"signCount": 123
}
Processing Pipeline
The authentication completion endpoint:
- State Validation: Verifies session state and challenge integrity
- Assertion Verification: Validates the authenticator's signature and data
- Counter Update: Updates the credential's signature counter
- Session Cleanup: Removes authentication state from session
- Success Response: Returns authentication confirmation with updated counter
Section sources
Session Management
The simple authentication flow uses Flask session management for temporary state storage during registration and authentication processes.
Session Data Structure
graph TD
A[Flask Session] --> B[state]
A --> C[simple_credentials]
A --> D[simple_credentials_email]
A --> E[simple_register_public_key]
A --> F[register_rp_id]
A --> G[authenticate_rp_id]
B --> B1[Registration/Authentication State]
C --> C1[Stored Credentials List]
D --> D1[Associated Email]
E --> E1[Registration Public Key Options]
F --> F1[Registration Relying Party ID]
G --> G1[Authentication Relying Party ID]
Diagram sources
Session Lifecycle
The session management follows a strict lifecycle pattern:
-
Registration Phase:
state: Stores registration challenge and optionssimple_register_public_key: Contains public key parametersregister_rp_id: Relying party identifier
-
Authentication Phase:
state: Stores authentication challenge and optionsauthenticate_rp_id: Relying party identifiersimple_credentials: List of stored credentials
-
Cleanup:
- Sessions are automatically cleared after successful completion
- Temporary data is removed to prevent replay attacks
Section sources
Credential Storage
The platform implements a dual-storage system supporting both local filesystem storage and Google Cloud Storage for credential persistence.
Storage Architecture
graph TB
subgraph "Storage Backends"
A[Local Filesystem]
B[Google Cloud Storage]
end
subgraph "Storage Components"
C[Credential Data]
D[Metadata]
E[Session Data]
end
subgraph "Storage Operations"
F[savekey]
G[readkey]
H[delkey]
I[iter_credentials]
end
A --> C
B --> C
A --> D
B --> D
A --> E
B --> E
F --> A
F --> B
G --> A
G --> B
H --> A
H --> B
I --> A
I --> B
Diagram sources
Credential Data Structure
Each stored credential contains comprehensive metadata and cryptographic material:
| Field | Type | Description |
|---|---|---|
credential_data |
object | Attested credential data from authenticator |
auth_data |
object | Authenticator data and flags |
user_info |
object | User identity information |
registration_time |
number | Unix timestamp of registration |
client_data_json |
string | Base64-encoded client data |
attestation_object |
string | Base64-encoded attestation object |
attestation_format |
string | Attestation format type |
attestation_statement |
object | Attestation statement data |
client_extension_outputs |
object | Client extension results |
properties |
object | Additional credential properties |
Storage Operations
The storage system provides atomic operations for credential management:
- Save Operation: Serializes and persists credential data using pickle
- Read Operation: Deserializes stored credential data
- Delete Operation: Removes credential data and associated metadata
- Iterate Operation: Enumerates all stored credentials
Section sources
Frontend Integration
The frontend integration provides seamless WebAuthn API interaction through JavaScript modules that handle the complete authentication flow.
Frontend Architecture
sequenceDiagram
participant UI as "User Interface"
participant JS as "auth-simple.js"
participant WebAuthn as "WebAuthn API"
participant Server as "API Server"
Note over UI,Server : Registration Flow
UI->>JS : simpleRegister()
JS->>Server : POST /api/register/begin
Server-->>JS : Registration Options
JS->>WebAuthn : create(options)
WebAuthn-->>JS : Generated Credential
JS->>Server : POST /api/register/complete
Server-->>JS : Registration Result
JS->>UI : Display Success Message
Note over UI,Server : Authentication Flow
UI->>JS : simpleAuthenticate()
JS->>Server : POST /api/authenticate/begin
Server-->>JS : Authentication Options
JS->>WebAuthn : get(options)
WebAuthn-->>JS : Assertion Response
JS->>Server : POST /api/authenticate/complete
Server-->>JS : Authentication Result
JS->>UI : Display Success Message
Diagram sources
- server/server/static/scripts/simple/auth-simple.js
- server/server/static/scripts/simple/auth-simple.js
Error Handling
The frontend implements comprehensive error handling for various WebAuthn scenarios:
| Error Type | Browser Error | User-Friendly Message |
|---|---|---|
| Cancelled | NotAllowedError |
"User cancelled or authenticator not available" |
| Already Registered | InvalidStateError |
"Authenticator is already registered for this account" |
| Security Issue | SecurityError |
"Security error - check your connection and try again" |
| Not Supported | NotSupportedError |
"WebAuthn is not supported in this browser" |
Local Storage Integration
The frontend maintains a local credential cache using browser localStorage for offline access and improved performance:
- Credential Persistence: Stores generated credentials locally
- Automatic Loading: Loads stored credentials for authentication
- Counter Updates: Updates signature counts after successful authentication
- Cleanup: Provides mechanisms to clear stored credentials
Section sources
- server/server/static/scripts/simple/auth-simple.js
- server/server/static/scripts/simple/auth-simple.js
- server/server/static/scripts/shared/local-storage.js
Security Considerations
The simple authentication flow implements multiple layers of security to protect against common attack vectors and ensure cryptographic integrity.
Input Validation
The backend implements comprehensive input validation:
- Challenge Validation: Ensures challenges are properly formatted and not expired
- Credential ID Validation: Validates credential identifiers and prevents tampering
- Signature Verification: Cryptographically verifies all signatures and attestations
- RP ID Verification: Validates relying party identifiers and hashes
State Management Security
Session state management incorporates several security measures:
- Challenge Binding: Associates challenges with specific sessions
- Timeout Protection: Implements reasonable timeouts for authentication flows
- State Isolation: Prevents cross-session state leakage
- Cleanup Mechanisms: Automatically clears sensitive data after completion
Attestation Security
The platform implements robust attestation verification:
- Certificate Chain Validation: Verifies complete certificate chains
- Root Certificate Trust: Validates against trusted root certificates
- Algorithm Integrity: Ensures cryptographic algorithm consistency
- Metadata Verification: Cross-references with FIDO Metadata Service
Replay Attack Prevention
Multiple mechanisms prevent replay attacks:
- Challenge Uniqueness: Each challenge is unique and single-use
- Timestamp Validation: Validates timestamps and expiration
- Counter Monitoring: Tracks and validates signature counters
- Session Isolation: Maintains separate sessions for different operations
Section sources
Error Handling
The authentication endpoints implement structured error handling with meaningful error messages and appropriate HTTP status codes.
Error Response Patterns
| Endpoint | Error Conditions | HTTP Status | Response Format |
|---|---|---|---|
/api/register/begin |
Invalid email format, malformed credentials | 400 | { "error": "message" } |
/api/register/complete |
Missing session state, invalid attestation | 400 | { "error": "message" } |
/api/authenticate/begin |
No credentials found, invalid email | 404 | { "error": "message" } |
/api/authenticate/complete |
Authentication state expired, invalid signature | 400 | { "error": "message" } |
Error Recovery Strategies
- State Expiration: Clear expired session state automatically
- Retry Mechanisms: Allow retry with fresh challenges
- Graceful Degradation: Provide fallback options for unsupported features
- User Guidance: Offer clear instructions for resolving common errors
Section sources
Examples
Registration Example
Step 1: Begin Registration
curl -X POST "https://example.com/api/register/[email protected]" \
-H "Content-Type: application/json" \
-d '{}'
Response:
{
"publicKey": {
"challenge": "dGVzdF9jaGFsbGVuZ2U=",
"rp": {
"id": "example.com",
"name": "Example RP"
},
"user": {
"id": "dXNlcg==",
"name": "a_user",
"displayName": "A. User"
},
"pubKeyCredParams": [
{
"type": "public-key",
"alg": -49
}
],
"timeout": 90000,
"attestation": "none",
"authenticatorSelection": {
"authenticatorAttachment": "cross-platform",
"requireResidentKey": false,
"userVerification": "discouraged"
}
},
"__session_state": "eyJjaGFsbGVuZ2UiOiAi...",
"status": "OK"
}
Step 2: Complete Registration
curl -X POST "https://example.com/api/register/[email protected]" \
-H "Content-Type: application/json" \
-d '{
"id": "credential_id",
"rawId": "credential_id",
"response": {
"attestationObject": "base64_encoded_attestation",
"clientDataJSON": "base64_encoded_client_data"
},
"type": "public-key",
"__session_state": {
"challenge": "dGVzdF9jaGFsbGVuZ2U="
}
}'
Response:
{
"status": "OK",
"algo": "ML-DSA-65 (PQC)",
"storedCredential": {
"type": "simple",
"email": "[email protected]",
"credentialId": "base64_encoded_id",
"publicKeyAlgorithm": -49,
"signCount": 0,
"createdAt": 1640995200.0
},
"relyingParty": {
"attestationFmt": "packed",
"credentialId": "hex_encoded_id",
"publicKeyAlgorithm": -49
}
}
Authentication Example
Step 1: Begin Authentication
curl -X POST "https://example.com/api/authenticate/[email protected]" \
-H "Content-Type: application/json" \
-d '{
"credentials": [
{
"credentialId": "base64url_encoded_id",
"aaguid": "base64url_encoded_aaguid",
"publicKey": "base64url_encoded_public_key",
"algorithm": -49
}
]
}'
Response:
{
"publicKey": {
"challenge": "dGVzdF9jaGFsbGVuZ2U=",
"rpId": "example.com",
"allowCredentials": [
{
"type": "public-key",
"id": "base64url_encoded_credential_id"
}
],
"timeout": 90000,
"userVerification": "discouraged"
},
"__session_state": "eyJjaGFsbGVuZ2UiOiAi..."
}
Step 2: Complete Authentication
curl -X POST "https://example.com/api/authenticate/[email protected]" \
-H "Content-Type: application/json" \
-d '{
"id": "credential_id",
"rawId": "credential_id",
"response": {
"authenticatorData": "base64_encoded_auth_data",
"clientDataJSON": "base64_encoded_client_data",
"signature": "base64_encoded_signature"
},
"type": "public-key",
"__session_state": {
"challenge": "dGVzdF9jaGFsbGVuZ2U="
}
}'
Response:
{
"status": "OK",
"authenticatedCredentialId": "base64url_encoded_credential_id",
"signCount": 123
}