Skip to content

Fix Copilot proxy auth and GHEC model discovery - #8038

Merged
lpcox merged 3 commits into
mainfrom
copilot/fix-copilot-proxy-regressions
Sep 3, 2026
Merged

Fix Copilot proxy auth and GHEC model discovery#8038
lpcox merged 3 commits into
mainfrom
copilot/fix-copilot-proxy-regressions

Conversation

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fine-grained GitHub PATs were sent with the target-selected token scheme on Business, Enterprise, and GHEC endpoints. Canonical GHEC targets also missed GitHub-hosted model-discovery handling, while a legacy isolation placeholder could override the real GitHub credential for inference.

  • Credential selection

    • Classify resolved GitHub credentials before selecting the Authorization scheme.
    • Use Bearer for github_pat_ fine-grained PATs on every Copilot target.
    • Preserve existing token behavior for OAuth and classic PATs on applicable targets.
    • Reject placeholder-token-for-credential-isolation alongside current and offline BYOK placeholders.
  • GHEC request shape

    • Treat canonical copilot-api.<tenant>.ghe.com targets as GitHub-hosted catalog endpoints.
    • Apply X-GitHub-Api-Version: 2026-07-01 to startup and proxied /models.
    • Resolve integration identity from COPILOT_INTEGRATION_ID, then GITHUB_COPILOT_INTEGRATION_ID, then the default.
    • Preserve Copilot-Integration-Id for GHEC without synthesizing interaction headers.
  • Safe diagnostics

    • Reflect credential kind, selected scheme, inference credential source, and integration-ID source without credential material.
const githubTokenAuthPrefix = getGitHubTokenAuthPrefix(githubToken, rawTarget, env);
// github_pat_* → ****** OAuth/classic PAT → token only where the target requires it

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix Copilot proxy handling of fine-grained PATs and legacy provider placeholders Fix Copilot proxy auth and GHEC model discovery Sep 2, 2026
Copilot AI requested a review from lpcox September 2, 2026 21:15
@lpcox
lpcox marked this pull request as ready for review September 2, 2026 21:55
Copilot AI balanced review requested due to automatic review settings September 2, 2026 21:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Three moderate issues leave integration-ID precedence, diagnostics, and GHEC header preservation incomplete.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes Copilot authentication, GHEC model discovery, placeholder handling, and safe diagnostics.

Changes:

  • Selects authorization schemes by credential type.
  • Adds canonical GHEC request handling and integration identity support.
  • Rejects legacy credential-isolation placeholders.
  • Adds targeted regression tests.

Required fixes:

  • Forward GITHUB_COPILOT_INTEGRATION_ID into the sidecar environment.
  • Expose the new diagnostic fields through the management /reflect response.
  • Preserve caller-provided, case-variant integration IDs on GHEC requests.
File summaries
File Description
containers/api-proxy/request-headers.test.js Tests GHEC integration headers.
containers/api-proxy/request-headers.js Recognizes GHEC hosts; integration-ID deduplication needs correction.
containers/api-proxy/providers/copilot.js Updates authentication, discovery, identity, and diagnostics; environment forwarding and reflection output remain incomplete.
containers/api-proxy/providers/copilot-auth.js Classifies credentials and rejects legacy placeholders.
containers/api-proxy/copilot-auth.test.js Tests credential resolution and authorization schemes.
containers/api-proxy/copilot-adapter-enterprise.test.js Adds GHEC and fine-grained PAT regression coverage.
Review details

Suppressed comments (1)

containers/api-proxy/providers/copilot.js:194

  • When Copilot uses an OIDC provider, resolveHeaders() sends a Bearer OIDC token, but these static values report credential_kind: none, inference_credential_source: none, and can even report token as the scheme on a GHES-classified target. Make the reflected values depend on oidcConfigured/authProvider; otherwise the new safe diagnostics misdescribe the credential actually used for inference.
        credential_kind: apiKey ? 'byok' : githubToken && githubToken.startsWith('github_pat_') ? 'fine_grained_pat' : githubToken ? 'github_token' : 'none',
        selected_scheme: authPrefix,
        inference_credential_source: inferenceCredentialSource,
        inference_selected_scheme: authPrefix,
  • Files reviewed: 6/6 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +81 to +83
