Skip to content

security: untrack a committed env backup, widen the env gitignore - #166

Merged
ralyodio merged 1 commit into
masterfrom
worktree-scrub-env-clean
Jul 30, 2026
Merged

ralyodio merged 1 commit into
masterfrom
worktree-scrub-env-clean

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Replaces #164, which is closed. Identical diff; this one keeps credential detail out of the PR text.

What this does

  1. Untracks the committed env backup file, so it is not carried forward into future commits.

  2. Widens the gitignore. The old list named each env variant explicitly:

    .env / .env.local / .env.*.local / .env.development / .env.production / .env.test
    

    A .env.bak-<date> matched none of them. Replaced with .env* plus !.env.example, so it fails closed — any future .env.prod, .env.staging, .env.backup is ignored by default.

This does not clear the failing gitleaks check

The workflow runs gitleaks detect --source ., which scans git history (the job step is named "Scan history"), so its findings resolve to the original commit regardless of what HEAD looks like. Confirmed on the predecessor branch: same finding count, same commit, after the file was removed.

gitleaks will keep failing on every PR in this repo until one of:

  • history is rewritten to drop the blob (git filter-repo) — needs a force-push to master and a re-clone by everyone; not attempted here;
  • the findings are suppressed via a .gitleaksignore listing their fingerprints — the documented mechanism for known, remediated findings. Deliberately not included: suppressing the check while the credentials are still live would hide a real exposure. Correct follow-up once rotation is done;
  • the workflow is narrowed to scan new commits rather than full history.

Worth merging regardless — it stops the file propagating and closes the gitignore gap that admitted it.

Before you merge

The deletion is recorded in the commit, so merging removes the file from your local working tree on your next pull. Save a copy outside the repo first if that is your only one.

Verification

🤖 Generated with Claude Code

A backup of a local environment file was committed to master in 925da5e
(#160, 2026-07-28) and has been tracked ever since. It carries live
credentials, so gitleaks has been failing on every PR since that merge.

The old ignore list named each env variant explicitly — .env, .env.local,
.env.development and so on — so a .env.bak-<date> matched none of them.
Replaced with `.env*` plus a negation for the checked-in .env.example,
which fails closed instead of open.

This stops the file being carried forward and closes the gitignore gap.
It does NOT clear the gitleaks check: that job runs `gitleaks detect
--source .`, which scans history, so the findings still resolve to
925da5e regardless of what HEAD looks like. See the PR for the options.

Nor does it undo the exposure — the values are in the repository's
history and need rotating on their own schedule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@ralyodio
ralyodio merged commit 49a11c4 into master Jul 30, 2026
7 of 8 checks passed
@ralyodio
ralyodio deleted the worktree-scrub-env-clean branch July 30, 2026 21:49
ralyodio added a commit that referenced this pull request Jul 30, 2026
…ives (#168)

Every PR in this repo failed gitleaks, whatever it touched. The job ran
`gitleaks detect --source .` over full history, so it resolved to a blob
committed once and reported it forever — #163 and #166 both went red on a
finding neither introduced. A check that is red on arrival stops being read,
which is the failure mode that matters here.

Pull requests now scan only base..head. History is still scanned in full on
push to master and on the weekly cron, so an existing finding cannot be merged
out of sight — it just stops masking new ones.

Two more false-positive fingerprints. A fingerprint pins one commit, and both
already-pinned lines survived later edits to their files, so each matched again
under a newer SHA: the pk_test_ fixture the analyzer test asserts on, and the
docs curl example that by then read `-H "Authorization: Bearer $SECRET"`.

Deliberately still unpinned: the 21 findings in .env.bak-2026-07-28. Those are
real credentials, they remain in history, and suppressing them before they are
rotated would hide a live exposure.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ralyodio added a commit that referenced this pull request Jul 30, 2026
A backup of a local environment file was committed to master in cfb23d2
(#160, 2026-07-28) and has been tracked ever since. It carries live
credentials, so gitleaks has been failing on every PR since that merge.

The old ignore list named each env variant explicitly — .env, .env.local,
.env.development and so on — so a .env.bak-<date> matched none of them.
Replaced with `.env*` plus a negation for the checked-in .env.example,
which fails closed instead of open.

This stops the file being carried forward and closes the gitignore gap.
It does NOT clear the gitleaks check: that job runs `gitleaks detect
--source .`, which scans history, so the findings still resolve to
cfb23d2 regardless of what HEAD looks like. See the PR for the options.

Nor does it undo the exposure — the values are in the repository's
history and need rotating on their own schedule.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ralyodio added a commit that referenced this pull request Jul 30, 2026
…ives (#168)

Every PR in this repo failed gitleaks, whatever it touched. The job ran
`gitleaks detect --source .` over full history, so it resolved to a blob
committed once and reported it forever — #163 and #166 both went red on a
finding neither introduced. A check that is red on arrival stops being read,
which is the failure mode that matters here.

Pull requests now scan only base..head. History is still scanned in full on
push to master and on the weekly cron, so an existing finding cannot be merged
out of sight — it just stops masking new ones.

Two more false-positive fingerprints. A fingerprint pins one commit, and both
already-pinned lines survived later edits to their files, so each matched again
under a newer SHA: the pk_test_ fixture the analyzer test asserts on, and the
docs curl example that by then read `-H "Authorization: Bearer $SECRET"`.

Deliberately still unpinned: the 21 findings in .env.bak-2026-07-28. Those are
real credentials, they remain in history, and suppressing them before they are
rotated would hide a live exposure.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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