Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions .github/workflows/secret-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,20 @@ jobs:
| tar -xz gitleaks
sudo mv gitleaks /usr/local/bin/gitleaks

- name: Run gitleaks (all our branch commits, excluding submodule history)
# ONE-TIME AUDIT, not for merge: until #2389, PR scans covered 0 commits,
# so commits that live only on a branch or a PR head were never scanned.
# This run scans every remote head plus every refs/pull/*/head. It prints
# commit, file and rule only, never the value.
- name: Fetch every pull-request head
run: git fetch -q origin '+refs/pull/*/head:refs/remotes/pr/*'

- name: Audit gitleaks over every remote head and PR head
run: |
# Scan the full history of our branches (not --all, which includes
# submodule git objects from _external/clawdbot).
# ~500 commits, ~15s. Catches historical leaks in our own code.
gitleaks detect --source . --config .gitleaks.toml --redact -v \
--log-opts="--branches --remotes=origin/main --remotes=origin/v1.0.x"
echo "refs: $(git for-each-ref refs/remotes | wc -l)"
echo "commits: $(git rev-list --remotes | wc -l)"
gitleaks detect --source . --config .gitleaks.toml --redact \
--report-format json --report-path /tmp/audit.json \
--log-opts="--remotes" || true
echo "findings: $(jq length /tmp/audit.json)"
jq -r '.[] | "\(.Commit[0:12]) \(.File) \(.RuleID)"' /tmp/audit.json | sort -u
test "$(jq length /tmp/audit.json)" = 0
5 changes: 5 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ regexes = [
# (shared on the landing page, README, and Discord). Tests pin it as the
# REACT_APP_COMMUNITY_INVITE_TOKEN fixture; it is not a secret.
'''7b91255f18ae3c0ae3721707a6613731''',
# A fake ChatGPT JWT in agentProvisionerServiceK8s.test.js (#2213): the
# base64 of {"alg":"RS256"} followed by the literal ".jwt", no payload and no
# signature. generic-api-key matched it, and main's Secret Scan was red on
# every push from 2026-10-16. The exact literal only, so a real token still fails.
'''eyJhbGciOiJSUzI1NiJ9\.jwt''',
]

paths = [
Expand Down
Loading