Refactor shared OIDC runtime auth flow for OpenAI and Copilot adapters#4948
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the API proxy’s OIDC runtime authentication logic to eliminate duplicated, security-sensitive behavior across the OpenAI and Copilot provider adapters by centralizing shared enablement/provider-access methods and the OIDC header resolution path into proxy-utils.js, and adding unit tests for the new utilities.
Changes:
- Added shared OIDC runtime adapter helpers (
createOidcRuntimeAdapterMethods,resolveOidcAuthHeaders) tocontainers/api-proxy/proxy-utils.js. - Updated
openai.jsandcopilot.jsadapters to reuse the shared OIDC methods and centralized header resolution while keeping provider-specific static fallback/header shaping. - Added focused Jest coverage for the new OIDC utility helpers in
proxy-utils.oidc.test.js.
Show a summary per file
| File | Description |
|---|---|
| containers/api-proxy/proxy-utils.oidc.test.js | Adds unit tests covering the new shared OIDC runtime methods and header resolution outcomes. |
| containers/api-proxy/proxy-utils.js | Introduces shared OIDC runtime adapter methods and centralized OIDC auth header resolution helper. |
| containers/api-proxy/providers/openai.js | Replaces duplicated OIDC enablement/header logic with shared helpers while preserving OpenAI-specific header behavior. |
| containers/api-proxy/providers/copilot.js | Replaces duplicated OIDC enablement/header logic with shared helpers while preserving Copilot-specific header behavior. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 4/4 changed files
- Comments generated: 2
| it('returns an empty object for AWS OIDC request-signing flow', () => { | ||
| const headers = resolveOidcAuthHeaders({ | ||
| oidcProvider: null, | ||
| awsOidcProvider: { isReady: () => true }, | ||
| buildOidcHeaders: () => ({ Authorization: 'ignored-token' }), | ||
| }); | ||
|
|
||
| expect(headers).toEqual({}); | ||
| }); | ||
|
|
||
| it('returns null when OIDC is not configured', () => { | ||
| const headers = resolveOidcAuthHeaders({ | ||
| oidcProvider: null, | ||
| awsOidcProvider: null, | ||
| buildOidcHeaders: () => ({ Authorization: 'ignored-token' }), | ||
| }); | ||
|
|
||
| expect(headers).toBeNull(); | ||
| }); |
| // we surface a non-empty marker here to keep alwaysBind/isEnabled probes happy and | ||
| // resolve the real token lazily inside getAuthHeaders. | ||
| const authToken = staticAuthToken; | ||
| const oidcRuntimeMethods = createOidcRuntimeAdapterMethods({ | ||
| staticAuthToken: authToken, |
- Add test: bearer OIDC takes precedence over AWS OIDC when both configured - Update copilot.js comment: authToken is typically undefined in OIDC mode, enablement is handled by oidcConfigured (not a 'non-empty marker') Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (1 files)
Coverage comparison generated by |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Smoke Test: Copilot BYOK (Direct) Mode — Azure OpenAI (Foundry, api-key)
Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) Overall: PASS
|
🔬 Smoke Test Results — PASS
PR: Refactor shared OIDC runtime auth flow for OpenAI and Copilot adapters Overall: PASS
|
|
Smoke test — Auth mode: PAT (
Overall: FAIL
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
• 🔍 MCP API: ✅ 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: PASS
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Smoke Test: Copilot BYOK (Direct Mode) ✅ PASS✅ GitHub MCP connectivity — listed 2 recent closed PRs successfully Mode: Direct BYOK (COPILOT_PROVIDER_API_KEY) via api-proxy sidecar → api.githubcopilot.com
|
|
Reviewed merged PRs:
|
Chroot Version Comparison — Smoke Test Results
Overall: ❌ Tests did not pass — Python and Node.js versions differ between host and chroot environments.
|
Smoke Test: API Proxy OpenTelemetry Tracing
Overall: ✅ All functional scenarios pass. Scenario 5 is expected-pending (file fallback active; no collector endpoint wired for this PR run).
|
Smoke Test: GitHub Actions Services Connectivity
Overall: ❌ FAIL
|
Smoke Test: Gemini
Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "localhost"See Network Configuration for more information.
|
|
GitHub API: ✅ PASS Total: PASS
|
The API proxy still duplicated OIDC runtime adapter logic between
openai.jsandcopilot.jsafter provider initialization was centralized. This left security-critical token/header behavior split across multiple files.Consolidate OIDC runtime adapter methods
createOidcRuntimeAdapterMethods(...)incontainers/api-proxy/proxy-utils.jsto centralize:isEnabled()OIDC-aware readiness checkgetOidcProvider()getAwsOidcProvider()Consolidate OIDC header resolution path
resolveOidcAuthHeaders(...)incontainers/api-proxy/proxy-utils.jsto centralize:oidcProvider.getToken())null) for static-auth fallbackopenai.jsandcopilot.jsnow pass provider-specific header builders and keep only their static fallback behavior.Add focused utility coverage
containers/api-proxy/proxy-utils.oidc.test.jsfor: