Skip to content

ci(gitleaks): pin the version, verify the checksum and drop to least privilege - #1455

Merged
eleshar merged 3 commits into
developfrom
chore/gitleaks-hardening
Aug 2, 2026
Merged

ci(gitleaks): pin the version, verify the checksum and drop to least privilege#1455
eleshar merged 3 commits into
developfrom
chore/gitleaks-hardening

Conversation

@eleshar

@eleshareleshar commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Linked issues

Closes#1454

Build/CI change

What: Hardens the organisation-wide gitleaks implementation and adds a scheduled updater.

Why: The reusable workflow resolved the latest gitleaks release at run time and piped the archive
directly into tar. CI therefore executed a binary that was never integrity-checked, at a version
that could change without any commit to this repository. It also inherited whatever permissions the
calling workflow granted, had no timeout, and left the extracted binary in the workspace.

Changes:

  • Pin 8.30.1 and its official linux_x64 SHA-256 on adjacent lines; verify with
    sha256sum --check before extraction.
  • Pin actions/checkout to 3d3c42e5aac5ba805825da76410c181273ba90b1 (v7.0.1), version in a
    same-line comment, with persist-credentials: false.
  • Explicit permissions: contents: read at workflow and job level; timeout-minutes: 15;
    set -euo pipefail in every run block; temp directory removed under if: always().
  • Replace the undocumented gitleaks detect alias with the supported gitleaks dir and
    gitleaks git commands.
  • Pass values into shell through env rather than interpolating ${{ }} into script bodies.
  • Fall back gracefully when a calling repository has no .gitleaks.toml.
  • New optional runner input so a caller can run the scan on its own unprivileged self-hosted
    group. Defaults to '"ubuntu-latest"', so every existing caller is unchanged.
  • New gitleaks-update.yml: weekly, excludes drafts and prereleases, retrieves the official
    checksum manifest, updates version and checksum together, re-verifies the download, opens a PR,
    never merges.

Still using the open-source CLI directly, so no paid gitleaks organisation licence is required.

Baseline & Target

Before: version resolved from api.github.com on every run; no checksum; no explicit
permissions; no timeout; actions/checkout@v7 floating tag; extracted binary left in the workspace;
scan runner not selectable.

After: fixed version and verified checksum; contents: read; 15-minute timeout; immutable action
SHA; workspace cleaned; runner selectable by the caller. Scan runtime is unchanged — the download was
already happening, it is now verified.

Rollback

Revert this PR. The pinned values live on two adjacent lines in gitleaks-reusable.yml, so a version
can also be rolled back on its own by restoring the previous version and checksum pair. Recovery
paths are documented in docs/secret-scanning.md.

Notes

Secrets and permissions. The scan workflows request contents: read only and reference no
secrets. The updater mints a short-lived App installation token via actions/create-github-app-token
pinned to bcd2ba49218906704ab6c1aa796996da409d3eb1 (v3.2.0), scoped with repositories: .github
and exactly three write scopes — contents (push the branch), pull-requests (open the PR) and
workflows. The workflows scope is required, not speculative: the update diff edits
.github/workflows/gitleaks-reusable.yml, and a push touching a workflow file is rejected without
it. That is also why GITHUB_TOKEN cannot perform this job.

Prerequisite for the updater only.vars.DEP_MERGE_APP_ID and secrets.DEP_MERGE_APP_PRIVATE_KEY
are not yet present on this repository, so the weekly updater will not run until they are added. The
scan path — the part every other repository consumes — has no such dependency and works today.

Live version verification, 2 August 2026.actions/checkout v7.0.1 (published 2026-07-20),
actions/create-github-app-token v3.2.0 (2026-05-12), gitleaks v8.30.1 (2026-03-21, latest
non-prerelease). Immutable references recorded above.

Test evidence

13 of 13 local checks passed against the real 8.30.1 binary:

