Skip to content

fix(enrichment): detect GitHub fine-grained PATs in secret-scan#3117

Merged
gittensory-orb[bot] merged 1 commit into
JSONbored:mainfrom
luciferlive112116:fix/enrichment-secret-scan-github-pat
Jul 4, 2026
Merged

fix(enrichment): detect GitHub fine-grained PATs in secret-scan#3117
gittensory-orb[bot] merged 1 commit into
JSONbored:mainfrom
luciferlive112116:fix/enrichment-secret-scan-github-pat

Conversation

@luciferlive112116

Copy link
Copy Markdown
Contributor

Summary

The secret scanner's RULES in review-enrichment/src/analyzers/secret-scan.ts detects the classic GitHub
token family but not GitHub fine-grained personal access tokens — which are now GitHub's recommended
default token type. The existing GitHub rule:

{ kind: "github_token", re: /\bgh[pousr]_[A-Za-z0-9]{36,}\b/, confidence: "high" },

only matches the ghp_/gho_/ghu_/ghs_/ghr_ prefixes. A fine-grained PAT has the shape
github_pat_ + 82 base62/underscore characters — the letters g-i-t-h-u-b… never contain a gh[pousr]_
pair, so that rule never matches it, and no other rule has a github_pat_ prefix.

Concrete false negative (a leaked token in a PR diff, as scanPatch receives it):

+GITHUB_TOKEN=github_pat_11ABCDE3Y0…_LmNoPqRsTuVwXyZ…            (github_pat_ + 82 chars)
  • Actual: no finding — the token passes the scanner unflagged. The generic keyword-assignment fallback
    only fires on a keyword = "quoted value" shape and would at best report a low-value generic "verify",
    never a GitHub credential; a bare KEY=github_pat_… env/CI line is missed entirely.
  • Correct: flagged as a GitHub credential (high confidence).

Fix: add one rule for github_pat_ + 82 [0-9A-Za-z_] chars — the standard fine-grained-PAT shape,
mirroring the existing fixed-length format rules (npm_{36}, hf_{34}, glpat-{20}). Zero false-positive
risk: the 11-char literal prefix followed by exactly 82 token chars is not a shape ordinary prose, base64
blobs, or hex hashes produce, and it cannot collide with the existing github_token rule.

No linked issue: small, self-evident detection-coverage fix (one additive rule) closing a false-negative
for the current GitHub-recommended credential format, alongside the token families already covered; no
schema/config/deploy change — fits the repo's preferred (not required) linked-issue policy.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked an issue, or this is small enough that the summary explains why an issue is not needed.

Validation

  • git diff --check
  • npm run typecheck
  • npm run rees:test — the review-enrichment build + analyzer suite (see note below)
  • npm run test:coverage (N/A — this file is in review-enrichment/, outside the src/** Codecov scope)
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • Ran locally: git diff --check (clean), the review-enrichment TypeScript build (npm --prefix review-enrichment run build, clean), and the secret-scan analyzer test via node --test21/21 tests
    pass
    , including the new fine-grained-PAT case (asserts kind: "github_pat", confidence: "high", single
    finding). The change is confined to review-enrichment/, outside the src/** Codecov scope, so
    test:coverage does not apply. The fixture is assembled from fragments so it is never a contiguous secret
    literal in source.
  • Not run locally: the UI, root typecheck, and the metadata:check step of rees:test. metadata:check
    compares the committed analyzer-metadata.json (generated on CI/Linux) against a local regeneration and
    reports a spurious byte difference on this Windows dev box (it fails identically on unmodified main);
    this change adds a scan rule, not any analyzer descriptor, so the committed metadata is unchanged and
    metadata:check passes on CI (Linux). analyzer-metadata.json was NOT modified.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests.
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks.
  • Visible UI changes include a UI Evidence section below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Notes

  • Detection-only addition: this adds one high-confidence rule for a real credential format and changes no
    existing rule, so it cannot alter current findings; no analyzer descriptor changes, so
    analyzer-metadata.json is intentionally untouched. The regression fixture is built from string fragments
    (never a contiguous secret literal), matching the convention the test file already uses.
  • Regression test added in review-enrichment/test/secret-scan.test.ts: a github_pat_ + 82-char token is
    now flagged kind: "github_pat" at high confidence. All existing token-format assertions are unchanged.

@superagent-security

Copy link
Copy Markdown

Superagent didn't find any vulnerabilities or security issues in this PR.

@gittensory-orb gittensory-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.5x multiplier. label Jul 4, 2026
@gittensory-orb

gittensory-orb Bot commented Jul 4, 2026

Copy link
Copy Markdown

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-04 15:08:36 UTC

2 files · 1 AI reviewer · no blockers · readiness 80/100 · CI green · clean

⏸️ Suggested Action - Manual Review

Review summary
The change adds a specific high-confidence rule for GitHub fine-grained PATs and exercises it through the real `scanPatch` path that iterates `RULES`, so the previously missed `github_pat_` shape is now detected before the generic fallback. The regex is ordered with the other provider-specific rules, uses the documented fixed-length token body, and the fixture length matches the rule exactly. I do not see a reachable correctness regression in the changed files.

Nits — 4 non-blocking
  • nit: `review-enrichment/src/analyzers/secret-scan.ts:24` says `base62/underscore`, but underscore is not part of base62; use `base62 plus underscore` or `alphanumeric/underscore` so the comment matches the regex exactly.
  • nit: `review-enrichment/test/secret-scan.test.ts:57` covers a quoted TypeScript literal, but the PR description's concrete false negative is a bare env-style assignment, so add that shape if you want the test to lock the advertised behavior directly.
  • In `review-enrichment/test/secret-scan.test.ts`, add a second assertion with `hunk([`GITHUB_TOKEN=${fakeGithubPat}`])` so the test covers the env/CI line called out in the PR description.
  • In `review-enrichment/test/secret-scan.test.ts`, consider adding one off-by-one negative case for 81 or 83 body characters to document that the fixed-length rule is intentional.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ No-issue rationale PR body explains why no issue is linked.
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (no linked issue context).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 109 registered-repo PR(s), 52 merged, 23 issue(s).
Contributor context ✅ Confirmed Gittensor contributor luciferlive112116; Gittensor profile; 109 PR(s), 23 issue(s).
Gate result ✅ Passing No configured blocker found.
Review context
  • Author: luciferlive112116
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 109 PR(s), 23 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Await review-lane availability.
  • Refresh registry data or choose a registered active repo.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@gittensory-orb gittensory-orb Bot added the gittensor Gittensor contributor context label Jul 4, 2026

@gittensory-orb gittensory-orb Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Gittensory approves — the gate is satisfied and CI is green.

@gittensory-orb gittensory-orb Bot merged commit 8a27764 into JSONbored:main Jul 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.5x multiplier. gittensor Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant