Repository navigation
Conversation
sc979
commented
Jul 28, 2026
sc979
commented
Jul 28, 2026
sc979
commented
Jul 28, 2026
sc979
commented
Jul 28, 2026
Co-authored-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
sc979
commented
Jul 28, 2026
Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
sc979
commented
Jul 28, 2026
sc979
marked this pull request as draft
July 28, 2026 12:18
sc979
commented
Jul 29, 2026
sc979
commented
Jul 29, 2026
sc979
commented
Jul 29, 2026
sc979
commented
Jul 29, 2026
sc979
commented
Jul 29, 2026
Co-authored-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com> Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
sc979
marked this pull request as ready for review
July 29, 2026 09:25
sc979
commented
Jul 29, 2026
Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
sc979
commented
Jul 29, 2026
Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
sc979
commented
Jul 29, 2026
Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
already managed by the triggering pipeline. causing failing loop Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
Signed-off-by: Stéphane Chapron <34628915+sc979@users.noreply.github.com>
On a push that creates a new branch (or rewrites history), the gitleaks range fell back to a full-history scan. Because a branch usually forks off the default branch, that re-scanned commits already living in the default branch and re-reported pre-existing secrets that the branch never introduced. Resolve the range against the default branch instead: scan only merge-base(origin/<default>, after)..after, i.e. the commits unique to the branch. The empty-"before" case now follows the same path, so it is consistent with a real new branch. When the default branch cannot be resolved, fall back to a full scan (over-scan is the safe direction). Also correct the range-resolved log to ::notice:: (::info:: is not a valid workflow command). Assisted-by: Claude Code (claude-opus-4-8)
This was referenced Sep 21, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Since persist-credentials: false, the re-fetch that recovers commits
missing from the clone ("invalid revision range") had no credentials
and could never succeed. Re-fetches now authenticate with the job token,
passed to each git process only through env-scoped config: nothing is
written to .git/config, shown on a command line or exported to
gitleaks. The PR base, the pushed SHA and tag pushes are handled too,
with a backoff between attempts and a warning on every fallback.
Make the scan cover what the change under test brings, and fail closed:
- PR scans include commits merged in from other branches, and
.gitattributes can no longer hide file contents (--text)
- a rewritten default branch gets a full scan instead of an empty range
- gitleaks errors, unsupported events and unresolvable ranges fail the
job; pull_request_target always fails, before checkout, as it is not
compliant with the security posture; branch deletions pass
- the gitleaks binary is verified against a sha256 pinned in the
workflow, and the job token is scoped to contents: read
Also document the workflow in CLAUDE.md and drop stray whitespace from
the PR template.
Assisted-by: Claude Code (claude-opus-5-5)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Author
✅ Automated Review — PassedThis PR was reviewed using the Centreon automated review skill. Complexity: high — Recommended reviewers: 2 No blocking issues found. Ready for human review.
Areas that deserve careful human attention:
|
sc979
marked this pull request as draft
October 7, 2026 08:41
Bring in #74 (shallow PR checkout with a computed fetch depth, faster blocklist scan). The gitleaks conflict keeps the pull_request_target guard as the first step, then the fetch-depth step, and keeps the job token scoped to contents: read.
Since #74 the PR checkout is shallow (fetch-depth = PR commits + 2). When the base branch moved further than that since the PR forked, the merge-base was unreachable: the scan concluded "no shared history" and ran a full scan of the shallow clone, where gitleaks reads boundary commits as roots and reports every pre-existing secret in the tree. A clean PR then failed on secrets already on the base branch. The scan now deepens the PR history (32 to 1024 commits, doubling) until the fork point is reachable from both sides, unshallows as a last resort, and never scans a range holding a shallow boundary commit. "No shared history" is only concluded on a complete clone. Deepening goes through the authenticated fetch and stops when a fetch brings nothing, so the existing retry loop takes over. Also shorten the pull_request_target error message. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Assisted-by: Claude Code (claude-opus-5-5)
Secrets already on the destination branch are that branch's own business: the scan must fail only when one of the analyzed branch's commits holds a secret, whatever the destination is called. Several ranges broke that rule: an unrelated-history PR, a rewritten or created default branch, workflow_dispatch and schedule scanned the full history of every branch; a new branch was compared with the default branch only (wrong for branches cut from dev-YY.MM.x); and a push merging the destination back in rescanned its commits. - pull_request scans base..head, the commits not on the PR base. - push, workflow_dispatch and schedule scan the ref's commits that are on no other branch (nor before the push), excluded through --remotes so the range does not grow with the branch count. An empty range passes without running gitleaks. - On the shallow PR checkout, only the base side is deepened, from the base SHA, until base..head holds no parentless commit, so the PR side is not fetched again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Assisted-by: Claude Code (claude-opus-5-5)
A commit must be scanned until it is on the destination branch, even when another branch (load, performance or security tests...) already holds it: excluding every other branch let such commits through, e.g. a dispatch on a branch whose commits sit on feature branches, or one push updating two branches. - push to an existing branch scans before..after, every pushed non-merge commit; a "before" missing after a force-push is fetched once while the server still serves it. - push creating a branch (or whose "before" is gone), workflow_dispatch and schedule have no destination nor "before" to exclude, so they scan the ref's whole history. - pull_request is unchanged: base..head. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Assisted-by: Claude Code (claude-opus-5-5)
The secret scan is a pull request gate; workflow_dispatch is kept to debug the pipeline. Push and schedule are no longer supported: the job fails closed on them, like on any other unsupported event, and security-checks.yml only calls the secret scan on pull_request and workflow_dispatch (its push and schedule runs keep the dependency scan). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Assisted-by: Claude Code (claude-opus-5-5)
Align security-checks.yml with the supported scan events: drop the push and schedule triggers, so the per-job event filter on the secret scan is no longer needed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Assisted-by: Claude Code (claude-opus-5-5)
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.
Description
What are your needs or what are you planning to do in this PR?
Resolves the "Invalid revision range" failures on the gitleaks job by replacing
gitleaks/gitleaks-actionwith a pinned gitleaks binary (8.30.1, verified against asha256 pinned in the workflow) driven by a script that resolves the scan range
defensively (authenticated re-fetch + retry), scans every commit of the analyzed
branch that is not already on the destination branch, and fails closed.
Quality gate
Every non-merge commit of the analyzed branch is scanned. Only the commits already on
the destination branch are excluded, whether or not they are also on other branches
(load, performance or security test branches…), so no new secret can reach the
destination unnoticed.
The workflow assumes no branch name (
main,develop,dev-YY.MM.x…): thedestination comes from the event itself.
Supported events:
pull_request(the quality gate) andworkflow_dispatch(mostly todebug the pipeline). Org usage, checked on 2026-10-07: 73 of the 76 non-archived
repositories (centreon + quanta-computing) call
gitleaks-analysis.yml@mainthroughsecu-secret-scan.yml, on exactly these two events. In this repository,security-checks.ymlnow runs on these two events only (its push and scheduletriggers are removed).
centreon/.githubhas no caller, andquanta-computing/cxm-zone-probeis empty.The branch is up to date with
main(merged, not rebased, to keep the PR history):it keeps
actions/checkoutv7.0.1 withpersist-credentials: false(#69, #71) andthe shallow PR checkout from #74 (
fetch-depth= PR commits + 2, full clone otherwise).The job token is scoped to
contents: readonly: the script calls no GitHub API, sothe
pull-requests: readadded for the action in #72 is dropped.Scan range per event
The range is passed to gitleaks as
--log-optsand validated withgit logfirst.Every range carries
--text, so a repository's.gitattributes(e.g.* -diff)cannot hide file contents from the scan.
pull_requestbase..head,--no-merges: every commit not on the PR base, including commits merged in from other branches (gitleaks-action's--first-parentskipped them), excluding the base commits merged into the PR. A PR with an unrelated history scans its own historyworkflow_dispatch--no-merges: no destination to excludepull_request_targetpush,schedule,merge_group…)An empty range (e.g. a PR whose head is already on its base) passes with a notice,
without running gitleaks.
Shallow PR checkout (#74)
Pull requests are checked out with
fetch-depth= PR commits + 2, which holds every PRcommit. When the base branch moved further than that since the PR forked, the base side
does not reach the shared history yet, and a shallow boundary commit looks parentless:
gitleaks would scan its whole tree and report every pre-existing secret. So, for
pull_request, the range is trusted only oncebase..headholds no parentless commit:--depth= PR commits + 1 + 32, 64 … 1024 from thebase SHA, through the same authenticated fetch), so the PR side is not fetched again;
--unshallowis the last resort (e.g. unrelated histories);In the tests, with
main100 commits ahead of a 1-commit PR, 3 deepen rounds fetchabout 130 base commits, and the clone stays shallow.
workflow_dispatchkeeps a fullclone (depth 0).
Re-fetch when hashes changed after checkout
actions/checkoutpins its refs and can't be re-run in a loop. When the event's SHAsare missing from the clone, the step re-fetches and retries, up to 5 attempts with a
5/10/15/20 s backoff:
refs/pull/<n>/head, the base branch, and the event's head/baseSHAs if still served. A head (or base) SHA force-pushed away falls back to the live
PR tip (or base branch tip), with a
::warning::.force-pushed away, falls back to the live tip of the branch, with a
::warning::(branches only: a tag never falls back to a same-name branch).
Failed fetches are logged as
::warning::. If the range is still unresolvable, the jobfails and points to those warnings.
Credentials stay unpersisted.
persist-credentials: falseis kept as a hardeningmeasure, so the clone holds no token. The re-fetches authenticate with the job token,
set on each
git fetchprocess only through env-scoped git config(
GIT_CONFIG_COUNT/KEY_0/VALUE_0): never written to.git/config, never on acommand line, masked in the logs, and not exported to the gitleaks process.
Build outcome
2).gitleaks.toml)pull_request_targetpush,schedule…)Test coverage
Both
run:steps are extracted verbatim from the workflow and run withbash -e,as GitHub does. The scan runs against throwaway repos whose remote is served over smart
HTTP and rejects any request without the job token: a runner-like full clone
(
fetch-depth: 0, no persisted credentials, detached HEAD) with commits pushed afterthe clone, and a shallow PR checkout (merge commit fetched at depth PR commits + 2, as
actions/checkoutdoes,main100 commits ahead of the fork point).mainanddev-26.10.x+ clean branch → OK; branch leak → KO, only the branch's file reported; after mergingmainthat brought a new secret → OK; unrelated history → OK when clean, KO when it leaks. Dispatch: whole history scanned (KO on any secret in it, OK on a clean orphan branch)main100 commits ahead → pass, 3 base-side deepen rounds, no boundary commit scanned, no unshallow; PR's own leak reported (notmain's);mainmerged in →main's secret not reported; leaking side branch reported; unrelated history with secrets on base → unshallow, pass; deepen with an invalid token → fail closed, one fetch per attempt, token not in argv::warning::+ failure; tag dispatch with its SHA gone → no fallback to a same-name branch.git/, not in any git argv, not in gitleaks' environment, base64 header maskedpush,schedule,merge_group→ fail (unsupported);pull_request_targetrejected by the first step (before checkout) and by the script;security-checks.ymltriggers on PR and dispatch only0pass;2fail;1/126fail; empty range → pass without running gitleaks.gitattributes* -diffdoesn't hide a leak (PR and dispatch); broken.gitleaks.toml→ job failsResult: 107 / 112 passed. The 5 failures are the install-step cases: the test
machine's network intercepts TLS to GitHub (
curlexit 60, self-signed certificate),so the release could not be downloaded there. The same cases passed on 2026-10-02, and
the real-gitleaks cases ran with the 8.30.1 binary verified against
GITLEAKS_SHA256.🤖 Generated with Claude Code