Repository navigation
Preserve custom BYOK ports through API proxy and Squid - #10776
Conversation
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
|
|
||
| if (parsed.kind === 'ok') { | ||
| if (parsed.pathname !== '/' || parsed.search || parsed.hash || parsed.username || parsed.password || parsed.port) { | ||
| if (parsed.pathname !== '/' || parsed.search || parsed.hash || parsed.username || parsed.password) { |
There was a problem hiding this comment.
Fixed in 76b74f4: the warning now logs only the parsed scheme, hostname, and port, never the path, query, fragment, or credentials.
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Requests to custom upstream ports already in Safe_ports can bypass blocked-domain and DLP protections by falling through to a broader allow rule.
3 open issues
What changed in this PR
This PR adds end-to-end custom-port support across AWF’s runner configuration, API proxy, and Squid policy, addressing BYOK endpoints such as Ollama on port 11434.
Changes:
- Preserve provider schemes, explicit ports, and base paths through routing, discovery, validation, and WebSockets.
- Add trusted API-proxy hostname/port exceptions to Squid and its policy manifest.
- Expand regression coverage and document the new endpoint support.
| File | Description |
|---|---|
tests/integration/api-proxy.test.ts |
Exercise protected BYOK routing and denied access. |
src/types/squid.ts |
Define configured API-proxy upstream tuples. |
src/test-helpers/config-writer-dependency-mocks.test-utils.ts |
Use real target normalization in mocks. |
src/squid/policy-manifest.ts |
Record custom-upstream policy exceptions. |
src/squid/config-generator.ts |
Insert upstream exceptions before port checks. |
src/squid/api-proxy-upstreams.ts |
Generate source-scoped hostname/port access rules. |
src/squid/api-proxy-upstreams.test.ts |
Cover exception scope, guards, and validation. |
src/services/api-proxy-upstreams.test.ts |
Cover effective routing and configuration precedence. |
src/services/api-proxy-env-config.ts |
Align sidecar routing with Squid upstreams. |
src/openai-base-url-env.ts |
Accept HTTP and preserve explicit ports. |
src/openai-base-url-env.test.ts |
Verify HTTP and custom-port endpoint resolution. |
src/host-env.ts |
Preserve ports during runner-side normalization. |
src/docker-manager-string-utils.test.ts |
Update HTTP port-preservation expectations. |
src/copilot-api-resolver.test.ts |
Update scheme and authority expectations. |
src/copilot-api-resolver.internal.ts |
Preserve Copilot provider schemes and ports. |
src/config-writer.ts |
Pass upstreams to policy generation; redact audits. |
src/config-writer.test.ts |
Cover upstream propagation and audit redaction. |
src/cli.test.ts |
Update derived Copilot target expectations. |
docs/awf-config-spec.md |
Document HTTP and custom-port endpoint requirements. |
containers/api-proxy/websocket-tunnel.test.js |
Verify custom-port CONNECT and upgrade handling. |
containers/api-proxy/websocket-tunnel.js |
Separate tunnel authority from TLS hostname. |
containers/api-proxy/upstream-http.test.js |
Cover explicit and default request ports. |
containers/api-proxy/upstream-http.js |
Dial upstream hostname and port separately. |
containers/api-proxy/server.target-ports.test.js |
Cover provider ports and protected request forwarding. |
containers/api-proxy/server.routing.test.js |
Verify normalization, discovery, and validation URLs. |
containers/api-proxy/request-headers.test.js |
Cover Copilot header scoping with ports. |
containers/api-proxy/request-headers.js |
Check provider identity using hostname only. |
containers/api-proxy/proxy-utils.js |
Preserve authorities and expose hostname extraction. |
containers/api-proxy/providers/copilot.js |
Preserve schemes in Copilot models URLs. |
containers/api-proxy/providers/copilot-auth.js |
Exclude ports from Copilot identity checks. |
containers/api-proxy/model-discovery.proxy-agent.test.js |
Verify custom discovery ports through the proxy. |
Review effort: Max
| lines.push( | ||
| `http_access allow api_upstream_source ${acl}_host ${acl}_port${guards ? ` ${guards}` : ''}${config.enableDlp ? ' !dlp_blocked' : ''}` | ||
| ); |
There was a problem hiding this comment.
Fixed in 76b74f4: source/hostname/port-scoped deny rules now precede the custom-port allow, including when that port is already in Safe_ports.
| if (parsed.protocol === 'http:') return `http://${parsed.host}`; | ||
| if (parsed.protocol === 'https:') return parsed.host; |
There was a problem hiding this comment.
Fixed in 76b74f4: allowlist validation compares the parsed hostname, including HTTP targets with custom ports.
| for (const [index, endpoint] of config.apiProxyUpstreams.entries()) { | ||
| if (endpoint.port === 80 || endpoint.port === 443) continue; | ||
| validateApiProxyPort(endpoint.port); | ||
| const hostname = endpoint.hostname.replace(/\.$/, ''); |
There was a problem hiding this comment.
Fixed in 76b74f4: canonical undotted custom-port hostnames are now included in sensitive endpoint redaction forms, with trailing-dot coverage.
|
@copilot address review feedback |
Addressed the review feedback in |
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.
|
|
💎 Smoke Gemini is crystallizing results on this pull request... |
|
❌ Smoke Copilot BYOK reports failed. BYOK mode investigation needed...
|
|
Smoke Cloud Hypervisor completed. Cloud Hypervisor + Copilot passed.
|
|
❌ Security Guard failed. Please review the logs for details. Security GuardOutcome: The agent failed after emitting a no-op output. Task completion is unconfirmed; the no-op does not establish success or a transient failure. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 Smoke CodexOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅
|
|
Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.
|
|
✅ Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓
|
|
💎 Smoke Gemini is crystallizing results on this pull request... |
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤
|
|
Smoke Cloud Hypervisor completed. Cloud Hypervisor + Copilot passed.
|
|
✅ Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓
|
|
🛡️ Smoke Copilot Network Isolation confirmed the egress allowlist is enforced. ✅
|
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 Smoke CodexOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
📡 Smoke OTel Tracing completed. All tracing scenarios validated. ✅
|
|
✅ Build Test Suite completed successfully!
|
|
🔌 Smoke Services — All services reachable! ✅
|
|
✅ Smoke Claude passed
|
|
🔑 Smoke Copilot BYOK AOAI (api-key) is testing Azure OpenAI BYOK (api-key) mode on this pull request... |
Smoke Test: Claude Engine Validation
Overall result: PASS
|
|
EGRESS_RESULT allow=pass deny=pass
Overall: PASS — @lpcox
|
|
Smoke Copilot: PASS
cc
|
Smoke Services: ❌ FAIL
Overall: FAIL
|
|
|
Smoke Test: Copilot BYOK (Direct Mode) ✅All tests passed — Running in direct BYOK mode via api-proxy sidecar → api.githubcopilot.com
Author: @lpcox | Mode: COPILOT_PROVIDER_API_KEY (direct)
|
OTEL Smoke Test
|
|
Cloud Hypervisor + Copilot smoke test
Overall: PASS
|
Chroot Version Comparison
Result: Not all tests passed (Node.js mismatch), so the
|
🏗️ Build Test Suite Results
Overall: 7/8 ecosystems passed — FAIL Java failure: .NET note:
|
Smoke Test
|


AWF dropped configured provider ports, routing Ollama
http://host.docker.internal:11434/v1to port 80. Preserving the port alone would still encounter Squid’s unsafe-port rejection.Provider routing
Firewall policy
Safe_portsunchanged; retain agent isolation, raw-IP restrictions, dangerous-port rejection, blocklists, and DLP.Regression coverage
:11434, HTTPS non-default ports, defaults,/v1, and protected-route models/chat requests.