Skip to content

copilot_chat: Exchange OAuth token for session token before API calls#57738

Open
eodus wants to merge 1 commit into
zed-industries:mainfrom
eodus:fix/copilot-session-token-exchange
Open

copilot_chat: Exchange OAuth token for session token before API calls#57738
eodus wants to merge 1 commit into
zed-industries:mainfrom
eodus:fix/copilot-session-token-exchange

Conversation

@eodus

@eodus eodus commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements Copilot session token exchange in copilot_chat, matching the protocol used by all other Copilot clients (VS Code, JetBrains, Neovim plugins).

Problem

Zed's copilot_chat crate currently uses the raw OAuth token (ghu_...) directly in Copilot API requests. The Copilot backend expects clients to first exchange this token for a short-lived session token via GET /copilot_internal/v2/token. Without this exchange, the server falls back to a degraded model catalog based on the OAuth app registration, causing users to see no models or a reduced set.

This is the root cause of #57219 for users who have successfully authenticated (i.e. have a valid OAuth token in apps.json).

Solution

  • Add exchange_session_token() that calls the /copilot_internal/v2/token endpoint
  • Cache the session token with TTL-based refresh (5 min before expiry, matching the ~30 min server TTL)
  • Use the session token in update_models() and get_auth_details() for all downstream API calls
  • Fall back gracefully to the raw OAuth token if the exchange fails (e.g. network issue)
  • Add Copilot-Integration-Id header required by enterprise endpoints when using session tokens
  • Add #[serde(default)] on ModelBilling fields that enterprise endpoints may omit

Notes

  • The Copilot-Integration-Id: vscode-chat value is the de facto standard used by all third-party Copilot integrations — no per-client integration ID exists for non-VS Code clients.
  • The oauth_token parameter name in copilot_request_headers() now sometimes carries a session token rather than an OAuth token. A naming cleanup could be done in a follow-up PR to keep this one focused on the functional fix.
  • Tested with GitHub Copilot Enterprise subscription — models load correctly after this change.

Related issue: apps.jsonauth.db migration

There may be a separate contributing factor to #57219: the Copilot SDK appears to have migrated OAuth token storage from apps.json (which copilot_chat currently reads) to a SQLite auth.db. Users who authenticated before this migration have a working apps.json and hit only the token exchange bug (fixed by this PR). Users on a fresh install may not get apps.json created at all, which is a separate auth-layer issue. This PR focuses on the token exchange; the auth.db migration would be a separate change.

Fixes #57219

Release Notes:

  • Fixed GitHub Copilot models not appearing in the model picker for enterprise users by implementing the session token exchange protocol that all other Copilot clients use.

@cla-bot

cla-bot Bot commented May 26, 2026

Copy link
Copy Markdown

We require contributors to sign our Contributor License Agreement, and we don't have @eodus on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'.

@zed-community-bot zed-community-bot Bot added the first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions label May 26, 2026
@eodus

eodus commented May 26, 2026

Copy link
Copy Markdown
Contributor Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label May 26, 2026
@cla-bot

cla-bot Bot commented May 26, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@maxdeviant maxdeviant changed the title copilot_chat: exchange OAuth token for session token before API calls copilot_chat: Exchange OAuth token for session token before API calls May 26, 2026
Zed currently uses the raw OAuth token (ghu_...) directly in Copilot
API requests. All other Copilot clients (VS Code, Claude Code, OpenCode)
exchange this token for a short-lived session token via
GET /copilot_internal/v2/token before making API calls.

The session token carries integrator identity and is required for the
full model catalog on enterprise endpoints. Without it, the server
defaults to a degraded model list based on the OAuth app registration.

This change:
- Adds exchange_session_token() that calls the token exchange endpoint
- Caches the session token with TTL-based refresh (5 min before expiry)
- Uses the session token for model catalog fetches and all API calls
- Falls back gracefully to raw OAuth token if exchange fails
- Adds Copilot-Integration-Id header required by enterprise endpoints

Fixes zed-industries#57219
@eodus eodus force-pushed the fix/copilot-session-token-exchange branch from 55ec166 to 60a5eac Compare May 26, 2026 14:52
eodus added a commit to eodus/zed that referenced this pull request May 26, 2026
The Copilot SDK migrated token storage from apps.json to a SQLite
auth.db. Zed's copilot_chat only reads apps.json/hosts.json, so
users who sign in with the newer SDK get no OAuth token and no models.

