security(lims): fix DJANGO_DEBUG drift in docker-compose-release.yml - #46
Merged
Merged
Conversation
The dash-named release compose file still shipped DJANGO_DEBUG: "true" for lims, with FIELD_ENCRYPTION_KEY entirely absent -- both missed by 951ad25, which fixed docker-compose.release.yml (the file electron-builder actually bundles) and docker-compose.yml (dev) but not this one. lab_data_manager/settings.py reads DJANGO_DEBUG directly from the environment with no override anywhere in the image (confirmed via Dockerfile/entrypoint/supervisord), so this was a live, effective drift, not dead configuration. Not reachable through the packaged Electron app's startup path (electron/main.js never resolves to the dash file) -- this closes a parity gap in a file SECURITY-COMPOSE-HARDENING.md already documents as "kept in parity," not a live exposure in the shipped installer. Fixed to match the dot file exactly (DJANGO_DEBUG: "false" + FIELD_ENCRYPTION_KEY sourced from LIMSX_FIELD_ENCRYPTION_KEY, the same convention DJANGO_SECRET_KEY already uses) rather than inventing a new mechanism. Adds tests/test_lims_debug_config.py, parametrized over both release files plus the dev compose as the parity source of truth, so this specific drift -- and the crash-loop that flipping DEBUG alone without FIELD_ENCRYPTION_KEY would cause -- can't silently reappear. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to PR #44/#45 (HIPAA Studio compose hardening audit) — closes the
limsDEBUG drift flagged during that audit and deliberately left out at the time.Finding:
docker-compose-release.yml(dash-named) still shippedDJANGO_DEBUG: "true"for thelimsservice, withFIELD_ENCRYPTION_KEYentirely absent.Proof of effectiveness (not just presence):
omnibioai-lims/lab_data_manager/settings.py:29readsDJANGO_DEBUGdirectly from the environment (env.bool("DJANGO_DEBUG", ...)) with no override.Dockerfile's persistentENVlayer deliberately omitsDJANGO_DEBUG(comment: "Never set it to true in the persistent ENV layer") — the only place the image sets it is a transientRUN DJANGO_DEBUG=true ... collectstaticbuild-time step, which does not affect the runtime container.DEBUGvalue. This was a live, effective drift, not dead configuration.Root cause: commit
951ad25("disable prod DEBUG, wire up FIELD_ENCRYPTION_KEY") fixeddocker-compose.release.yml(dot) anddocker-compose.yml(dev) but missed the dash file.Deployment-path scoping — why this isn't a live exposure in the shipped installer:
electron-builder.jsonandelectron/main.js'sgetComposeFilePath()only ever referencedocker-compose.release.yml(dot) ordocker-compose.yml(dev) — never the dash file. Confirmed by direct inspection, not inference.SECURITY-COMPOSE-HARDENING.md§6 already documentsdocker-compose-release.ymlas "not the shipped artifact... kept in [credential/exposure] parity" with the dot file — this PR closes exactly that parity gap..github/workflows/disabled/release.yml) lives outside.github/workflows/'s auto-discovered root and is not referenced by any active workflow — GitHub Actions does not run it.Fix: minimal, matches the already-established convention exactly (same pairing the dot-file fix already uses) rather than inventing anything new:
FIELD_ENCRYPTION_KEYis required alongside the DEBUG flip:settings.pyraisesRuntimeError("FIELD_ENCRYPTION_KEY must be set in non-debug environments")onceDEBUG=False, so flipping DEBUG alone (without wiring the key) would have crash-looped the container. Verified viadocker compose configwith dummy secrets — resolves cleanly,DJANGO_DEBUG: "false"andFIELD_ENCRYPTION_KEYinterpolate correctly.Out of scope (per audit brief, not touched): HOST_IP bindings, LIMS auth/tenant isolation, other services' credentials, the broader HOST_IP architecture question.
Test plan
tests/test_lims_debug_config.py, parametrized over both release compose files + the dev compose as parity source of truth (mirrorstest_compose_release_config.py's approach to the JWT-secret drift between the same two files).git stash+ rerun) — bothDJANGO_DEBUGandFIELD_ENCRYPTION_KEYassertions catch the original bug.docker compose --env-file <dummy-secrets> -f docker-compose-release.yml configresolves cleanly;limsblock showsDJANGO_DEBUG: "false"andFIELD_ENCRYPTION_KEYinterpolated.origin/main(d809a0a) and this branch: identical 51 failed + 22 errored IDs on both (pre-existing, unrelated — require live services). This branch adds 178 passed vs. baseline's 173 passed (+5 = the new test file), zero regressions.SECURITY-COMPOSE-HARDENING.md§7 updated with a dated remediation note (matching the existing control-center follow-up entry's style) recording the drift, the proof it was effective, and why it's not a shipped-installer exposure.🤖 Generated with Claude Code