fix(mcp): scope GITTENSORY_MCP_TOKEN read access to an operator allowlist - #2464
Conversation
…list The shared, end-user-obtainable GITTENSORY_MCP_TOKEN had unconditional read access to every private repo, any other contributor's private decision pack/profile/notifications, and operator-only fleet analytics. #2274 scoped the write/manage MCP paths to MCP_ACTUATION_REPO_ALLOWLIST but left canAccessRepo, requireContributorAccess, and requireOperatorAccess trusting the static mcp identity unconditionally. Adds a MCP_READ_REPO_ALLOWLIST env var (fail-closed, same csv/wildcard model as the write-side allowlist) scoping repo-context reads, and a wildcard-only unlock for the non-repo-scoped contributor/operator tools since there's no single repo to check a scoped entry against. api and internal static identities (operator-only Worker secrets) remain unconditionally trusted, unaffected by this change. Fixes #2455
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-02 05:09:13 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 5 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 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.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2464 +/- ##
=======================================
Coverage 95.93% 95.93%
=======================================
Files 225 225
Lines 25332 25343 +11
Branches 9217 9221 +4
=======================================
+ Hits 24302 24313 +11
Misses 417 417
Partials 613 613
🚀 New features to boost your workflow:
|
Summary
GITTENSORY_MCP_TOKEN(staticmcpidentity) had unconditional read access to every private repo, any other contributor's private decision pack/profile/notifications, and operator-only fleet analytics. fix(mcp): scope the static MCP token to an operator-configured repo allowlist #2274 scoped the write/manage MCP paths toMCP_ACTUATION_REPO_ALLOWLISTbut leftcanAccessRepo,requireContributorAccess, andrequireOperatorAccesstrusting the staticmcpidentity unconditionally.MCP_READ_REPO_ALLOWLIST(fail-closed, same csv/wildcard model as the write-side allowlist) scoping repo-context reads (gittensory_get_repo_context,gittensory_get_issue_quality,gittensory_preflight_pr,gittensory_validate_linked_issue,gittensory_get_label_audit, etc.), and requires the full wildcard opt-in for the non-repo-scoped contributor/operator tools (another contributor's decision pack/profile/notifications,gittensory_get_fleet_analytics) since there's no single repo to check a scoped allowlist entry against.api/internalstatic identities (operator-only Worker secrets, never handed to end users) remain unconditionally trusted, unaffected by this change.requireWatchableRepowas left unchanged: its only caller (watchIssues) already gates the staticmcpidentity viarequireContributorAccess's stricter wildcard-only check first, so an additional repo-scoped check there would be unreachable dead code.Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally; new code is 100% line+branch covered (verified viacoverage/lcov.infofor the exact ranges touched). Global 96.54%/95.51%.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderate— 0 vulnerabilitiesAlso ran
npm run db:migrations:checkandnpm run rees:test(unaffected, both green) since this repo's fulltest:ciincludes them.Safety
test/unit/issue-watch.test.ts,test/unit/mcp-fleet-analytics.test.ts,test/unit/mcp-output-schemas.test.ts.)UI Evidencesection — N/A, no UI changed.env.d.tsdoc comment, matching howMCP_ACTUATION_REPO_ALLOWLISTis documented.)Notes
test/helpers/d1.ts'sMCP_ACTUATION_REPO_ALLOWLIST: "*"test-harness default that the existing precedent for this exact class of fix already exists (write-side scoping from fix(mcp): a static GITTENSORY_MCP_TOKEN grants actuation access to every repo, not just the operator's #2253/fix(mcp): scope the static MCP token to an operator-configured repo allowlist #2274) — this PR mirrors that pattern for the read side rather than inventing a new one.