Table of Contents
- Configuration Errors
- Table of Contents
- Introduction
- Environment Variable Configuration
- Secret Key Management
- RP Entity Configuration
- TLS Certificate Issues
- MDS Metadata Configuration
- Cloud Deployment Configuration
- Debugging Configuration Loading
- Common Misconfigurations
- Environment Variable Misconfigurations
- Issue 1: Incorrect RP ID Format
- Issue 2: Secret Key Encoding Problems
- Issue 3: Missing Trusted CA Configuration
- Deployment Configuration Issues
- Issue 1: Render.yaml Configuration
- Issue 2: Cloud Build Pipeline
- Issue 3: Docker Environment Variables
- RP Entity Configuration Problems
- Troubleshooting Guide
Configuration Errors
Table of Contents
- Introduction
- Environment Variable Configuration
- Secret Key Management
- RP Entity Configuration
- TLS Certificate Issues
- MDS Metadata Configuration
- Cloud Deployment Configuration
- Debugging Configuration Loading
- Common Misconfigurations
- Troubleshooting Guide
Introduction
The Post-Quantum WebAuthn Platform relies on a sophisticated configuration system that manages environment variables, secret keys, RP entity settings, and TLS certificates. Configuration errors can prevent the platform from starting correctly or compromise security. This document covers common configuration issues, their symptoms, and resolution strategies.
Environment Variable Configuration
Core Environment Variables
The platform uses several critical environment variables for operation:
| Variable | Purpose | Default Value | Validation Required |
|---|---|---|---|
FIDO_SERVER_SECRET_KEY |
Flask session secret | Generated randomly | Must be securely stored |
FIDO_SERVER_SECRET_KEY_FILE |
Path to secret key file | None | File must be readable |
FIDO_SERVER_RP_ID |
Relying Party Identifier | Request host | Must be valid domain |
FIDO_SERVER_RP_NAME |
Relying Party Name | "Demo server" | Human-readable name |
FIDO_SERVER_SESSION_METADATA_RECOVER |
Session recovery flag | None | Boolean values |
Environment Variable Resolution Order
The configuration system follows a specific priority order for resolving environment variables:
flowchart TD
A["Environment Variable Check"] --> B{"Variable Set?"}
B --> |Yes| C["Use Environment Value"]
B --> |No| D["Check Alternative Path"]
D --> E{"Alternative Path Set?"}
E --> |Yes| F["Attempt File Read"]
E --> |No| G["Use Default Value"]
F --> H{"File Read Successful?"}
H --> |Yes| I["Use File Content"]
H --> |No| J["Log Warning & Continue"]
C --> K["Configuration Complete"]
I --> K
G --> K
J --> K
Diagram sources
Section sources
Secret Key Management
Secret Key Generation and Storage
The platform implements a robust secret key management system that handles multiple storage mechanisms:
Key Storage Mechanisms
- Environment Variable: Direct string value
- File-based Storage: Secure file containing key bytes
- Automatic Generation: Random 32-byte key generation
- Persistent Storage: Automatic key persistence to disk
Secret Key Resolution Process
sequenceDiagram
participant App as Application
participant Config as Config Module
participant Env as Environment
participant FS as File System
participant Gen as Key Generator
App->>Config : _resolve_secret_key()
Config->>Env : os.environ.get("FIDO_SERVER_SECRET_KEY")
Env-->>Config : secret_key_value
alt secret_key_value exists
Config->>Config : Encode UTF-8
else secret_key_value missing
Config->>Env : os.environ.get("FIDO_SERVER_SECRET_KEY_FILE")
Env-->>Config : file_path
alt file_path exists
Config->>FS : Open file_path
FS-->>Config : file_content
alt file_content valid
Config->>Config : Use file_content
else file_content invalid
Config->>Config : Log warning & continue
end
else file_path missing
Config->>Gen : os.urandom(32)
Gen-->>Config : random_bytes
Config->>FS : Store to default_path
FS-->>Config : Success/Failure
end
end
Config-->>App : Final secret key bytes
Diagram sources
Common Secret Key Issues
Issue 1: Missing Secret Key
Symptoms: Flask session errors, CSRF validation failures
Cause: No secret key configured in any storage mechanism
Solution: Set FIDO_SERVER_SECRET_KEY or FIDO_SERVER_SECRET_KEY_FILE
Issue 2: File Permission Errors
Symptoms: "Unable to read secret key file" warnings in logs Cause: Insufficient file permissions or non-existent file Solution: Verify file existence and permissions
Issue 3: Corrupted Key Files
Symptoms: Application fails to start with key-related errors Cause: Truncated or corrupted key files Solution: Delete corrupted files and let system regenerate
Section sources
RP Entity Configuration
RP ID Resolution Logic
The platform implements intelligent RP ID resolution with multiple fallback mechanisms:
flowchart TD
A["determine_rp_id()"] --> B{"Explicit ID Provided?"}
B --> |Yes| C["Return Explicit ID"]
B --> |No| D{"Configured RP_ID?"}
D --> |Yes| E["Return Configured ID"]
D --> |No| F{"Request Context Available?"}
F --> |Yes| G["Extract Host from Request"]
F --> |No| H["Return 'localhost'"]
G --> I{"Host is Localhost?"}
I --> |Yes| J["Return 'localhost'"]
I --> |No| K["Return Host"]
C --> L["Build RP Entity"]
E --> L
J --> L
K --> L
H --> L
Diagram sources
RP Entity Validation
Common RP Configuration Issues
| Issue | Symptom | Cause | Solution |
|---|---|---|---|
| Invalid RP ID | Authentication failures | Malformed domain name | Use valid domain format |
| Missing RP Name | Default "Demo server" | Unset FIDO_SERVER_RP_NAME |
Set appropriate name |
| Host Resolution Failure | RP ID defaults to localhost | No request context | Ensure proper host header |
| Case Sensitivity | RP ID mismatches | Different hostname casing | Normalize to lowercase |
RP Entity Construction
The build_rp_entity() function creates the relying party entity with proper validation:
classDiagram
class PublicKeyCredentialRpEntity {
+string name
+string id
+validate_rp_id() bool
+normalize_host() string
}
class ConfigModule {
+build_rp_entity() PublicKeyCredentialRpEntity
+determine_rp_id() string
+create_fido_server() Fido2Server
}
class FlaskRequest {
+string host
+has_request_context() bool
}
ConfigModule --> PublicKeyCredentialRpEntity : creates
ConfigModule --> FlaskRequest : uses
PublicKeyCredentialRpEntity --> ConfigModule : validated by
Diagram sources
Section sources
TLS Certificate Issues
Trusted CA Configuration
The platform supports multiple methods for configuring trusted certificate authorities:
Subject-Based Trust Configuration
flowchart TD
A["Parse Trusted CA Subjects"] --> B["Split by Delimiters"]
B --> C["Normalize Components"]
C --> D{"Empty Components?"}
D --> |Yes| E["Remove Empty"]
D --> |No| F["Validate Subjects"]
E --> F
F --> G{"Valid Subjects?"}
G --> |Yes| H["Store in Config"]
G --> |No| I["Return None"]
H --> J["Trusted CA Subjects Ready"]
I --> J
Diagram sources
Fingerprint-Based Trust Configuration
The platform supports SHA-256 fingerprint validation for certificate trust:
| Requirement | Value | Purpose |
|---|---|---|
| Minimum Length | 40 hexadecimal characters | Prevent trivial matches |
| Format | Uppercase hex | Consistent comparison |
| Validation | SHA-256 hash | Cryptographic verification |
TLS Trust Anchor Configuration
The platform includes built-in trust anchors for metadata downloads:
graph TB
subgraph "Built-in Trust Anchors"
A["ISRG Root X1<br/>SHA-256: 29:19:FF:..."]
B["DigiCert Global Root G2<br/>SHA-256: 40:3D:..."]
C["Baltimore CyberTrust Root<br/>SHA-256: 7D:28:..."]
end
subgraph "Additional Trust Anchors"
D["Custom CA Certificates"]
E["Environment-Specific CAs"]
end
A --> F["TLS Verification Chain"]
B --> F
C --> F
D --> F
E --> F
Diagram sources
Common TLS Issues
Issue 1: MDS Download Failures
Symptoms: Metadata download timeouts, SSL certificate errors Cause: Outdated or missing trust anchors Solution: Update trust anchor configuration or network connectivity
Issue 2: Custom CA Certificate Problems
Symptoms: Certificate verification failures Cause: Incorrect CA certificate format or expired certificates Solution: Verify certificate format and expiration dates
Section sources
MDS Metadata Configuration
Metadata URL Resolution
The platform uses the FIDO Alliance Metadata Service (MDS) for authenticator information:
MDS Configuration Constants
| Constant | Value | Purpose |
|---|---|---|
MDS_METADATA_URL |
https://mds3.fidoalliance.org/ |
Primary MDS endpoint |
MDS_METADATA_FILENAME |
blob.jwt |
Metadata blob filename |
MDS_METADATA_PATH |
static/blob.jwt |
Local metadata path |
MDS_METADATA_VERIFIED_PATH |
static/fido-mds3.verified.json |
Verified metadata path |
Metadata Loading Process
sequenceDiagram
participant App as Application
participant Startup as Startup Module
participant Metadata as Metadata Module
participant Network as Network Layer
participant Cache as Cache System
App->>Startup : warm_up_dependencies()
Startup->>Metadata : ensure_metadata_bootstrapped()
Metadata->>Network : download_metadata_blob()
Network-->>Metadata : JWT blob or cached data
alt New metadata available
Metadata->>Metadata : Verify signature
Metadata->>Cache : Store verified metadata
Cache-->>Metadata : Success
else Cached metadata valid
Metadata->>Metadata : Load from cache
end
Metadata-->>Startup : Metadata ready
Startup-->>App : Dependencies warmed
Diagram sources
Metadata Trust Verification
The platform implements cryptographic verification of metadata sources:
flowchart TD
A["Metadata Download"] --> B["Verify Signature"]
B --> C{"Signature Valid?"}
C --> |Yes| D["Mark as Trusted"]
C --> |No| E["Mark as Untrusted"]
D --> F["Store in Base Metadata"]
E --> G["Use Fallback"]
F --> H["Ready for Use"]
G --> H
Diagram sources
Section sources
Cloud Deployment Configuration
Render Platform Configuration
The Render deployment configuration defines basic service settings:
Render.yaml Structure
| Setting | Value | Purpose |
|---|---|---|
| Type | web |
Web service type |
| Runtime | docker |
Containerized deployment |
| Plan | free |
Free tier deployment |
| Auto Deploy | true |
Automatic deployments |
| Dockerfile | ./Dockerfile |
Container definition |
Google Cloud Build Configuration
The Cloud Build pipeline automates deployment to Google Cloud Run:
Key Deployment Settings
| Parameter | Value | Impact |
|---|---|---|
| CPU | 0.5 |
Resource allocation |
| Memory | 512Mi |
Memory allocation |
| Port | 8080 |
Container port |
| Min Instances | 0 |
Auto-scaling minimum |
| Max Instances | 3 |
Auto-scaling maximum |
Container Environment Variables
The Docker container exposes several environment variables:
Essential Container Variables
| Variable | Purpose | Default |
|---|---|---|
PORT |
Container port | 8000 |
LD_LIBRARY_PATH |
Library paths | /opt/liboqs/lib:/usr/local/lib |
PYTHONPATH |
Python module path | /app |
Section sources
Debugging Configuration Loading
Logging Configuration
The platform implements comprehensive logging for configuration debugging:
Key Logger Locations
graph TB
subgraph "Logging Sources"
A["config.py - Secret Key Operations"]
B["startup.py - Dependency Checks"]
C["metadata.py - Metadata Downloads"]
D["app.py - Application Startup"]
end
subgraph "Log Levels"
E["INFO - Startup Messages"]
F["WARNING - Configuration Warnings"]
G["DEBUG - Detailed Operations"]
H["ERROR - Critical Failures"]
end
A --> F
B --> E
C --> G
D --> E
Diagram sources
Configuration Debugging Commands
Environment Variable Inspection
To debug environment variable issues, use these commands:
# Check all FIDO_SERVER variables
env | grep FIDO_SERVER
# Verify secret key file permissions
ls -la $FIDO_SERVER_SECRET_KEY_FILE
# Test RP ID resolution
python -c "from server.server.config import determine_rp_id; print(determine_rp_id())"
Configuration Validation Script
# Configuration validation script
from server.server.config import app, determine_rp_id, build_rp_entity
print("=== Configuration Validation ===")
print(f"Secret Key: {'Set' if app.secret_key else 'Not Set'}")
print(f"RP ID: {app.config.get('FIDO_SERVER_RP_ID')}")
print(f"RP Name: {app.config.get('FIDO_SERVER_RP_NAME')}")
print(f"Session Recovery: {app.config.get('SESSION_METADATA_RECOVER_ON_START')}")
# Test RP entity creation
try:
rp = build_rp_entity()
print(f"RP Entity: {rp.id} - {rp.name}")
except Exception as e:
print(f"RP Entity Error: {e}")
# Test RP ID resolution
try:
rp_id = determine_rp_id()
print(f"Resolved RP ID: {rp_id}")
except Exception as e:
print(f"RP ID Resolution Error: {e}")
Section sources
Common Misconfigurations
Environment Variable Misconfigurations
Issue 1: Incorrect RP ID Format
Problem: RP ID contains invalid characters or malformed domains
Example: http://example.com instead of example.com
Solution: Remove protocol prefixes and ensure valid domain format
Issue 2: Secret Key Encoding Problems
Problem: Secret key contains special characters or improper encoding Example: Non-UTF-8 characters in secret key Solution: Use base64-encoded secrets or ensure proper UTF-8 encoding
Issue 3: Missing Trusted CA Configuration
Problem: Custom CA certificates not properly configured Example: Incorrect subject DN format Solution: Use proper RFC 2253 DN format for subjects
Deployment Configuration Issues
Issue 1: Render.yaml Configuration
Problem: Incorrect service type or runtime specification
Example: Using python runtime instead of docker
Solution: Verify Render platform requirements
Issue 2: Cloud Build Pipeline
Problem: Incorrect image tagging or deployment parameters Example: Using wrong project ID or region Solution: Validate Cloud Build configuration against project settings
Issue 3: Docker Environment Variables
Problem: Missing essential environment variables in container Example: PORT not set or LD_LIBRARY_PATH incorrect Solution: Review Dockerfile environment variable declarations
RP Entity Configuration Problems
Issue 1: Host Header Resolution
Problem: RP ID resolves to localhost in production Example: Missing Host header or proxy configuration Solution: Configure proper reverse proxy or set explicit RP_ID
Issue 2: Session Metadata Recovery
Problem: Session data lost on restart Example: Missing SESSION_METADATA_RECOVER flag Solution: Set appropriate recovery flag for deployment environment
Section sources
Troubleshooting Guide
Diagnostic Checklist
Pre-Deployment Checks
-
Environment Variables
FIDO_SERVER_SECRET_KEYorFIDO_SERVER_SECRET_KEY_FILEsetFIDO_SERVER_RP_IDproperly configuredFIDO_SERVER_RP_NAMEset appropriately
-
File Permissions
- Secret key file readable by application user
- Metadata directories writable
- Log directories accessible
-
Network Connectivity
- MDS metadata endpoint reachable
- Custom CA certificates accessible
- Reverse proxy configured correctly
Runtime Diagnostics
-
Application Logs
# Check application startup logs docker logs <container_id> # Monitor real-time logs docker logs -f <container_id> -
Configuration Validation
# Test configuration loading python -c "from server.server.config import app; print(app.config)" # Verify secret key generation python -c "from server.server.config import _resolve_secret_key; print(len(_resolve_secret_key()))" -
RP Entity Testing
# Test RP ID resolution curl -H "Host: example.com" http://localhost:5000/_health # Verify RP entity construction python -c "from server.server.config import build_rp_entity; rp = build_rp_entity(); print(rp.id, rp.name)"
Common Error Patterns
Configuration Loading Failures
Error Pattern: "Unable to read secret key file" warnings Diagnosis: Check file existence, permissions, and encoding Resolution: Fix file permissions or regenerate secret key
RP ID Resolution Issues
Error Pattern: RP ID resolves to localhost unexpectedly Diagnosis: Verify request context and host header Resolution: Configure reverse proxy or set explicit RP_ID
Metadata Download Failures
Error Pattern: MDS metadata download timeouts Diagnosis: Check network connectivity and firewall rules Resolution: Update trust anchors or configure proxy settings
Performance Optimization
Configuration Caching
The platform implements several caching mechanisms:
- Metadata Cache: Local storage of verified metadata
- Session Metadata: Persistent session state
- Secret Key Cache: Temporary storage of generated keys
Monitoring Configuration Health
# Configuration health check script
import logging
from server.server.config import app, determine_rp_id, build_rp_entity
def check_configuration_health():
"""Perform comprehensive configuration health check."""
logger = logging.getLogger(__name__)
# Check secret key
if not app.secret_key:
logger.error("Secret key not configured")
return False
# Check RP configuration
try:
rp_id = determine_rp_id()
if rp_id == "localhost":
logger.warning("RP ID resolves to localhost")
except Exception as e:
logger.error(f"RP ID resolution failed: {e}")
return False
# Check metadata availability
try:
from server.server.metadata import ensure_metadata_bootstrapped
ensure_metadata_bootstrapped()
except Exception as e:
logger.error(f"Metadata bootstrap failed: {e}")
return False
logger.info("Configuration health check passed")
return True
if __name__ == "__main__":
check_configuration_health()
Section sources