Skip to content

Commit 33cb962

Browse files
feat(ci): add gitleaks PR-gating + base toml (Phase 0.B1-fleet Wave 2) (#3)
* feat(ci): add gitleaks PR-gating + base allowlist (Phase 0.B1-fleet) Adds a Secret Scan workflow that runs gitleaks against every PR and push to default branch. Mirrors the canonical pattern in BfxLendingBot, BfxPingPongBot, and the Wave-1 repos (BotEventAggregator, Knowledge-Hub, DigiConta, blazor-shared, infra-iac). This is Wave 2 of the Phase 0.B1-fleet rollout — the 6 repos that didn't yet have a `gitleaks.toml`. CI-style scan (`--log-opts="--no-merges -1"`) on current HEAD reports `no leaks found` against gitleaks default rules, so the toml ships as a minimal scaffold (extend `paths` / add `regexes` if findings surface). Phase 0 of the Restart-2026-04 master plan requires zero secret-leak findings across all fleet repos before the bot fleet restarts on Opus 4.7. Pre-PR gating catches hardcoded secrets before they merge to master/main. 🤖 Generated with [Claude Code](https://claude.com/claude-code) * fix(ci): pin gitleaks version + scan PR range (Copilot review) Addresses Copilot's 3 template-level concerns on Wave 2 PRs: - Pin gitleaks to 8.30.1 + verify SHA256 (no latest-release scraping) - Scan full PR commit range on pull_request (was: --log-opts -1, missed earlier commits) - fetch-depth: 0 so the base..head range resolves * fix(gitleaks): anchor allowlist regexes + drop .env.local (Copilot review) - Anchor paths so '.env.example.bak' and 'docs/.env.example.md' aren't allowlisted. - Remove .env.local — a real one with real secrets MUST trip the scan. Use .env.example for committed samples. * fix(ci): pin commitlint workflow actions to SHA (org ruleset) Org ruleset enforces "all actions must be pinned to a full-length commit SHA". - actions/checkout@v4 → @de0fac2e... (v6.0.2) - wagoid/commitlint-github-action@v6 → @b948419d... (v6.2.1) Surfaced as a workflow setup error blocking the gitleaks Wave 2 PR; same fix should be applied fleet-wide to any other repo whose commitlint.yml still carries unpinned tags. --------- Co-authored-by: JCBauza <5790807+JCBauza@users.noreply.github.com> Co-authored-by: cloudingenium-automation[bot] <277329096+cloudingenium-automation[bot]@users.noreply.github.com>
1 parent 1e619db commit 33cb962

3 files changed

Lines changed: 87 additions & 3 deletions

File tree

.github/workflows/commitlint.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ jobs:
88
commitlint:
99
runs-on: ubuntu-latest
1010
steps:
11-
- uses: actions/checkout@v4
11+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
1212
with:
1313
fetch-depth: 0
1414
- name: Lint commits in PR
15-
uses: wagoid/commitlint-github-action@v6
15+
uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1
1616
with:
1717
configFile: ".commitlintrc.json"
1818
failOnWarnings: false
1919
firstParent: false
20-

.github/workflows/secret-scan.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Secret Scan
2+
3+
# Mirrors the BfxLendingBot / BfxPingPongBot pattern:
4+
# Gitleaks PR-gating runs on every PR + every push to default branch
5+
# to catch hardcoded secrets before merge. Uses repo-local gitleaks.toml
6+
# for allowlist (extends gitleaks default rules with paths/regexes for
7+
# this repo's known false positives).
8+
#
9+
# Phase 0.B1-fleet rollout (Restart-2026-04 master plan).
10+
# Hardened 2026-04-27 per Copilot review (#9/#3/#10):
11+
# - Pin gitleaks version + verify SHA256 (no latest-release scraping).
12+
# - Scan full PR commit range, not just last commit (--log-opts -1).
13+
# - Allowlist anchored regexes only (see gitleaks.toml).
14+
15+
on:
16+
push:
17+
branches: [master, main]
18+
pull_request:
19+
branches: [master, main]
20+
workflow_dispatch:
21+
22+
permissions:
23+
contents: read
24+
25+
concurrency:
26+
group: secret-scan-${{ github.ref }}
27+
cancel-in-progress: true
28+
29+
jobs:
30+
gitleaks:
31+
name: Secret Scan
32+
runs-on: [self-hosted, Linux, Build]
33+
timeout-minutes: 5
34+
permissions:
35+
contents: read
36+
steps:
37+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
38+
with:
39+
# Full history needed so --log-opts can resolve the PR base..head range.
40+
fetch-depth: 0
41+
42+
- name: Gitleaks — secret scanning
43+
env:
44+
GITLEAKS_VERSION: "8.30.1"
45+
GITLEAKS_SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb"
46+
run: |
47+
mkdir -p "$HOME/.local/bin"
48+
curl -sSfL -o /tmp/gitleaks.tar.gz \
49+
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
50+
echo "${GITLEAKS_SHA256} /tmp/gitleaks.tar.gz" | sha256sum -c -
51+
tar xzf /tmp/gitleaks.tar.gz -C "$HOME/.local/bin" gitleaks
52+
53+
# Scan the full PR commit range on pull_request (catches secrets introduced
54+
# earlier in the branch); fall back to the last push delta on direct pushes.
55+
if [ "${{ github.event_name }}" = "pull_request" ]; then
56+
LOG_OPTS="--log-opts=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}"
57+
else
58+
LOG_OPTS="--log-opts=HEAD~1..HEAD"
59+
fi
60+
"$HOME/.local/bin/gitleaks" detect --source . --config gitleaks.toml "$LOG_OPTS" --verbose --redact --no-banner

gitleaks.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# =============================================================================
2+
# Gitleaks Configuration
3+
# =============================================================================
4+
# Mirrors the BfxLendingBot pattern: useDefault rules + minimal path
5+
# allowlist. Currently no false positives on this repo's working tree;
6+
# extend `paths` or add `regexes` here if findings surface in CI.
7+
#
8+
# Hardened 2026-04-27 per Copilot review:
9+
# - Anchored regexes (no unintended matches like `foo/.env.local.backup`).
10+
# - `.env.local` REMOVED from allowlist — a real `.env.local` with real
11+
# secrets MUST trip gitleaks. Use `.env.example` for committed samples.
12+
# =============================================================================
13+
14+
[extend]
15+
useDefault = true
16+
17+
[allowlist]
18+
description = "Global allowlist"
19+
paths = [
20+
# Anchored regexes — match exactly the intended file at repo root or any subdir,
21+
# never a backup/sibling like `.env.example.bak` or `docs/.env.example.md`.
22+
'''(^|/)\.gitleaksignore$''',
23+
'''(^|/)\.env\.example$''',
24+
]
25+
regexTarget = "line"

0 commit comments

Comments
 (0)