Skip to content

SECRET_KEY rotation: DJANGO_SECRET_KEY / DJANGO_SECRET_KEY_FALLBACKS wiring (#38 follow-up) - #40

Merged
man4ish merged 1 commit into
mainfrom
fix/secret-key-rotation-38
Aug 11, 2026
Merged

SECRET_KEY rotation: DJANGO_SECRET_KEY / DJANGO_SECRET_KEY_FALLBACKS wiring (#38 follow-up)#40
man4ish merged 1 commit into
mainfrom
fix/secret-key-rotation-38

Conversation

@man4ish

@man4ish man4ish commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Security-critical -- companion to omnibioai-workbench#207

Compose-side half of the SECRET_KEY rotation. See omnibioai-workbench#207 for the settings.py change (env-driven SECRET_KEY, SECRET_KEY_FALLBACKS, hard-fail guard) and the full rationale/verification writeup.

What

       DJANGO_DEBUG: "false"
+      DJANGO_SECRET_KEY: ${WORKBENCH_DJANGO_SECRET_KEY}
+      DJANGO_SECRET_KEY_FALLBACKS: ${WORKBENCH_DJANGO_SECRET_KEY_FALLBACKS:-}

for both workbench and celery-worker. Real values are in this repo's .env (gitignored -- confirmed via git check-ignore -v .env, not committed here or anywhere):

WORKBENCH_DJANGO_SECRET_KEY=<newly generated via Django's get_random_secret_key()>
WORKBENCH_DJANGO_SECRET_KEY_FALLBACKS=<the old, potentially-exposed literal>

WORKBENCH_-prefixed specifically so it can't collide with LIMSX_DJANGO_SECRET_KEY, lims's own equivalent already sitting in this same shared .env.

Real bug caught during verification

The generated key contains a $ sequence. Docker Compose silently re-interpolated it out of the .env-sourced value on first attempt -- 8 characters dropped, with only a warning (The "g98u77" variable is not set. Defaulting to a blank string.) as the tell. Caught by explicitly checking the byte-for-byte live value in the container rather than trusting the deploy succeeded quietly. Fixed with $$ escaping in .env (standard Compose escaping for a literal $), then re-verified exact match.

14-day bake period

Before WORKBENCH_DJANGO_SECRET_KEY_FALLBACKS (here) and the SECRET_KEY_FALLBACKS entry it feeds (omnibioai-workbench#207) get dropped. Matches Django's own SESSION_COOKIE_AGE default so no legitimate session gets cut off early. End date + drop-the-fallback follow-up posted as a comment on #38.

Verified live

Rebuilt + recreated both containers from this branch + omnibioai-workbench#207 together. Confirmed exact key value landed correctly post-$$-fix, and confirmed a real pre-rotation session (via get_session_auth_hash()) kept authenticating after rotation -- via the fallback, with Django transparently re-signing it under the new key on that validated use (inspected the session table directly to confirm, not just a 200). Hard-fail guard tested in isolation.

Requesting fast review

Same urgency tier as #39 -- flagging directly for review ahead of the normal queue.

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

…ch + celery-worker

Companion to omnibioai-workbench#207, which wires settings.py's SECRET_KEY
off these env vars (with a hard-fail guard if DJANGO_DEBUG=false and no
real key is set). Real values live in this repo's .env (gitignored,
confirmed via git check-ignore -- not committed here or anywhere).

New .env vars (not part of this diff, .env is gitignored):
  WORKBENCH_DJANGO_SECRET_KEY=<newly generated via Django's own
    get_random_secret_key()>
  WORKBENCH_DJANGO_SECRET_KEY_FALLBACKS=<the old, potentially-exposed
    literal that used to be hardcoded in settings.py>

14-day bake period before WORKBENCH_DJANGO_SECRET_KEY_FALLBACKS (here)
and the settings.py SECRET_KEY_FALLBACKS entry it feeds are dropped --
end date tracked on #38.

Verified live: rebuilt + recreated both containers, confirmed the exact
byte-for-byte key value landed in the container (caught and fixed a
real Compose $-interpolation bug along the way -- see companion PR),
and confirmed a pre-rotation session kept authenticating post-rotation
via the fallback rather than being force-logged-out.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@man4ish
man4ish merged commit e59e533 into main Aug 11, 2026
7 checks passed
@man4ish
man4ish deleted the fix/secret-key-rotation-38 branch August 11, 2026 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant