feat(github): repository-scoped user tokens for per-repo imports#446
Open
guitavano wants to merge 1 commit into
Open
feat(github): repository-scoped user tokens for per-repo imports#446guitavano wants to merge 1 commit into
guitavano wants to merge 1 commit into
Conversation
Add GITHUB_SCOPE_TOKEN, repository_id on OAuth exchange/refresh, and Basic auth for GitHub scoped token API. Alias /api/mcp to /mcp for local wrangler. Co-authored-by: Cursor <cursoragent@cursor.com>
7 tasks
Contributor
There was a problem hiding this comment.
3 issues found across 7 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="github/server/tools/scope-token.ts">
<violation number="1" location="github/server/tools/scope-token.ts:14">
P3: This adds duplicated OAuth credential-loading logic; extract to a shared helper to avoid drift between auth flows.</violation>
<violation number="2" location="github/server/tools/scope-token.ts:38">
P2: Trim `target` before `.min(1)` so whitespace-only owner logins are rejected at validation time.</violation>
</file>
<file name="github/server/lib/github-client.ts">
<violation number="1" location="github/server/lib/github-client.ts:97">
P2: `repository_id` is sent to `/login/oauth/access_token`, but this parameter is not documented for code exchange/refresh and may be ignored, so per-repo scoping may not actually apply during token mint/refresh.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| .describe("GitHub repository ID to scope the token to"), | ||
| target: z | ||
| .string() | ||
| .min(1) |
Contributor
There was a problem hiding this comment.
P2: Trim target before .min(1) so whitespace-only owner logins are rejected at validation time.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At github/server/tools/scope-token.ts, line 38:
<comment>Trim `target` before `.min(1)` so whitespace-only owner logins are rejected at validation time.</comment>
<file context>
@@ -0,0 +1,68 @@
+ .describe("GitHub repository ID to scope the token to"),
+ target: z
+ .string()
+ .min(1)
+ .describe(
+ "GitHub user or organization login that owns the repository (owner login)",
</file context>
| } | ||
|
|
||
| if (options?.repositoryId !== undefined) { | ||
| body.repository_id = String(options.repositoryId); |
Contributor
There was a problem hiding this comment.
P2: repository_id is sent to /login/oauth/access_token, but this parameter is not documented for code exchange/refresh and may be ignored, so per-repo scoping may not actually apply during token mint/refresh.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At github/server/lib/github-client.ts, line 97:
<comment>`repository_id` is sent to `/login/oauth/access_token`, but this parameter is not documented for code exchange/refresh and may be ignored, so per-repo scoping may not actually apply during token mint/refresh.</comment>
<file context>
@@ -63,20 +71,30 @@ async function postToGitHub(
+ }
+
+ if (options?.repositoryId !== undefined) {
+ body.repository_id = String(options.repositoryId);
}
</file context>
| import { scopeUserAccessTokenToRepository } from "../lib/github-client.ts"; | ||
| import type { Env } from "../types/env.ts"; | ||
|
|
||
| function getOAuthCredentials(): { clientId: string; clientSecret: string } { |
Contributor
There was a problem hiding this comment.
P3: This adds duplicated OAuth credential-loading logic; extract to a shared helper to avoid drift between auth flows.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At github/server/tools/scope-token.ts, line 14:
<comment>This adds duplicated OAuth credential-loading logic; extract to a shared helper to avoid drift between auth flows.</comment>
<file context>
@@ -0,0 +1,68 @@
+import { scopeUserAccessTokenToRepository } from "../lib/github-client.ts";
+import type { Env } from "../types/env.ts";
+
+function getOAuthCredentials(): { clientId: string; clientSecret: string } {
+ const clientId = process.env.GITHUB_CLIENT_ID || "";
+ const clientSecret = process.env.GITHUB_CLIENT_SECRET || "";
</file context>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GITHUB_SCOPE_TOKENtool to mint repository-scoped user tokens via GitHub/applications/{client_id}/token/scopedrepository_idduring OAuth code exchange and refresh when provided in mesh client state / metadatatarget(owner login)/api/mcp→/mcpfor local wrangler devTest plan
bun test github/server/lib/github-client.test.tsbun run devingithub/with.dev.varsconfiguredGITHUB_SCOPE_TOKENwith{ repository_id, target }through mesh proxyMade with Cursor
Summary by cubic
Adds repository-scoped GitHub user tokens to support per-repo imports. Introduces the
GITHUB_SCOPE_TOKENtool and threadsrepository_idthrough OAuth exchange/refresh; also aliases/api/mcpto/mcpfor local dev.New Features
GITHUB_SCOPE_TOKENto mint repo-scoped tokens via GitHub/applications/{client_id}/token/scopedusing App Basic auth; requirestarget(owner login).repository_idduring OAuth code exchange and refresh when provided; parsed from Mesh clientstate(mesh:<base64url>)./api/mcpto/mcpfor wrangler dev.Migration
GITHUB_CLIENT_IDandGITHUB_CLIENT_SECRET(seegithub/server/.dev.vars.examplefor local).statewithrepositoryIdto receive scoped tokens, and callGITHUB_SCOPE_TOKENwith{ repository_id, target }after repo selection.Written for commit 1cbdf7e. Summary will update on new commits. Review in cubic