const integrationId = (env.COPILOT_INTEGRATION_ID || '').trim()
|| (env.GITHUB_COPILOT_INTEGRATION_ID || '').trim()
|| 'agentic-workflows';
modelsPath,
reflectionConfigured: !!authToken || oidcConfigured,
reflectionModelsPath: modelsPath,
reflectionExtra: {
Comment thread containers/api-proxy/request-headers.js Outdated
Comment on lines 94 to 97
const copilotHost = isCopilotIntegrationHost(targetHost);
for (const [name, value] of Object.entries(injectHeaders)) {
if (!copilotHost && name.toLowerCase() === 'copilot-integration-id') continue;
headers[name] = value;
@lpcox

lpcox commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

@copilot address review feedback

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address review feedback

Addressed all three review items in commit 09159cf: forwarded GITHUB_COPILOT_INTEGRATION_ID, preserved case-insensitive caller integration IDs for GHEC, and exposed the safe Copilot diagnostics through /reflect. Targeted and full API proxy tests pass.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

✅ Copilot review passed with no inline comments.

@copilot Add the ready-for-aw label to this PR to trigger agentic CI smoke tests.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • example.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "example.com"

See Network Configuration for more information.

🛡️ Egress verdict from Smoke Copilot Network Isolation

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Build Test Suite completed successfully!

Generated by Build Test Suite for #8038

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

Tested by Smoke Chroot

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — All services reachable! ✅

🔌 Service connectivity validated by Smoke Services

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Smoke Gemini reports failed. Facets need polishing...

💎 Faceted by Smoke Gemini

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Contribution Check failed. Please review the logs for details.

Generated by Contribution Check for #8038

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅

📡 OTel tracing validated by Smoke OTel Tracing

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

📰 VERDICT: Smoke Docker Sbx has concluded. All systems operational. This is a developing story. 🎤

📰 BREAKING: Report filed by Smoke Docker Sbx

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Security Guard completed successfully!

Security review complete: PR #8038 contains no security vulnerabilities. The changes improve Copilot proxy auth handling (fine-grained PAT detection, GHEC model discovery, legacy placeholder filtering) while maintaining existing security boundaries. All 4 security-relevant files show defensive improvements with no weakened DROP/REJECT, expanded ACCEPT, auth regressions, or capability additions.

Generated by Security Guard for #8038

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Smoke Claude passed

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.anthropic.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.anthropic.com"

See Network Configuration for more information.

Generated by Smoke Claude for #8038

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Claude Engine Validation

Check Status
API ✅ PASS
gh CLI ✅ PASS
File ✅ PASS

Overall result: PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • api.anthropic.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.anthropic.com"

See Network Configuration for more information.

Generated by Smoke Claude for #8038 · claude · haiku45 · 58.3 AIC · ⊞ 4.5K ·
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct Mode) ✅ PASS

Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY) with api-proxy sidecar injection.

🔑 BYOK report filed by Smoke Copilot BYOK
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

@lpcox Egress smoke test results:

EGRESS_RESULT allow=pass deny=pass

✅ Allowed domain (github.com) reachable — allowed=200
✅ Blocked domain (example.com) denied — CONNECT tunnel 403

Overall: PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • example.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "example.com"

See Network Configuration for more information.

🛡️ Egress verdict from Smoke Copilot Network Isolation
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Services Connectivity

  • Redis PING: ❌ (name resolution failure: host.docker.internal)
  • PostgreSQL pg_isready: ❌ (no response, same DNS failure)
  • PostgreSQL SELECT 1: ❌ (could not translate host name)

Overall: FAILhost.docker.internal could not be resolved from the AWF sandbox, blocking all connectivity checks.

🔌 Service connectivity validated by Smoke Services
Add label ready-for-aw to run again

@github-actions github-actions Bot added the smoke-copilot-network-isolation Copilot network-isolation egress smoke test label Sep 3, 2026
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot Engine@lpcox

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.14 Python 3.12.14 ✅ YES
Node.js v24.19.0 v2.98.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: FAILED — Node.js version mismatch between host and chroot environments (host: v24.19.0, chroot: v2.98.0). The smoke-chroot label was not applied since not all tests passed.

Tested by Smoke Chroot
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Docker Sbx Smoke Test

Overall: PASS

cc @lpcox (author)

📰 BREAKING: Report filed by Smoke Docker Sbx
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

PR titles:

  • Fix Copilot proxy auth and GHEC model discovery
  • test: organize Cloud Hypervisor manager tests by feature

GitHub merged PR review: ✅
safeinputs-gh query: ❌ (safeinputs-gh missing)
Playwright title: ✅
File write/readback: ✅
Discussion step: ❌ (discussion comments disabled)
Build AWF: ✅
Overall: FAIL

Warning

Firewall blocked 7 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • msfeed25.pkgs.visualstudio.com
  • www.google.com
  • www.gstatic.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "msfeed25.pkgs.visualstudio.com"
    - "www.google.com"
    - "www.gstatic.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A (ran, output correct) ✅ PASS
.NET json-parse N/A (ran, output correct) ✅ PASS
Go color 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx passed ✅ PASS
Node.js execa passed ✅ PASS
Node.js p-limit passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — PASS