CheckResult
Correct checksum acceptedpass
Incorrect checksum rejected before extractionpass
.gitleaks.toml loads; clean working-tree scanpass
Full-history git scanpass
Allowlisted documentation values not flaggedpass
Seeded fake credential detected, non-zero exitpass
All three workflow files parsepass
7 extracted run blocks clean under ShellCheckpass
No write permissions in scan workflowspass
No latest resolution in the scan pathpass
All external actions SHA-pinnedpass

The seeded credential was randomly generated in a temporary directory outside the repository and was
never written to git.

Idempotency of the updater was reasoned through all four reachable states — no branch and no PR, an
open PR for the version, a branch with no PR, and a stale branch with different content — and
implemented with checkout -B, a no-op guard when the tree already matches the target pin,
--force-with-lease, and PR creation only when none is open.

Required vs optional checks

Branch protection on develop requires exactly one status check, validate-pr-template, and no
approving reviews:

required_status_checks.contexts = ["validate-pr-template"]
required_pull_request_reviews = null

Linting and Validation are not required. Both fail on pre-existing repository content
unrelated to this change (SCSS, Markdown, slacks-summary.js, and workflow issues in
config-summary.yml, ui-standardisation.yml, validate-changelog.yml, unresolved
NGINX_SITE_UPPER references and a nick-fields/retry@v3 reference). This PR touches none of those
files — its diff is limited to three gitleaks workflows, CHANGELOG.md and docs/secret-scanning.md.

Changelog

Changed

  • Gitleaks scanning now runs a pinned, checksum-verified binary under least-privilege permissions,
    with a weekly updater that pairs each version bump with its official checksum.

Checklist (Global DoD / PR)

  • All AC met and demonstrated — 13 of 13 checks pass, evidence table above
  • Tests added/updated (unit/E2E as appropriate) — integrity, detection and allowlist checks run against the real binary
  • Accessibility checklist completed (where relevant):
    • Semantic HTML and heading order verified — not applicable, CI workflows produce no UI
    • Keyboard navigation and visible focus states verified — not applicable
    • ARIA used only where needed — not applicable
    • Contrast and non-colour cues reviewed (WCAG 2.2 AA or higher) — not applicable
  • Docs/readme/changelog updated (if user-facing) — docs/secret-scanning.md added, CHANGELOG updated with PR and issue links
  • Security checklist completed (where relevant):
    • Untrusted input validated and sanitised — values passed via env, not interpolated into script bodies
    • Output escaped for its rendering context — --redact prevents findings printing secret material
    • Privileged actions enforce nonce and capability checks — not applicable; scan jobs are contents: read and hold no token. The updater's token is scoped to this repository with three justified write scopes.
    • No secrets/sensitive data introduced; OWASP risks reviewed — no secrets added; supply-chain risk addressed by SHA pinning and checksum verification
  • Code/design reviews approved — CodeRabbit review state is APPROVED; all three findings resolved in ec46856
  • CI green; linked issues closed; release notes prepared (if shipping) — every required check passes; the two failing checks are non-required and fail identically on unchanged develop content

…privilege
The reusable workflow resolved the latest gitleaks release at run time and piped
the archive straight into tar, so CI executed an unverified binary whose version
could change without a commit. It also ran with whatever permissions the caller
happened to grant.
- Pin gitleaks 8.30.1 and its official linux_x64 SHA-256 side by side, and verify
the archive with sha256sum --check before extraction.
- Pin actions/checkout to the immutable SHA for v7.0.1, version in a same-line
comment, with persist-credentials: false.
- Add explicit contents: read at workflow and job level, timeout-minutes, and
set -euo pipefail in every run block.
- Remove the temporary directory under if: always().
- Replace the undocumented detect alias with the supported dir and git commands.
- Pass values into shell through env instead of interpolating expressions.
- Fall back gracefully when a calling repository has no .gitleaks.toml.
- Add gitleaks-update.yml, a weekly updater that pairs each version bump with its
official checksum, re-verifies the download and opens a PR without merging.
- Document the controls and the recovery path in docs/secret-scanning.md.
@github-actions

