Skip to content

gitleaks false positive on CLAUDE_SHIM=0 turns the hygiene lane red for every open PR #3610

Description

@kyle-sexton

Context

The hygiene job's gitleaks step fails on pull requests that do not touch the flagged file,
which fails the ci-status rollup and blocks merge. Observed on #3588, whose diff is
documentation only.

The finding, reproduced locally with the CI-pinned gitleaks 8.30.1 and this repo's
.gitleaks.toml:

RuleID:      generic-api-key
Secret:      CLAUDE_SHIM=0
File:        plugins/claude-config/lib/resolve-convention-home.sh
Line:        248
Commit:      f7aec1549dec60407a24a7d8ea720696b7b099af
Fingerprint: f7aec1549dec60407a24a7d8ea720696b7b099af:plugins/claude-config/lib/resolve-convention-home.sh:generic-api-key:248

The source is an ordinary shell variable initialization:

AGENTS_STATE="none"; AGENTS_TOKEN=""
CLAUDE_STATE="none"; CLAUDE_TOKEN=""
CLAUDE_SHIM=0

generic-api-key fires because the preceding CLAUDE_TOKEN="" line supplies the keyword context
and CLAUDE_SHIM=0 is captured as the value. There is no secret here.

Why this reaches unrelated pull requests

The commit is not on main and not on the branch of the pull request that fails. It is reachable
from origin/chore/bespoke-conversion and origin/chore/retired-conventions-mechanism, both
pushed 2026-09-01T21:47Z. The CI checkout fetches all branches, and the gitleaks step's git scan
reaches the commit through those refs — the failing run reported 1,987 commits scanned where the
pull request head's own history is 1,976. A scan confined to the head resolves clean; adding
--log-opts=--all reproduces the finding exactly.

main's own last push run (2026-09-01T21:40Z) predates the offending push by seven minutes, which
is why main is still green while every pull request opened or pushed after it is red.

Proposed fix

.gitleaks.toml states the policy: "inherit the upstream default ruleset and add nothing
repo-specific. Managed consumers do not edit this file. Intentional findings use a
repository-owned .gitleaksignore or inline gitleaks:allow comment." So the config is not the
place to fix this. Two options, in order of preference:

  1. On the branch that introduced the line, add an inline allow marker, or rename the variable so
    the keyword context no longer forms (for example CLAUDE_SHIM_PRESENT=0 reads the same and
    does not sit under a *_TOKEN line).
  2. A .gitleaksignore fingerprint entry. Weaker: the fingerprint is commit-scoped, so a rebase of
    that branch invalidates it.

Worth considering separately: whether the gitleaks step should scan the pull request's own history
rather than every fetched ref. Scanning all refs means any branch in the repository can red-line
every open pull request, which is what happened here.

Acceptance criteria

  • The hygiene job's gitleaks step passes on a pull request whose diff does not touch
    plugins/claude-config/lib/resolve-convention-home.sh.
  • The fix does not add a repo-specific rule or allowlist to .gitleaks.toml.
  • A decision is recorded on whether the scan should be scoped to the pull request's own
    commits.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions