Three places secrets leak, and only one gets mentioned
"Do not commit secrets to git" is advice everybody knows, and it covers exactly one of three places. The other two leak secrets to more people and get checked by fewer.
| Place | Who can read it | Why it goes unchecked |
|---|---|---|
| Git history | Anybody who can clone | Known about, but people check the current files, not the history |
| CI environment variables | Anybody who can edit the pipeline, plus every log of every run | It looks like the correct practice |
| The container image | Anybody who can pull it, internal registry included | ENV and deleted layers persist in the image |
The second deserves attention because it is the recommended practice: "put secrets in environment variables rather than files". True, but insufficient — an environment variable in CI has three leak paths:
- A build step prints
envfor debugging, and that log is retained 90 days. - A script with
set -xechoes every command with its variable values expanded. - A build dependency reads
process.envand sends it somewhere (that is supply chain, module 6).
The third is the subtlest: RUN rm secret.txt in a Dockerfile deletes nothing. Each RUN creates a layer, and the previous layer is still in the image — docker history plus a tar over that layer recovers the file. The same reasoning applies to an ARG carrying a secret into a build.
And the most important point of this lesson: once a secret has leaked, deleting it is not the fix — rotating it is. A pushed commit exists in every clone, every fork, every CI cache, and in the index of anybody scanning GitHub. A git rebase to remove it from history is housekeeping; it does not recall what already left. The correct order is always: rotate first, clean up second.
Comments
Commenting needs an account with at least one completed lesson. That condition is what keeps this thread worth reading: every point belongs to someone who can be asked back, and reputation accrues over time.
You can still read every comment below without an account. Signing in brings you back to this exact spot, not to the top of the page.
Loading comments…