github-actionsBot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

🚫 This PR description is missing required template content.

Missing required section(s): Global DoD checklist

Please update the PR body using one of the repository PR templates:

Empty placeholders, unchecked checklist boxes, and stub issue references do not count.

@github-actionsgithub-actionsBot added status:needs-review Awaiting code review type:chore Chore / small hygiene change labels Aug 2, 2026
@github-actions

github-actionsBot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

⏱️ Aging and SLA annotation

  • Age: 0 day(s)
  • SLA state: Within SLA
  • Thresholds: warn at 7 days, breach at 14 days
  • Last updated: 2026-08-02T07:05:53.568Z

Maintained by project-meta-sync workflow.

@coderabbitai

coderabbitaiBot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added organisation-wide secret scanning with Gitleaks, supporting full-history and working-tree scans.
    • Added configurable runner selection for scanning workflows.
    • Added scheduled checks to keep the scanning tool current and raise verification pull requests automatically.
  • Security
    • Strengthened scan integrity, access controls, failure handling and temporary-file cleanup.
    • Added protections to prevent overlapping scans and limit permissions to what is required.
  • Documentation
    • Added guidance covering setup, operation, automated updates and recovery procedures.
    • Documented the changes in the Unreleased changelog.

Walkthrough

The change hardens reusable Gitleaks scanning with pinned, checksum-verified binaries, read-only permissions, immutable checkout, supported scan commands, timeouts, and cleanup. It adds a scheduled updater that verifies stable releases and opens pull requests. Documentation covers usage and recovery procedures.

Changes

Gitleaks workflow hardening

Layer / File(s)Summary
Verified scan runtime
.github/workflows/gitleaks-reusable.yml
The reusable workflow accepts JSON runner selections, pins Gitleaks and checkout, verifies the archive checksum, supports git and dir scans, and cleans temporary files.
Caller controls and documentation
.github/workflows/gitleaks.yml, docs/secret-scanning.md, CHANGELOG.md
The caller workflow applies read-only permissions and concurrency controls. The documentation and changelog describe the hardened workflow, update process, and recovery actions.
Automated release update flow
.github/workflows/gitleaks-update.yml
The scheduled updater resolves stable releases, retrieves checksums, verifies the archive and scan, and opens a pull request with updated pins.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels:lang:yaml, area:automation