This change:
- Adds sqlez dependency to copilot_chat for SQLite reading
- Adds extract_oauth_token_from_db() that reads auth.db via sqlez
- Tries auth.db at startup (constructor) if env var is not set
- Tries auth.db as fallback in the file watcher callback when
  apps.json/hosts.json don't contain a token
- Validates token starts with ghu_ before accepting

Related to zed-industries#57219 (complements the session token exchange in zed-industries#57738)

Release Notes:

- Fixed GitHub Copilot authentication for users whose SDK stores tokens in auth.db instead of apps.json
eodus added a commit to eodus/zed that referenced this pull request May 26, 2026
The Copilot SDK migrated token storage from apps.json to a SQLite
auth.db. Zed's copilot_chat only reads apps.json/hosts.json, so
users who sign in with the newer SDK get no OAuth token and no models.

This change:
- Adds sqlez dependency to copilot_chat for SQLite reading
- Adds extract_oauth_token_from_db() that reads auth.db via sqlez
- Tries auth.db at startup (constructor) if env var is not set
- Tries auth.db as fallback in the file watcher callback when
  apps.json/hosts.json don't contain a token
- Validates token starts with ghu_ before accepting

Related to zed-industries#57219 (complements the session token exchange in zed-industries#57738)

Release Notes:

- Fixed GitHub Copilot authentication for users whose SDK stores tokens in auth.db instead of apps.json
eodus added a commit to eodus/zed that referenced this pull request May 26, 2026
The Copilot SDK migrated token storage from apps.json to a SQLite
auth.db. Zed's copilot_chat only reads apps.json/hosts.json, so
users who sign in with the newer SDK get no OAuth token and no models.

This change:
- Adds sqlez dependency to copilot_chat for SQLite reading
- Adds extract_oauth_token_from_db() that reads auth.db via sqlez
- Tries auth.db at startup (constructor) if env var is not set
- Tries auth.db as fallback in the file watcher callback when
  apps.json/hosts.json don't contain a token
- Validates token starts with ghu_ before accepting

Related to zed-industries#57219 (complements the session token exchange in zed-industries#57738)

Release Notes:

- Fixed GitHub Copilot authentication for users whose SDK stores tokens in auth.db instead of apps.json
eodus added a commit to eodus/zed that referenced this pull request May 26, 2026
The Copilot SDK migrated token storage from apps.json to a SQLite
auth.db. Zed's copilot_chat only reads apps.json/hosts.json, so
users who sign in with the newer SDK get no OAuth token and no models.

This change:
- Adds sqlez dependency to copilot_chat for SQLite reading
- Adds extract_oauth_token_from_db() that reads auth.db via sqlez
- Tries auth.db at startup (constructor) if env var is not set
- Tries auth.db as fallback in the file watcher callback when
  apps.json/hosts.json don't contain a token
- Validates token starts with ghu_ before accepting

Related to zed-industries#57219 (complements the session token exchange in zed-industries#57738)

Release Notes:

- Fixed GitHub Copilot authentication for users whose SDK stores tokens in auth.db instead of apps.json
eodus added a commit to eodus/zed that referenced this pull request May 26, 2026
The Copilot SDK migrated token storage from apps.json to a SQLite
auth.db. Zed's copilot_chat only reads apps.json/hosts.json, so
users who sign in with the newer SDK get no OAuth token and no models.

This change:
- Adds sqlez dependency to copilot_chat for SQLite reading
- Adds extract_oauth_token_from_db() that reads auth.db via sqlez
- Tries auth.db at startup (constructor) if env var is not set
- Tries auth.db as fallback in the file watcher callback when
  apps.json/hosts.json don't contain a token
- Validates token starts with ghu_ before accepting

Related to zed-industries#57219 (complements the session token exchange in zed-industries#57738)

Release Notes:

- Fixed GitHub Copilot authentication for users whose SDK stores tokens in auth.db instead of apps.json
@smitbarmase smitbarmase added the area:ai/copilot AI feedback for GitHub Copilot via ACP label May 27, 2026
@morgankrey

Copy link
Copy Markdown
Contributor

This is fixed by #57764

@morgankrey morgankrey closed this May 28, 2026
@eodus

eodus commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

@morgankrey no, that is a separate issue! If you use just API key (not a temporary key!) copilot server returns truncated list of the models. That probably affects corporate users only.

The scheme I implemented repeats Vscode auth scheme and other tools. That results into the full model list

@morgankrey morgankrey reopened this May 29, 2026
@morgankrey

Copy link
Copy Markdown
Contributor

Sorry - got confused

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:ai/copilot AI feedback for GitHub Copilot via ACP cla-signed The user has signed the Contributor License Agreement first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zed agent does not show models from copilot

4 participants