fix(copilot): exchange raw GitHub token for Copilot API JWT#12876
Closed
difujia wants to merge 1 commit into
Closed
fix(copilot): exchange raw GitHub token for Copilot API JWT#12876difujia wants to merge 1 commit into
difujia wants to merge 1 commit into
Conversation
Raw GitHub tokens (gho_/github_pat_/ghu_) are now exchanged for short-lived Copilot API tokens via /copilot_internal/v2/token before being used as Bearer credentials. This is required to access internal-only models (e.g. claude-opus-4.6-1m with 1M context). Implementation: - exchange_copilot_token(): calls the token exchange endpoint with in-process caching (dict keyed by SHA-256 fingerprint), refreshed 2 minutes before expiry. No disk persistence — gateway is long-running so in-memory cache is sufficient. - get_copilot_api_token(): convenience wrapper with graceful fallback — returns exchanged token on success, raw token on failure. - Both callers (hermes_cli/auth.py and agent/credential_pool.py) now pipe the raw token through get_copilot_api_token() before use. 12 new tests covering exchange, caching, expiry, error handling, fingerprinting, and caller integration. All 185 existing copilot/auth tests pass. Part 2 of NousResearch#7731.
008d17f to
eee988c
Compare
13 tasks
This was referenced Apr 24, 2026
Contributor
Author
|
Cherry-picked into main via d7ad07d. Thanks! |
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.
Part 2 of #7731, as scoped by @konsisumer.
Problem
Raw GitHub tokens (
gho_/github_pat_/ghu_) are sent directly asAuthorization: Bearerto the Copilot API. This works for basic models but does not grant access to internal-only models likeclaude-opus-4.6-1m(1M context), which require an exchanged Copilot API token.Solution
Exchange raw GitHub tokens for short-lived Copilot API tokens via
GET https://api.github.com/copilot_internal/v2/tokenbefore use.Token caching strategy
Per the discussion in #7731: in-process caching only, no disk persistence.
dictkeyed by SHA-256 token fingerprint (first 16 hex chars)expires_atChanges
hermes_cli/copilot_auth.py:exchange_copilot_token(raw_token)→(api_token, expires_at)— core exchange with cachingget_copilot_api_token(raw_token)→str— convenience wrapper with graceful fallback to raw tokenhermes_cli/auth.py:_resolve_api_key_provider_secret("copilot")now pipes throughget_copilot_api_token()agent/credential_pool.py:_refresh_copilot_entries()stores the exchanged token in the credential poolGraceful fallback
If the exchange fails (network error, 401, unsupported account),
get_copilot_api_token()returns the raw token unchanged. This preserves existing behavior for accounts that work without exchange.Tests
12 new tests covering: successful exchange, caching, cache expiry, empty token response, network errors, fallback behavior, fingerprint consistency, and caller integration. All 185 existing copilot/auth/credential-pool tests pass.
Not included (separate PRs)
proxy-ep(Fix terminal interactivity #4 in [Bug]: Copilot provider uses hardcoded context windows and lacks token exchange — breaks account-specific models and enterprise endpoints #7731)/modelscontext windows (Terminal tool #1 — see fix(copilot): wire live /models max_prompt_tokens into context-window resolver #12840)