Skip to content

Harden Copilot proxy auth normalization to avoid malformed Authorization headers#3322

Merged
lpcox merged 2 commits into
mainfrom
copilot/awf-api-proxy-fix-auth-header
May 18, 2026
Merged

Harden Copilot proxy auth normalization to avoid malformed Authorization headers#3322
lpcox merged 2 commits into
mainfrom
copilot/awf-api-proxy-fix-auth-header

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 18, 2026

Copilot requests routed through the AWF API proxy could fail with 400 bad request: Authorization header is badly formatted when the sidecar received non-credential placeholder/dummy BYOK values or pre-prefixed auth tokens. This change tightens Copilot auth token normalization and fallback behavior so injected headers are consistently valid.

  • Auth token normalization

    • stripBearerPrefix now normalizes both Bearer <token> and token <token> inputs (case-insensitive), preventing malformed forwarded headers from prefix artifacts.
  • Placeholder/dummy BYOK handling

    • Treats COPILOT_API_KEY=dummy-byok-key-for-offline-mode as non-credential input (same class as the AWF placeholder token), so the adapter does not use it as upstream auth material.
    • Falls back to COPILOT_GITHUB_TOKEN when a real BYOK key is absent.
  • Regression coverage

    • Added auth-unit assertions for:
      • token prefix stripping
      • ignoring offline dummy BYOK key
      • fallback resolution to GitHub token when dummy key is present
function stripBearerPrefix(value) {
  return ((value || '').replace(/^\s*(?:Bearer|token)\s+/i, '').trim()) || undefined;
}

function resolveApiKey(env) {
  const key = stripBearerPrefix(env.COPILOT_API_KEY);
  return key === COPILOT_PLACEHOLDER_TOKEN || key === COPILOT_DUMMY_BYOK_KEY ? undefined : key;
}

Copilot AI changed the title [WIP] Fix malformed Authorization header in API proxy Harden Copilot proxy auth normalization to avoid malformed Authorization headers May 18, 2026
Copilot AI requested a review from lpcox May 18, 2026 13:59
Copilot finished work on behalf of lpcox May 18, 2026 13:59
@lpcox lpcox marked this pull request as ready for review May 18, 2026 14:48
@lpcox lpcox requested a review from Mossaka as a code owner May 18, 2026 14:48
Copilot AI review requested due to automatic review settings May 18, 2026 14:48
@github-actions github-actions Bot mentioned this pull request May 18, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Smoke Test Results

Test Status
GitHub MCP connectivity ⚠️ 401 (MCP token scope)
GitHub.com HTTP connectivity ✅ (pre-step file confirmed)
File write/read /tmp/gh-aw/agent/smoke-test-copilot-26038197704.txt exists

Overall: PASS — Pre-step smoke file confirmed: Smoke test passed for Copilot at Mon May 18 14:49:34 UTC 2026

Note: GitHub MCP returned 401 (read-only token limitation in this environment), but all other checks passed.

📰 BREAKING: Report filed by Smoke Copilot

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

❌ Test 1 (GitHub API): gh CLI authentication failed — network/firewall constraint
✅ Test 2 (Playwright): GitHub.com navigation and title verification passed
✅ Test 3 (File verify): Smoke test file /tmp/gh-aw/agent/smoke-test-claude-26038197767.txt found with valid content

Summary: 2/3 tests passed. GitHub API test failed due to network constraints in the AWF sandbox environment.

💥 [THE END] — Illustrated by Smoke Claude

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results (Gemini)

  • GitHub MCP Testing: ❌ (Tool mcpscripts not found)
  • GitHub.com Connectivity: ❌ (SSL error 000)
  • File Writing Testing: ✅
  • Bash Tool Testing: ✅

Overall status: FAIL

PR Titles: N/A (Failed to retrieve)

Warning

Firewall blocked 1 domain

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

  • localhost

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

network:
  allowed:
    - defaults
    - "localhost"

See Network Configuration for more information.

💎 Faceted by Smoke Gemini

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens GitHub Copilot provider auth handling in the api-proxy sidecar to prevent malformed Authorization headers and to correctly ignore non-credential placeholder/dummy BYOK values, reducing 400s from upstream providers.

Changes:

  • Extend auth token normalization to strip both Bearer and token prefixes (case-insensitive).
  • Treat COPILOT_API_KEY=dummy-byok-key-for-offline-mode as a non-credential sentinel (like the AWF placeholder), falling back to COPILOT_GITHUB_TOKEN.
  • Add regression tests covering token stripping and dummy BYOK fallback behavior.
Show a summary per file
File Description
containers/api-proxy/providers/copilot.js Expands token prefix stripping and ignores the offline dummy BYOK key during API key resolution.
containers/api-proxy/server.auth.test.js Adds unit coverage for token prefix stripping and dummy BYOK sentinel fallback/ignoring behavior.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment on lines 63 to 66
function resolveApiKey(env) {
const key = stripBearerPrefix(env.COPILOT_API_KEY);
return key === COPILOT_PLACEHOLDER_TOKEN ? undefined : key;
return key === COPILOT_PLACEHOLDER_TOKEN || key === COPILOT_DUMMY_BYOK_KEY ? undefined : key;
}
Comment on lines 49 to 51
function stripBearerPrefix(value) {
return ((value || '').replace(/^\s*Bearer\s+/i, '').trim()) || undefined;
return ((value || '').replace(/^\s*(?:Bearer|token)\s+/i, '').trim()) || undefined;
}
@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Offline) Mode

Test Result
GitHub MCP connectivity ❌ 401 Bad credentials
GitHub.com HTTP ⚠️ Pre-step data unavailable (template not expanded)
File write/read ⚠️ Pre-step data unavailable (template not expanded)
BYOK inference (api-proxy → api.githubcopilot.com)

Running in BYOK offline mode (COPILOT_OFFLINE=true) via api-proxy → api.githubcopilot.com.

Overall: FAIL — GitHub MCP returned 401; pre-step smoke data template variables were not expanded.

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions
Copy link
Copy Markdown
Contributor

Overall status: FAIL
PR titles: fix: resolve test failures on macOS; fix: postprocess claude-token-optimizer lock file to use local awf build
✅ GitHub MCP PR review
❌ Safe Inputs GH CLI
✅ Playwright title
❌ Tavily search
✅ File writing
✅ Bash file read
❌ Discussion interaction
✅ AWF build

Warning

Firewall blocked 1 domain

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

  • registry.npmjs.org

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

network:
  allowed:
    - defaults
    - "registry.npmjs.org"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex

@github-actions
Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3 ❌ NO
Node.js v24.15.0 v20.20.2 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: ❌ FAILED — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot

@github-actions
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 ✅ PASS
.NET json-parse N/A ✅ 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 all passed ✅ PASS
Node.js execa all passed ✅ PASS
Node.js p-limit all passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Generated by Build Test Suite for issue #3322 · ● 3M ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results — FAIL

Check Result
Redis PING ❌ timeout (no response)
PostgreSQL pg_isready ❌ no response
PostgreSQL SELECT 1 ❌ skipped (pg_isready failed)

host.docker.internal is unreachable from this runner — service containers are not accessible. Overall: FAIL

🔌 Service connectivity validated by Smoke Services

@lpcox lpcox merged commit 4865f82 into main May 18, 2026
67 of 74 checks passed
@lpcox lpcox deleted the copilot/awf-api-proxy-fix-auth-header branch May 18, 2026 15:21
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.

[awf] API Proxy: Copilot engine fails with malformed Authorization header

3 participants