From 668b60765e8ab3b5d7f74b1e900a76f11f2032ac Mon Sep 17 00:00:00 2001 From: Ben Browning Date: Fri, 3 Apr 2026 20:57:14 +0000 Subject: [PATCH] Narrow GitHub PAT injection to api.github.com only Agents only need the PAT for GitHub API calls (gh CLI, PR creation, etc.), not for git clone of public repos. Removing github.com and *.githubusercontent.com from the credential routing avoids unnecessarily exposing the PAT on every request to those domains. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 3 +-- internal/credentials/config_test.go | 25 +++++++++++++++---------- internal/credentials/credentials.json | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 4036c80..bd50039 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -93,8 +93,7 @@ The default credential routing is defined in `internal/credentials/credentials.j | `*.anthropic.com` | `x-api-key: ` | `ANTHROPIC_API_KEY` | | `*.openai.com` | `Authorization: Bearer ` | `OPENAI_API_KEY` | | `*.cursor.com`, `*.cursorapi.com` | `Authorization: Bearer ` | `CURSOR_API_KEY` | -| `github.com`, `api.github.com` | `Authorization: Bearer ` | `GH_TOKEN` | -| `*.githubusercontent.com` | `Authorization: Bearer ` | `GH_TOKEN` | +| `api.github.com` | `Authorization: Bearer ` | `GH_TOKEN` | | `*.googleapis.com` | `Authorization: Bearer ` | gcloud ADC (auto-refresh) | ## Client Compatibility diff --git a/internal/credentials/config_test.go b/internal/credentials/config_test.go index eb0980f..e695d39 100644 --- a/internal/credentials/config_test.go +++ b/internal/credentials/config_test.go @@ -232,35 +232,40 @@ func TestBuildFromConfig_GitHubBearer(t *testing.T) { { EnvVar: "TEST_GH_TOKEN", InjectorType: "bearer", - Domains: []string{"github.com", "api.github.com", ".githubusercontent.com"}, + Domains: []string{"api.github.com"}, }, }, } store, _, _ := BuildFromConfig(cfg) - // Test exact domain match req := &http.Request{ - URL: &url.URL{Host: "github.com"}, + URL: &url.URL{Host: "api.github.com"}, Header: make(http.Header), } if matched, injected := store.InjectCredentials(req); !matched || !injected { - t.Error("should match github.com") + t.Error("should match api.github.com") } if got := req.Header.Get("Authorization"); got != "Bearer ghp_test" { t.Errorf("Authorization = %q, want %q", got, "Bearer ghp_test") } - // Test suffix domain match + // github.com should NOT match (no PAT for git clone of public repos) req2 := &http.Request{ - URL: &url.URL{Host: "raw.githubusercontent.com"}, + URL: &url.URL{Host: "github.com"}, Header: make(http.Header), } - if matched, injected := store.InjectCredentials(req2); !matched || !injected { - t.Error("should match raw.githubusercontent.com") + if matched, _ := store.InjectCredentials(req2); matched { + t.Error("should not match github.com") } - if got := req2.Header.Get("Authorization"); got != "Bearer ghp_test" { - t.Errorf("Authorization = %q, want %q", got, "Bearer ghp_test") + + // raw.githubusercontent.com should NOT match + req3 := &http.Request{ + URL: &url.URL{Host: "raw.githubusercontent.com"}, + Header: make(http.Header), + } + if matched, _ := store.InjectCredentials(req3); matched { + t.Error("should not match raw.githubusercontent.com") } } diff --git a/internal/credentials/credentials.json b/internal/credentials/credentials.json index 1326a5e..852428e 100644 --- a/internal/credentials/credentials.json +++ b/internal/credentials/credentials.json @@ -21,7 +21,7 @@ { "env_var": "GH_TOKEN", "injector": "bearer", - "domains": ["github.com", "api.github.com", ".githubusercontent.com"] + "domains": ["api.github.com"] }, { "env_var": "GOOGLE_APPLICATION_CREDENTIALS",