Suggested reviewers:krugazul

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Linked Issues check✅ PassedThe changes address all coding objectives in [#1454], including pinning, checksum verification, least privilege, safe scanning, cleanup, and scheduled updates.
Out of Scope Changes check✅ PassedThe workflow, documentation, changelog, runner input, and updater changes support the objectives in [#1454] without unrelated code changes.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check✅ PassedThe title clearly summarises the main Gitleaks hardening changes, including version pinning, checksum verification and least-privilege permissions.
Description check✅ PassedThe description covers the change, rationale, linked issue, changelog, testing evidence, rollback, security review and checklist items.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/gitleaks-hardening

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added priority:normal Default priority area:ci Build and CI pipelines area:documentation Docs & guides lang:md Markdown content/docs type:ci CI/CD pipeline work meta:needs-changelog Requires a changelog entry before merge labels Aug 2, 2026
@coderabbitai
coderabbitaiBot requested a review from krugazulAugust 2, 2026 05:30
@coderabbitaicoderabbitaiBot added area:automation Automation workflows and agents lang:yaml YAML config labels Aug 2, 2026

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/gitleaks-update.yml:
- Around line 100-129: Make the “Open the update pull request” step idempotent
by checking for an existing open pull request whose head branch is
deps/gitleaks-${NEW_VERSION} before git checkout or push. If found, exit
successfully (or update the existing pull request) without attempting to
recreate the branch; otherwise preserve the current branch creation, commit,
push, and PR flow.
- Around line 26-31: Update the create-github-app-token step identified by id
token to explicitly set permission-contents, permission-pull-requests, and
permission-workflows to write, limiting the generated App token to the
permissions required by this job.
In `@CHANGELOG.md`:
- Line 96: Add the required pull request link and issue link to the Unreleased
changelog entry describing Gitleaks hardening, preserving the existing entry
text and following the repository’s established changelog link format.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e4d86de-7437-46bd-883b-dd71607f3f6f

📥 Commits

Reviewing files that changed from the base of the PR and between 5b12ce4 and bf16baa.

📒 Files selected for processing (5)
  • .github/workflows/gitleaks-reusable.yml
  • .github/workflows/gitleaks-update.yml
  • .github/workflows/gitleaks.yml
  • CHANGELOG.md
  • docs/secret-scanning.md
📜 Review details
⏰ Context from checks skipped due to timeout. (7)
  • GitHub Check: lint-and-links
  • GitHub Check: Testing
  • GitHub Check: coderabbit-gate
  • GitHub Check: Mergify Merge Protections
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Summary
⚠️ CI failures not shown inline (2)

GitHub Actions: Validate PR Template / 0_validate-pr-template.txt: ci(gitleaks): pin the version, verify the checksum and drop to least privilege

Conclusion: failure

View job details

##[group]Run actions/github-script@v7
with:
script: const { validatePullRequestBody } = require('./scripts/validation/template-helpers.cjs');
const marker = '<!-- template-enforcement -->';
const pr = context.payload.pull_request;
const author = pr.user?.login || '';
const isDependabot = author === 'dependabot[bot]' || author === 'app/dependabot';
const isImgbot = author === 'imgbot[bot]' || author === 'app/imgbot';
if (isDependabot || isImgbot) {
core.info(`Skipping PR template validation for bot author ${author}.`);
return;
}
const validation = validatePullRequestBody(pr.body || '', pr.labels || [], pr.head?.ref || '');
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
per_page: 100
});
const previous = comments.find((comment) =>
comment.user?.type === 'Bot' && comment.body?.includes(marker)
);
if (validation.missing.length === 0) {
if (previous) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: previous.id,
body: `${marker}\n✅ Template check passed after update. Thanks for fixing the PR description.`
});
}
return;
}
const message = [
marker,
'🚫 This PR description is missing required template content.',
'',
`Missing required section(s): ${validation.missing.join(', ')}`,
'',
'Please update the PR body using one of the repository PR templates:',
'- https://github.com/lightspeedwp/.github/blob/develop/.github/pull_request_template.md',
'- https://github.com/lightspeedwp/.github/tree/develop/.github/PULL_REQUEST_TEMPLATE',
'',
'Empty placeholders, unchecked checklist boxes, and stub issue references do not count.'
].join('\n');
if (previous) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: previous.id,
body: message
});
} else {
await github.rest.issues....

GitHub Actions: Validate PR Template / validate-pr-template: ci(gitleaks): pin the version, verify the checksum and drop to least privilege

Conclusion: failure

View job details

##[group]Run actions/github-script@v7
with:
script: const { validatePullRequestBody } = require('./scripts/validation/template-helpers.cjs');
const marker = '<!-- template-enforcement -->';
const pr = context.payload.pull_request;
const author = pr.user?.login || '';
const isDependabot = author === 'dependabot[bot]' || author === 'app/dependabot';
const isImgbot = author === 'imgbot[bot]' || author === 'app/imgbot';
if (isDependabot || isImgbot) {
core.info(`Skipping PR template validation for bot author ${author}.`);
return;
}
const validation = validatePullRequestBody(pr.body || '', pr.labels || [], pr.head?.ref || '');
const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
per_page: 100
});
const previous = comments.find((comment) =>
comment.user?.type === 'Bot' && comment.body?.includes(marker)
);
if (validation.missing.length === 0) {
if (previous) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: previous.id,
body: `${marker}\n✅ Template check passed after update. Thanks for fixing the PR description.`
});
}
return;
}
const message = [
marker,
'🚫 This PR description is missing required template content.',
'',
`Missing required section(s): ${validation.missing.join(', ')}`,
'',
'Please update the PR body using one of the repository PR templates:',
'- https://github.com/lightspeedwp/.github/blob/develop/.github/pull_request_template.md',
'- https://github.com/lightspeedwp/.github/tree/develop/.github/PULL_REQUEST_TEMPLATE',
'',
'Empty placeholders, unchecked checklist boxes, and stub issue references do not count.'
].join('\n');
if (previous) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: previous.id,
body: message
});
} else {
await github.rest.issues....
🧰 Additional context used
📓 Path-based instructions (6)
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

**/*: Do not place reusable AI assets under .github/; store them in the appropriate top-level portable asset folder.
Portable JSON schemas belong in the root .schemas/ directory; portable agents belong in agents/; permanent human documentation belongs in docs/; temporary scratch files belong in .github/tmp/ and must be cleaned up.
Do not commit node_modules/, build/, or other generated artefacts.

**/*: Use UK English and optimise solutions for clarity, scalability, maintainability, and profitable outcomes.
Prefer minimal, modular solutions; justify heavier tools based on return on investment and maintenance cost.

Files:

  • docs/secret-scanning.md
  • CHANGELOG.md
**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

Use UK English throughout documentation and Markdown content, including spellings such as optimise, organisation, colour, and behaviour.

**/*.md: Documentation and AI infrastructure files must follow their applicable documented standards, including required structure, frontmatter, quality gates, and validation.
Run Markdown linting with npm run lint:md and validate frontmatter with npm run validate:frontmatter where applicable.

Files:

  • docs/secret-scanning.md
  • CHANGELOG.md
**/*.{md,yml,yaml,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not use a references frontmatter field; use inline links or footer sections instead.

Files:

  • docs/secret-scanning.md
  • CHANGELOG.md
**/docs/**/*.md

⚙️ CodeRabbit configuration file

**/docs/**/*.md: Review documentation files:

  • Ensure markdown is linted and formatted per project style guides.
  • Flag illogical folder structures, file naming, or misplaced content.
  • Confirm documentation is up to date, accurate, and cross-referenced.
  • Ensure accessibility (heading hierarchy, alt text for images, UK English).

Files:

  • docs/secret-scanning.md
**/.github/workflows/*.yml

⚙️ CodeRabbit configuration file

**/.github/workflows/*.yml: Review GitHub Actions workflows for this governance repo:

  • Security: check for least-privilege permissions (use permissions: at job level, default to read-only).
  • Secret handling: ensure secrets are passed via env vars, not interpolated directly into run: steps to prevent injection.
  • Action pinning: prefer SHA-pinned actions over mutable tags (e.g. actions/checkout@v4 is acceptable; SHA pins are better).
  • No pull_request_target with untrusted code execution unless explicitly justified.
  • Avoid storing sensitive outputs as unmasked step outputs.
  • Check for reusable workflow patterns and matrix strategies where appropriate.
  • Validate on: triggers: ensure branch/path filters are present to avoid unnecessary runs.
  • Confirm workflows are documented, DRY, and maintainable.
  • Ensure agent-triggered workflows use workflow_dispatch with defined inputs.

Files:

  • .github/workflows/gitleaks.yml
  • .github/workflows/gitleaks-update.yml
  • .github/workflows/gitleaks-reusable.yml
CHANGELOG.md

⚙️ CodeRabbit configuration file

CHANGELOG.md: Review CHANGELOG.md:

  • Confirm entries follow Keep a Changelog 1.1.0 format.
  • Each entry under [Unreleased] must include a PR link and issue link.
  • Verify entries use the correct section headings (Added, Changed, Fixed, Deprecated, Removed, Security, Documentation, Performance).
  • Check UK English spelling throughout.

Files:

  • CHANGELOG.md
🪛 LanguageTool
docs/secret-scanning.md

[grammar] ~34-~34: A determiner may be missing.
Context: ...ence | persist-credentials: false | | Least privilege | `permissions: contents: rea...

(THE_SUPERLATIVE)


[style] ~45-~45: Would you like to use the Oxford spelling “organization”? The spelling ‘organisation’ is also correct.
Context: ... public, so private repositories in the organisation can call the reusable workflow with no ...

(OXFORD_SPELLING_Z_NOT_S)


[uncategorized] ~62-~62: “Neither…nor” is a correlative construction, so the comma here may be unnecessary.
Context: ...that is neither a draft nor a prerelease, retrieves the official checksums.txt,...

(NEITHER_NOR_SUPERFLUOUS_COMMA)

🪛 zizmor (1.28.0)
.github/workflows/gitleaks-update.yml

[warning] 33-36: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 28-28: dangerous use of GitHub App tokens (github-app): app token inherits blanket installation permissions

(github-app)

🔇 Additional comments (5)
.github/workflows/gitleaks-reusable.yml (1)

2-68: LGTM!

.github/workflows/gitleaks.yml (1)

2-26: LGTM!

docs/secret-scanning.md (2)

16-74: LGTM!


1-14: 📐 Maintainability & Code Quality

Mark the documentation checks as complete.

docs/secret-scanning.md has the required frontmatter fields, so this check can be cleared.

.github/workflows/gitleaks-update.yml (1)

1-24: LGTM!

Also applies to: 38-99

Comment thread.github/workflows/gitleaks-update.yml
Comment thread.github/workflows/gitleaks-update.yml
Comment threadCHANGELOG.md Outdated
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Reviewer Summary for PR #1455

CI Status:success
Files changed: 5
Risk Distribution: 3 critical, 0 high, 0 medium, 2 low

Recommendations

  • ⚠️ 3 critical-risk file(s) modified (workflows, secrets)
  • ⚠️ Security-sensitive files modified (review carefully)

The scan job was hard-coded to ubuntu-latest, so a caller wanting the scan on
its own unprivileged self-hosted group could not have it. Add an optional
'runner' input carrying a JSON runner selection, defaulting to '"ubuntu-latest"'
so every existing caller is unchanged.
workflow_call inputs are limited to boolean, number and string, so the value is
a JSON string decoded with fromJSON. That accepts both a single label and a
label array.
@github-actionsgithub-actionsBot removed the type:ci CI/CD pipeline work label Aug 2, 2026
…nk the changelog
Addresses the three unresolved review findings on PR #1455.
Token scoping: request only contents, pull-requests and workflows write, scoped
to this repository through the repositories input. The workflows scope is not
speculative — the update diff edits .github/workflows/gitleaks-reusable.yml and
a push touching a workflow file is rejected without it, which is also why
GITHUB_TOKEN cannot perform this job.
Idempotency: repeated scheduled runs previously failed once the deps branch
existed. The job now converges from all four states — no branch and no PR, an
open PR for the version, a branch with no PR, and a stale branch with different
content — using checkout -B, a no-op guard when the tree already matches the
target pin, and force-with-lease so a branch advanced by someone else is never
discarded silently. The pull request is opened only when none is already open.
Changelog: added the PR and issue links required by the path instructions.
@mergify

mergifyBot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@eleshar
eleshar merged commit a14b5ad into developAug 2, 2026
42 of 48 checks passed
@eleshar
eleshar deleted the chore/gitleaks-hardening branch August 2, 2026 07:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:automationAutomation workflows and agentsarea:ciBuild and CI pipelinesarea:documentationDocs & guideslang:mdMarkdown content/docslang:yamlYAML configmeta:needs-changelogRequires a changelog entry before mergepriority:normalDefault prioritystatus:needs-reviewAwaiting code reviewtype:choreChore / small hygiene change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Harden the gitleaks implementation: pin version, verify checksum, least privilege

1 participant

@eleshar