selected_env vs DB columnStatus: Accepted
Date: 2026-04-28 UTC
Refs: #353, console-env-switcher.md
The console environment switcher requires persisting the operator's current environment context (prod or staging) somewhere. Two candidates:
selected_env directly in the signed cookie payload.console_sessions DB column (server-side session) — store selected_env on the existing session record in Postgres.console_admins DB column — store a per-user default that persists across session boundaries.The console already uses a server-side session model (console_sessions table). The Flask session cookie is a pointer to the session row (session_id), not a self-contained JWT.
Store selected_env on console_sessions (option 2). Do not add a column to console_admins.
Migration: ALTER TABLE console_sessions ADD COLUMN selected_env TEXT NOT NULL DEFAULT 'prod'.
The default value when unset is read from CONSOLE_DEFAULT_ENV env var at session creation time; the column default is 'prod' for existing sessions.
Positive:
- Env selection is session-scoped, not user-scoped. An operator returning after session expiry must consciously re-select their env context. This is safer: no silently-resumed prod context from a session opened days ago.
- Audit log joins work cleanly: console_audit_log.context.selected_env can be cross-referenced against console_sessions.selected_env for the same session_id.
- Server-side sessions already exist; adding one column is a zero-risk additive migration.
- Multi-tab behavior is predictable: same session_id across tabs shares selected_env. Tab 2 switching env affects tab 1 on next navigation (not silently mid-flight, because actions capture the env at POST time via _target_env hidden field).
Negative:
- No cross-session persistence. An operator who always works in staging must switch every new session. Mitigated by CONSOLE_DEFAULT_ENV env var allowing a deployment-level default.
- Multi-tab shared env is a design constraint, not a feature. Documented in open question #1 of the design doc.
Would not require a DB migration. However, the console's session is already server-side (cookie is a session_id, not a payload). Embedding selected_env in the cookie would split state between cookie and DB row, which creates inconsistency risk if the DB session row is modified server-side (e.g., forced revocation). Rejected for consistency reasons.
console_admins.default_env columnWould persist across sessions. Advantage: operators who always use staging don't re-switch every login. Disadvantage: a prod mutation on day 2 could be silently executed in the "last used context" without the operator noticing the banner. The failure mode (unintended prod mutation due to forgotten persistent state) is worse than the inconvenience of re-switching. Rejected as unsafe default.
This option is not precluded by this decision. A future per-user default column could be added and read at session creation time to set selected_env without affecting the mutation-time behavior.