diff --git a/services/flask-backend/app/__init__.py b/services/flask-backend/app/__init__.py index 1587bf41..17140260 100644 --- a/services/flask-backend/app/__init__.py +++ b/services/flask-backend/app/__init__.py @@ -38,6 +38,9 @@ def create_app(config_class: type | None = None) -> Quart: Returns: Configured Quart application instance + + Raises: + ValueError: If production config validation fails (missing or invalid secrets) """ app = Quart(__name__) @@ -46,6 +49,10 @@ def create_app(config_class: type | None = None) -> Quart: config_class = get_config() app.config.from_object(config_class) + # Validate configuration (production only) + if hasattr(config_class, "validate"): + config_class.validate() + # Setup logging _setup_logging(app) diff --git a/services/flask-backend/app/config.py b/services/flask-backend/app/config.py index 323de924..cf865bcd 100644 --- a/services/flask-backend/app/config.py +++ b/services/flask-backend/app/config.py @@ -177,6 +177,7 @@ class ProductionConfig(Config): # Strict security in production SECURITY_PASSWORD_SALT = os.getenv("SECURITY_PASSWORD_SALT") # Required SECRET_KEY = os.getenv("SECRET_KEY") # Required + JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY") # Required — must not fall back to dev default @classmethod def validate(cls) -> None: @@ -188,6 +189,11 @@ def validate(cls) -> None: raise ValueError("SECRET_KEY must be set in production") if not cls.SECURITY_PASSWORD_SALT or "change" in cls.SECURITY_PASSWORD_SALT: raise ValueError("SECURITY_PASSWORD_SALT must be set in production") + if ( + not cls.JWT_SECRET_KEY + or cls.JWT_SECRET_KEY == "dev-secret-key-change-in-production" + ): + raise ValueError("JWT_SECRET_KEY must be set in production") class TestingConfig(Config):