refactor(api-proxy): dedupe Azure OIDC helpers via shared github-oidc module#2887
Conversation
✅ 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.
There was a problem hiding this comment.
Pull request overview
This PR refactors the Azure OidcTokenProvider in containers/api-proxy to eliminate duplicated GitHub Actions OIDC minting / HTTP / proxy logic by delegating to the shared github-oidc helper module, aligning Azure with the existing AWS/GCP paths.
Changes:
- Replaced Azure’s in-file GitHub OIDC mint + HTTP/proxy helper implementations with calls into
containers/api-proxy/github-oidc.js. - Kept the Azure provider’s public/class method surface while switching implementation to shared helpers.
- Added a regression test asserting the GitHub OIDC mint request includes the configured
audiencequery parameter and the expectedAuthorizationheader.
Show a summary per file
| File | Description |
|---|---|
| containers/api-proxy/oidc-token-provider.js | Refactors Azure OIDC minting + HTTP/proxy helpers to delegate to the shared github-oidc module. |
| containers/api-proxy/oidc-token-provider.test.js | Adds a focused regression test to validate the GitHub OIDC mint request contract (audience + auth header). |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
containers/api-proxy/oidc-token-provider.js:273
- Similar to _httpGet(), _getProxyAgent() is now unused within this class/repo after moving proxy handling into github-oidc.js. If it’s not meant as a supported override point, consider removing it to avoid dead code.
/**
* Build proxy agent from env vars when configured.
* @param {URL} parsedUrl
* @returns {import('http').Agent|undefined}
*/
_getProxyAgent(parsedUrl) {
return getProxyAgent(parsedUrl);
}
- Files reviewed: 2/2 changed files
- Comments generated: 3
| _httpPost(url, body, headers) { | ||
| return new Promise((resolve, reject) => { | ||
| const parsedUrl = new URL(url); | ||
| const options = { | ||
| method: 'POST', | ||
| hostname: parsedUrl.hostname, | ||
| port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80), | ||
| path: parsedUrl.pathname + parsedUrl.search, | ||
| headers: { ...headers, 'Content-Length': Buffer.byteLength(body) }, | ||
| agent: this._getProxyAgent(parsedUrl), | ||
| }; | ||
|
|
||
| const mod = parsedUrl.protocol === 'https:' ? https : http; | ||
| const req = mod.request(options, (res) => { | ||
| let responseBody = ''; | ||
| res.on('data', (chunk) => { responseBody += chunk; }); | ||
| res.on('end', () => resolve({ statusCode: res.statusCode, body: responseBody })); | ||
| }); | ||
| req.on('error', reject); | ||
| req.setTimeout(10_000, () => { req.destroy(new Error('Azure token exchange timeout')); }); | ||
| req.write(body); | ||
| req.end(); | ||
| }); | ||
| return httpPost(url, body, headers); | ||
| } |
| req.setTimeout(10_000, () => { req.destroy(new Error('OIDC request timeout')); }); | ||
| }); | ||
| return httpGet(url, headers); | ||
| } |
|
|
||
| await new Promise(resolve => oidcServer.listen(0, '127.0.0.1', resolve)); | ||
| const oidcPort = oidcServer.address().port; | ||
|
|
||
| const provider = new OidcTokenProvider({ | ||
| requestUrl: `http://127.0.0.1:${oidcPort}/token`, | ||
| requestToken: 'custom-request-token', | ||
| tenantId: 'test', | ||
| clientId: 'test', | ||
| oidcAudience: 'api://custom-audience', | ||
| }); | ||
|
|
||
| const token = await provider._mintGitHubOidcToken(); | ||
| expect(token).toBe('jwt-from-github'); | ||
|
|
||
| provider.shutdown(); | ||
| await new Promise(resolve => oidcServer.close(resolve)); |
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.
|
@copilot address review feedback |
Addressed in commit
|
Smoke Test Results
Status: FAIL (gh CLI authentication issue)
|
Smoke Test: Copilot BYOK (Offline) Mode
Running in BYOK offline mode ( Overall: FAIL — GitHub MCP returned 401; pre-step template variables were not expanded (smoke-data step outputs missing).
|
🔬 Smoke Test Results — PR #2887
Overall: PARTIAL — pre-step template variables were not substituted into the agent prompt, so HTTP code and PR data could not be validated. File test passed. MCP auth unavailable in this context.
|
🧪 Chroot Version Comparison Results
Result: Not all tests passed — Python and Node.js versions differ between host and chroot. The
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS
|
|
Smoke test: FAIL Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "registry.npmjs.org"See Network Configuration for more information.
|
Smoke Test Results
Overall: FAIL —
|
The OIDC refactoring PRs (#2811, #2772, #2887) added new JS modules (github-oidc.js, aws-oidc-token-provider.js, gcp-oidc-token-provider.js, oidc-refresh-utils.js) but did not update the Dockerfile COPY command. This caused the api-proxy container to crash immediately on startup with exit code 1 (Cannot find module './github-oidc'), breaking all integration tests since commit 7c25298. Fixes the api-proxy container startup crash that has been failing all integration test runs on main since 2026-05-11T15:45Z. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… retry handling (#2895) * Initial plan * fix: reduce pid-tracker public API surface * docs: fix stale pid tracker jsdoc * fix: retry api-proxy startup when compose reports exited (1) Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/fcf2b573-5256-4c69-8f65-0a79431bd838 * fix(api-proxy): add missing JS modules to Dockerfile COPY The OIDC refactoring PRs (#2811, #2772, #2887) added new JS modules (github-oidc.js, aws-oidc-token-provider.js, gcp-oidc-token-provider.js, oidc-refresh-utils.js) but did not update the Dockerfile COPY command. This caused the api-proxy container to crash immediately on startup with exit code 1 (Cannot find module './github-oidc'), breaking all integration tests since commit 7c25298. Fixes the api-proxy container startup crash that has been failing all integration test runs on main since 2026-05-11T15:45Z. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: restore missing pid-tracker test cases for coverage Add back tests for malformed /proc/net/tcp rows and non-symlink file descriptors that were removed when the async trackPidForPort was dropped. These paths are still exercised in production via trackPidForPortSync and need coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Landon Cox <landon.cox@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bug Fix
OidcTokenProviderin the Azure path was maintaining a second copy of GitHub OIDC minting/HTTP/proxy helper logic already centralized ingithub-oidc.js. This change removes that duplicate security-critical implementation so Azure, AWS, and GCP all share the same canonical helper behavior.What was the bug?
Duplicate helper implementations in
containers/api-proxy/oidc-token-provider.js(_mintGitHubOidcToken,_httpGet,_httpPost,_getProxyAgent) created drift risk in OIDC token minting and transport handling.How did you fix it?
Shared helper consolidation
containers/api-proxy/github-oidc.js.Preserved Azure-specific timeout context
httpPosttimeout errors in_exchangeForAzureTokenso Azure paths continue to emitAzure token exchange timeoutfor actionable logs/errors.Dead code removal
_httpGetand_getProxyAgentwrappers after delegating GitHub minting to shared helpers.Regression guards
oidc-token-provider.test.jsasserting Azure mint flow sends:audiencequery paramAuthorization: Bearer <request token>headertry/finallycleanup to always shut down server/provider.