From 00d3dedb1fe0eb49eff589a63c70c6d583222615 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Wed, 21 Oct 2026 09:57:41 -0700 Subject: [PATCH 1/3] fix(ci): allowlist the fake JWT fixture from #2213; main's Secret Scan has been red since 10-16 generic-api-key matched a test fixture in agentProvisionerServiceK8s.test.js:456, the base64 of {"alg":"RS256"} followed by ".jwt" (no payload, no signature). Because the scan walks main's full history, every push to main has failed Secret Scan since #2213 (f660d6f2d), which hides any real finding behind a known red. The allowlist names that exact literal, so a real JWT still fails. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015eTFc9yqm2vKZiUyvLuBT4 --- .gitleaks.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitleaks.toml b/.gitleaks.toml index 80b8f7ffe9..967a926260 100644 --- a/.gitleaks.toml +++ b/.gitleaks.toml @@ -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 = [ From c09b7cbf3fd182b2b185fb22d3d32d0dee574d27 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:02:55 -0700 Subject: [PATCH 2/3] fix(ci): PR secret scans covered 0 commits; name the commits instead of a --remotes glob `--remotes=origin/main` is a git glob that becomes origin/main/*, so it matched nothing. On a push the scan still worked, because `--branches` held the checked-out branch, but a pull request checks out a detached merge commit with no local branch, and every PR scan reported "0 commits scanned, no leaks found": #2375, #2368 and #2389 all did. That is how #2213's fixture passed review and only went red on main. Scan HEAD (the PR merge commit, or the pushed branch) plus origin/main and origin/v1.0.x by name. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015eTFc9yqm2vKZiUyvLuBT4 --- .github/workflows/secret-scan.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml index 5fadda02c3..8b44aa5a9f 100644 --- a/.github/workflows/secret-scan.yml +++ b/.github/workflows/secret-scan.yml @@ -38,6 +38,13 @@ jobs: 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. + # ~2,600 commits, ~20s. Catches historical leaks in our own code. + # + # Name the commits; don't pattern-match them. `--remotes=origin/main` + # is a glob that git extends to origin/main/*, so it matched nothing. + # A push still scanned, through the checked-out branch in --branches, + # but a pull request checks out a detached merge commit with no local + # branch, and every PR scan reported "0 commits scanned" and passed. + # HEAD is that merge commit on a PR, and the pushed branch on a push. gitleaks detect --source . --config .gitleaks.toml --redact -v \ - --log-opts="--branches --remotes=origin/main --remotes=origin/v1.0.x" + --log-opts="HEAD origin/main origin/v1.0.x" From 2d7808d1278562541af1bca4ba69723fdf019af3 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:10:23 -0700 Subject: [PATCH 3/3] audit(ci): one-time gitleaks scan of every remote head and PR head (do not merge) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015eTFc9yqm2vKZiUyvLuBT4 --- .github/workflows/secret-scan.yml | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml index 8b44aa5a9f..64dbf7ec76 100644 --- a/.github/workflows/secret-scan.yml +++ b/.github/workflows/secret-scan.yml @@ -34,17 +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). - # ~2,600 commits, ~20s. Catches historical leaks in our own code. - # - # Name the commits; don't pattern-match them. `--remotes=origin/main` - # is a glob that git extends to origin/main/*, so it matched nothing. - # A push still scanned, through the checked-out branch in --branches, - # but a pull request checks out a detached merge commit with no local - # branch, and every PR scan reported "0 commits scanned" and passed. - # HEAD is that merge commit on a PR, and the pushed branch on a push. - gitleaks detect --source . --config .gitleaks.toml --redact -v \ - --log-opts="HEAD origin/main 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