Flask SECRET_KEY: Temporary key in development invalidates production sessions
0 reputation · 04 Jan 2020, 10:09 UTC
0 reputation · 04 Jan 2020, 10:09 UTC
When a Flask application starts without an explicit app.config['SECRET_KEY'], the framework falls back to generating a random key for each request. Locally this allows sessions to appear to persist, but the key changes on every reload, causing signed cookies to become invalid. In a production deployment, the same automatic key generation leads to authentication failures or lost session data, breaking features that rely on Flask-Login, Flask-Session, or other signed‑cookie mechanisms.
The core issue is the lack of a required configuration boundary: developers can run an app locally without a key, yet production environments must supply a secure, stable secret. This ambiguity creates an unresolved decision point in Flask’s design.
Key questions for architects and developers:
SECRET_KEY at startup, or is the current optional behavior acceptable?34775 reputation · 04 Jan 2020, 17:22 UTC
When a Flask app starts without an explicit app.config['SECRET_KEY'], Flask generates a random key for each request. In development this makes it look like sessions persist, but the key changes on every reload, breaking signed‑cookie sessions. In production, that same auto‑generation causes authentication failures and loss of session data for extensions that rely on signed cookies.
SECRET_KEY.import os
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
app.config.from_pyfile.
SESSION_COOKIE_NAME and any required backend configuration.How are you currently providing the secret key to your production environment—via an environment variable, a config file, or a secrets manager?
Use comments to ask for clarification. Post a solution as an answer.
6,520 reputation · 04 Jan 2020, 17:00 UTC
One clarification worth adding: in standard Flask, an unset SECRET_KEY does not produce a fresh per-request key. Accessing session inside a request raises a RuntimeError about the missing secret key, so the "sessions appear to persist locally" symptom usually points somewhere else.
The more common cause of restart-to-restart invalidation is a key generated at import time, for example secrets.token_hex() or os.urandom(24) assigned in module scope, or an ephemeral environment variable that differs per deployment. Both stay stable within a process and change on restart.
Verification: log only whether app.config['SECRET_KEY'] is set, never its value. On Flask 2.3 and later, SECRET_KEY_FALLBACKS lets old keys verify existing cookies during rotation; earlier releases invalidate every signed cookie the moment the key changes. Confirm the behavior against your installed version before relying on it.