Skip to content

fix(api): allow maintainer sessions to reach validate-linked-issue - #736

Merged
JSONbored merged 5 commits into
JSONbored:mainfrom
galuis116:fix/validate-linked-issue-session-allowlist
Jun 17, 2026
Merged

fix(api): allow maintainer sessions to reach validate-linked-issue#736
JSONbored merged 5 commits into
JSONbored:mainfrom
galuis116:fix/validate-linked-issue-session-allowlist

Conversation

@galuis116

Copy link
Copy Markdown
Contributor

Summary

The coarse session-path allowlist canSessionAccessPath decides whether a browser/session identity may even reach a path before its route handler runs. It lists the pre-submission tool check-before-start but omits its sibling validate-linked-issue.

Both route handlers are symmetric — each authenticates, loads data, then admits a maintainer session via requireSessionRepoAccess:

// validate-linked-issue (was broken) AND check-before-start (works) — identical guard:
if (identity.kind === "session") {
  const forbidden = await requireSessionRepoAccess(c, identity, fullName, repo);
  if (forbidden) return forbidden;
}

But because validate-linked-issue was missing from the allowlist, the global middleware short-circuited every non-operator session with 403 insufficient_role before the handler ran:

if (identity.kind === "session" && !canSessionAccessPath(c.env, identity, c.req.path))
  return c.json({ error: "insufficient_role" }, 403);

Effect: a verified maintainer of repo X, using the web UI / a session token, got a spurious 403 insufficient_role on validate-linked-issue for their own repo X, while the twin check-before-start worked. The route's own requireSessionRepoAccess admit-path was dead code. Only operators and raw server-to-server tokens (which bypass the session allowlist) could reach it. The MCP equivalent (gittensory_validate_linked_issue) was unaffected. It fails closed — a functionality/usability bug, not a security exposure.

The in-code contract is explicit: "A path added here MUST be scoped by a per-route guard in its handler." This route had the guard but was never added to the allowlist — the inverse of the requirement.

Fix

Add the path to the allowlist, mirroring check-before-start exactly:

if (isRepoCheckBeforeStartPath(path)) return true;
if (isRepoValidateLinkedIssuePath(path)) return true;   // added
...
function isRepoValidateLinkedIssuePath(path: string): boolean {
  return /^\/v1\/repos\/[^/]+\/[^/]+\/validate-linked-issue$/.test(path);
}

The handler's existing requireSessionRepoAccess guard then enforces repo scope, so this exposes nothing a maintainer can't already reach via check-before-start.

Tests

Added a regression test in access-boundary.test.ts: a non-operator maintainer of alice/repo-a now gets 200 on validate-linked-issue for their own repo (was 403 insufficient_role), and 403 forbidden_repo for another maintainer's bob/repo-b — proving the allowlist admits the route while the per-route guard still scopes it.

Full coverage suite green locally (only the known CRLF-local gittensory-focus-manifest test fails locally; passes in CI).

Closes #734

The session-path allowlist (canSessionAccessPath) listed check-before-start
but omitted its sibling validate-linked-issue, so a non-operator maintainer
using a browser/session token got 403 insufficient_role for their own repo
before the handler ran — leaving the route's requireSessionRepoAccess guard
dead. Add the path to the allowlist, mirroring check-before-start; the
per-route guard still enforces repo scope.

Closes JSONbored#734
@ghost

ghost commented Jun 14, 2026

Copy link
Copy Markdown

Note

Gittensory Gate skipped

PR closed before full evaluation. No late first comment was created.

Signal Result Evidence Action
Gate result ⚠️ Skipped #736 is no longer open. No action.

💰 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.

@ghost ghost added the gittensory:reviewed label Jun 14, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

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

@ghost

ghost commented Jun 14, 2026

Copy link
Copy Markdown

gittensory · advisory review

Reviewed 2 changed file(s) — two independent AI reviewers.

Changed files: src/api/routes.ts, test/unit/access-boundary.test.ts

Suggested action:Safe to merge — both reviewers found no blocking issues.

Reviewer A · gpt-oss-120b — recommends ✅ merge
The PR expands the session access allowlist to include the validate-linked-issue endpoint and adds a corresponding unit test, fixing a 403 error for maintainers on their own repos.

Suggestions

  • Consider adding an assertion on the response body in the new test to verify the handler’s output, not just the status code.
  • Add a comment near the new regex function explaining its purpose for future maintainers.

Worth double-checking

  • Ensure the validate-linked-issue handler does not expose any private scoring or private context information, as the endpoint is now reachable by maintainers.

Reviewer B · nemotron-3-120b-a12b — recommends ✅ merge
The PR adds access control for the validate-linked-issue endpoint to allow maintainer sessions on their own repo, mirroring the existing check-before-start endpoint. It includes a test verifying correct scoping (own repo allowed, other repo forbidden). The change is small, focused, and consistent with existing patterns.

Worth double-checking

  • Ensure the handler for validate-linked-issue does not leak forbidden public information (e.g., private context/score terms) in its response, as this PR only affects access control.
  • Verify that the endpoint's handler properly validates inputs (e.g., issueNumber) to prevent abuse.

@ghost ghost added the gittensory-review label Jun 14, 2026
@ghost ghost mentioned this pull request Jun 14, 2026
@JSONbored JSONbored added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jun 16, 2026
@ghost ghost removed gittensory-review labels Jun 16, 2026

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

PR #736 — fix(api): allow maintainer sessions to reach validate-linked-issue
Author: galuis116 | CI: ✅ pass | Status: Failing CI

Requested changes: please ensure proper test coverage/CI should be fully green

@ghost ghost mentioned this pull request Jun 16, 2026
5 tasks
@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.72%. Comparing base (71a2e0b) to head (ebe047e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #736      +/-   ##
==========================================
+ Coverage   96.69%   96.72%   +0.02%     
==========================================
  Files          94       94              
  Lines       13848    13850       +2     
  Branches     5051     5052       +1     
==========================================
+ Hits        13391    13397       +6     
+ Misses         88       86       -2     
+ Partials      369      367       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@galuis116
galuis116 requested a review from JSONbored June 17, 2026 02:25

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

PR #736 — fix(api): allow maintainer sessions to reach validate-linked-issue
Verdict: MERGE
Resolves issue #734: FULLY
CI: All green (test 1/2, lint, workers, ui, security). gittensory neutral.

Highlights:

  • Two-line mirror of the working sibling exactly as prescribed: adds isRepoValidateLinkedIssuePath predicate + the canSessionAccessPath allowlist entry beside isRepoCheckBeforeStartPath; regex anchored and structurally identical.
  • Safe: the handler's pre-existing requireSessionRepoAccess guard still enforces per-repo scope, so this only makes the route reachable, not wider than check-before-start. Fails closed.
  • Regression test targets the reported asymmetry: non-operator maintainer of alice/repo-a now gets 200 on own repo (was 403 insufficient_role) and 403 forbidden_repo cross-repo — asserts body and status.

Concerns / required changes:

  • None.

Completeness vs issue: Adds the predicate + allowlist entry and the missing positive maintainer-session test; the dead admit-path is now reachable. Fully resolved, no scope creep.

@dosubot dosubot Bot added the lgtm label Jun 17, 2026
@JSONbored
JSONbored merged commit 71bf2b0 into JSONbored:main Jun 17, 2026
17 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in gittensory - v1 roadmap Jun 17, 2026
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.05x multiplier.

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

[Bug]: validate-linked-issue route unreachable for maintainer sessions

2 participants