Repository navigation
RV-S4: stop the migration image baking local credentials (#174) - #204
Merged
Merged
Conversation
build/config.local.env (written by build/setup.sh) and the concrete build/environments/env_<env>.sql files hold real credentials. Both are gitignored, but .gitignore does not filter the Docker build context, so `docker build .` from a configured checkout copied them into an image layer. Layers are immutable and cached indefinitely: once pushed to a registry, rotating the leaked password is the only remediation. Two independent layers now stop that, per the 3 Nov decision: - .dockerignore lists both shapes, mirroring .gitignore lines 2-8, and re-includes build/environments/*.example.sql, which the image needs. - infra/Dockerfile replaces `COPY build/ ./build/` with an explicit source list, so nothing under build/ reaches the image unless a COPY names it. This is the layer that still holds when someone adds a new config file under build/. tests/test_docker_image_secrets.py enforces both with no Docker daemon: it synthesises the credential files, expands the Dockerfile's COPY sources as Docker would, and asserts none is reachable - while asserting the templates, deploy_all.sh and te_core_schema.sql still are. Both layers fail against main's Dockerfile/.dockerignore and pass with this change. Side effect: build/terraform-github-repos/ is no longer copied. It is Terraform for GitHub repository management, not needed by the runner. Build context under build/ drops from 49 files to 38. Does not change what the image can do: the deploy, load and evals actions keep every file they read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6WqjTEDRRQGLEYPPFVXx
This was referenced Nov 9, 2026
amar-python
marked this pull request as ready for review
November 10, 2026 06:38
amar-python
pushed a commit
that referenced
this pull request
Nov 10, 2026
#231 and #232 both added the three M5 log steps, so main lists version, schema_check and cross_upload_duplicates twice. zod collapses duplicate enum values, so it is harmless at runtime, but the duplicates were an accident. Remove them and add a test that reads the source (the parsed schema can't show them); it fails with a duplicate present. docs/ISSUE_TESTS.md: #174 is done on main (#204). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6Wqi8yaiaYWUVH8C4QAY
amar-python
pushed a commit
that referenced
this pull request
Nov 10, 2026
main (#224) regenerated docs/TEST_CASES.md after #204 merged, which cleared the red free-tier job this branch was opened to fix. What remains is the file move. The catalogue conflict is the only one; it is generated and gated by `test_catalogue.py --check`, so it is regenerated, not merged by hand. Free tier on the merged tree: 282 passed, 0 failed, 0 skipped; lint, health and the catalogue check clean. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T6WqjTEDRRQGLEYPPFVXx
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.
Closes #174.
What this changes
build/config.local.env(written bybuild/setup.shandscripts/provision_full_test_env.sh) and the concretebuild/environments/env_<env>.sqlfiles hold real credentials. Both are gitignored — but.gitignoredoes not filter the Docker build context, sodocker build .from a configured checkout copied them into an image layer. Layers are immutable and cached indefinitely; once such a layer is pushed to a registry, rotating the leaked password is the only remediation, and only if somebody notices.Both fixes from the 3 Nov decision, in one PR, defence in depth:
.dockerignore— lists**/config.local.env,**/config.local.env.*,**/*.local.envand the four concretebuild/environments/env_<env>.sqlfiles, mirroring.gitignorelines 2–8, and re-includesbuild/environments/*.example.sqlwhich the image needs.infra/Dockerfile—COPY build/ ./build/replaced with an explicit source list. Nothing underbuild/reaches the image unless aCOPYnames it. This is the layer that still holds when someone adds a new config file underbuild/without reading this PR.infra/README.mdis new and documents why (item 3 of the issue), alongside a short map of what is ininfra/.Verification
No Docker daemon was available in the session this ran in, so this uses the fallback the issue explicitly allows: comparing the Dockerfile's build-context file list before and after.
tests/test_docker_image_secrets.pydoes that statically — it synthesises the credential files (as the issue's verification step describes), expands the Dockerfile'sCOPYsources the way Docker would, and asserts none of them is reachable.Fails on
main's Dockerfile/.dockerignore, passes with the fix — both layers, independently:Build context under
build/, before vs after, with synthetic secrets present:All six credential-bearing files gone.
build/terraform-github-repos/also drops out — it is Terraform for GitHub repository management, which the runner never reads, so this is an image-size win rather than a functional change.No loss of function.
test_templates_are_still_copiedassertsenv_dev.example.sql,env_prod.example.sql,build/deploy_all.shandbuild/te_core_schema.sqlare all still in the image, so thedeploy,loadandevalsactions keep every file they read. Adocker runsmoke test could not be executed without a daemon — flagging that as the one piece of the issue's "Done when" not evidenced here.CI replica (free-tier job)
The integration job needs a PostgreSQL service that was not available here; the free-tier job was run in full.
Note for #172
Per the issue, the RV-S1 fix must not reintroduce this exposure by committing a populated
env_prod.sqlto the image. The explicitCOPYlist makes that harder by construction:build/environments/*.example.sqlis the only pattern reachingbuild/environments/in the image, so a concreteenv_prod.sqlcannot arrive there without deliberately editing aCOPYline. #172 should therefore generate it at runtime.Generated by Claude Code