Notes:

  • Java: Maven's default ~/.m2 directory was root-owned and not writable by the runner user, so -Dmaven.repo.local was pointed at a writable temp directory as a local workaround; the proxy settings from ~/.m2/settings.xml were still applied via JAVA_TOOL_OPTIONS/proxy config and all builds/tests succeeded through the firewall proxy.
  • No clone failures across any of the 8 test repositories.

Generated by Build Test Suite for #8038 · copilot · auto · 31.1 AIC · ⊞ 12K ·
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

GitHub MCP Testing (#8026, #8021): ❌ (got #8038, #8025)
GitHub.com Connectivity: ✅
File I/O Test: ✅
BYOK Inference Test: ✅

Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw)

FAIL

cc @lpcox @Copilot

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: API Proxy OTel Tracing — Results

  • Scenario 1 (Module Loading): otel.js loads successfully; isEnabled() returns true; exports include startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled, plus OTLP exporter/fan-out internals.
  • Scenario 2 (Test Suite): 3 suites / 68 tests passed (otel.test.js, otel-fanout.test.js, otel-workload-identity.test.js).
  • Scenario 3 (Env Var Forwarding): env-passthrough.ts forwards GITHUB_AW_OTEL_TRACE_ID and GITHUB_AW_OTEL_PARENT_SPAN_ID to the agent; api-proxy-env-config.ts forwards GH_AW_OTLP_ENDPOINTS, OTEL_EXPORTER_OTLP_ENDPOINT, and both trace-context vars to the api-proxy sidecar.
  • Scenario 4 (Token Tracker Integration): token-tracker-http.js implements the onUsage callback hook used by OTEL to set gen_ai.usage.* span attributes.
  • ⚠️ Scenario 5 (OTEL Diagnostics): No api-proxy-specific otel.jsonl/token-usage.jsonl was found under /tmp/gh-aw/sandbox/firewall/logs/api-proxy/ (api-proxy sidecar wasn't invoked for real LLM traffic in this smoke run). The workflow-level /tmp/gh-aw/otel.jsonl does contain an exported gh-aw.agent.setup span, confirming OTLP export plumbing works end-to-end through Squid. This is expected — the smoke test validates code paths/config rather than exercising live agent LLM calls.

Overall: PASS — all implemented scenarios succeeded; Scenario 5's absence of api-proxy-specific spans is expected given no live proxied LLM request occurred in this run.

📡 OTel tracing validated by Smoke OTel Tracing
Add label ready-for-aw to run again

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

GitHub MCP connectivity: ✅
GitHub.com connectivity: ✅
File write/read test: ✅
BYOK inference test: ✅

Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra

Overall status: PASS

/cc @Copilot @lpcox

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)
Add label ready-for-aw to run again

@lpcox
lpcox merged commit b7e426a into main Sep 3, 2026
178 of 182 checks passed
@lpcox
lpcox deleted the copilot/fix-copilot-proxy-regressions branch September 3, 2026 00:21
github-actions Bot added a commit that referenced this pull request Sep 3, 2026
…d GITHUB_COPILOT_INTEGRATION_ID fallback

Corrects docs/auth-matrix.md and docs/environment.md to reflect PR #8038
(Fix Copilot proxy auth and GHEC model discovery, merged 2026-09-02):

- COPILOT_GITHUB_TOKEN values starting with github_pat_ (fine-grained
  PATs) now always use the Bearer auth prefix on every Copilot target
  (github.com, GHEC, GHES, Business), overriding the previous
  target-based token/Bearer selection that still applies to classic
  PATs and OAuth tokens.
- Copilot-Integration-Id now also falls back to
  GITHUB_COPILOT_INTEGRATION_ID when COPILOT_INTEGRATION_ID is unset.
- Cross-referenced the stronger fine-grained-PAT guarantee from the
  existing Classic PAT + COPILOT_MODEL remediation guidance in
  docs/environment.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
lpcox pushed a commit that referenced this pull request Sep 3, 2026
…d GITHUB_COPILOT_INTEGRATION_ID fallback (#8055)

Corrects docs/auth-matrix.md and docs/environment.md to reflect PR #8038
(Fix Copilot proxy auth and GHEC model discovery, merged 2026-09-02):

- COPILOT_GITHUB_TOKEN values starting with github_pat_ (fine-grained
  PATs) now always use the Bearer auth prefix on every Copilot target
  (github.com, GHEC, GHES, Business), overriding the previous
  target-based token/Bearer selection that still applies to classic
  PATs and OAuth tokens.
- Copilot-Integration-Id now also falls back to
  GITHUB_COPILOT_INTEGRATION_ID when COPILOT_INTEGRATION_ID is unset.
- Cross-referenced the stronger fine-grained-PAT guarantee from the
  existing Classic PAT + COPILOT_MODEL remediation guidance in
  docs/environment.md.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Copilot proxy mishandles fine-grained PATs and legacy provider placeholders on GHEC data-residency endpoints

3 participants