Skip to content

GitHub Copilot: Enterprise sign-in impossible, and inference host is pinned to api.githubcopilot.com #79

Description

@ivseb

The GitHub Copilot provider pins two things that are not actually constant, which makes it unusable on GitHub Enterprise and sends non-Individual tokens to the wrong host.

Branch with the change:
main...ivseb:feat/copilot-enterprise

(Opening this as an issue rather than a PR — pull request creation is rejected on this repo, same as #78.)

The two problems

1. The inference host is not always api.githubcopilot.com. Copilot routes Individual, Business and Enterprise subscribers to different hosts. The host is carried in the Copilot token itself as proxy-ep=proxy.<tenant>.githubcopilot.com, and the token-exchange response can also name it directly — CopilotTokenResponse.endpoints.api is already declared in GitHubCopilotAuthService.ts but never read. Today baseURL is hardcoded, so anything other than an Individual subscription talks to a host its token does not belong to.

2. Enterprise deployments serve OAuth and token exchange from their own domain. DEVICE_CODE_URL, ACCESS_TOKEN_URL and COPILOT_TOKEN_URL all point at github.com / api.github.com, so on a GitHub Enterprise Server or GHE.com account sign-in cannot complete at all.

What the branch does

Resolves the inference host per request, most authoritative source first:

  1. endpoints.api from the token response (declared, previously unused)
  2. the proxy-ep field inside the token — survives a restart, since the token is persisted
  3. the configured deployment, else the existing github.com default

This is applied inside getCopilotFetch() rather than the constructor, because the OpenAI SDK pins baseURL at construction time — before any token exists, and it would never pick up a host change on refresh.

Adds an optional githubCopilotEnterpriseDomain setting (a field next to the existing custom client ID, empty = github.com). Device-flow and token-exchange URLs are derived from it, and it handles both Enterprise conventions, which differ:

Deployment Token exchange
github.com https://api.github.com/copilot_internal/v2/token
GHE.com (Enterprise Cloud, data residency) https://api.<domain>/copilot_internal/v2/token
GitHub Enterprise Server (self-hosted) https://<host>/api/v3/copilot_internal/v2/token

Input is normalized, so pasting https://github.acme.com/ or github.acme.com both work.

Defaults are unchanged. An empty domain reproduces the previous URLs exactly, so existing Individual setups are byte-for-byte unaffected — the only behavioural change for them is that the host now comes from their own token instead of a constant, which resolves to the same value.

Verification

npm run typecheck clean, eslint clean on the five touched files, production build succeeds. URL construction and proxy-ep extraction checked for github.com, GHES and GHE.com.

What I have not done: run it against a live Enterprise instance. The endpoint shapes follow GitHub's documented conventions (/api/v3 for GHES, api. subdomain for GHE.com), but they are not yet confirmed end-to-end. I do have access to a GitHub Enterprise Server instance and I'm happy to test the branch there and report back before you take any of it — just say the word and I'll do that first.

Tests

Same situation as #78: there are no *.test.ts files in this repository, so I couldn't extend the suite. normalizeEnterpriseDomain(), copilotEndpoints() and apiBaseFromCopilotToken() are exported as pure functions specifically so they're trivial to unit test — happy to write those if you tell me where they should live to match your private tree.

Smaller thing spotted nearby

CopilotTokenResponse.endpoints was typed but never read. The branch now uses it as the first-choice host; if it was left unused deliberately, drop that line and the proxy-ep fallback still covers every case I could find.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions