Skip to content

Preserve custom BYOK ports through API proxy and Squid - #10776

Merged
lpcox merged 7 commits into
mainfrom
copilot/fix-ollama-custom-port-issue
Oct 30, 2026
Merged

lpcox merged 7 commits into
mainfrom
copilot/fix-ollama-custom-port-issue

Conversation

Copilot AI commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

AWF dropped configured provider ports, routing Ollama http://host.docker.internal:11434/v1 to port 80. Preserving the port alone would still encounter Squid’s unsafe-port rejection.

  • Provider routing

    • Preserve HTTP/HTTPS scheme, explicit port, and base path across runner configuration, discovery, validation, inference, and WebSockets.
    • Align Squid destinations with effective provider configuration, including Azure fallback; retain default-port behavior and secret-endpoint redaction.
  • Firewall policy

    • Authorize custom ports only for the trusted API-proxy source and exact configured hostname/port.
    • Keep Safe_ports unchanged; retain agent isolation, raw-IP restrictions, dangerous-port rejection, blocklists, and DLP.
  • Regression coverage

    • Cover HTTP :11434, HTTPS non-default ports, defaults, /v1, and protected-route models/chat requests.
    • Reject untrusted sources, mismatched hosts/ports, raw IPs, and blocked destinations.

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) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 76b74f4: the warning now logs only the parsed scheme, hostname, and port, never the path, query, fragment, or credentials.

Copilot AI and others added 2 commits October 28, 2026 03:16
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix BYOK HTTP custom port issue in AWF v0.29.0 Preserve custom BYOK ports through API proxy and Squid Oct 28, 2026
Copilot AI requested a review from lpcox October 28, 2026 03:33
@lpcox
lpcox marked this pull request as ready for review October 28, 2026 03:44
Copilot AI max review requested due to automatic review settings October 28, 2026 03:44

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

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

Comment on lines +30 to +32
lines.push(
`http_access allow api_upstream_source ${acl}_host ${acl}_port${guards ? ` ${guards}` : ''}${config.enableDlp ? ' !dlp_blocked' : ''}`
);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 76b74f4: source/hostname/port-scoped deny rules now precede the custom-port allow, including when that port is already in Safe_ports.

Comment on lines +29 to +30
if (parsed.protocol === 'http:') return `http://${parsed.host}`;
if (parsed.protocol === 'https:') return parsed.host;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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(/\.$/, '');

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 76b74f4: canonical undotted custom-port hostnames are now included in sensitive endpoint redaction forms, with trailing-dot coverage.

@lpcox

lpcox commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator

@copilot address review feedback

Copilot AI commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address review feedback

Addressed the review feedback in 76b74f4 (redacted URL warnings, guarded custom-port exceptions against blocklist/DLP fallthrough, hostname-only allowlist matching, and trailing-dot endpoint redaction). Targeted root tests (51) and API-proxy routing tests (98) pass; CodeQL analysis was skipped because the database exceeded its size limit.

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

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

Tested by Smoke Chroot

@github-actions

Copy link
Copy Markdown
Contributor

💎 Smoke Gemini is crystallizing results on this pull request...

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

❌ Smoke Copilot BYOK reports failed. BYOK mode investigation needed...

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Smoke Cloud Hypervisor completed. Cloud Hypervisor + Copilot passed.

Cloud Hypervisor + Copilot smoke test by Smoke Cloud Hypervisor

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

❌ Security Guard failed. Please review the logs for details.

Security Guard

Outcome: incomplete

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.

Generated from Security Guard · haiku45 · ~6 AIC · ⊞ 6.0K · ◷

Generated by Security Guard for #10776

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

Smoke Codex

Outcome: reported_no_action

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.

Generated from Smoke Codex · gpt54 · ~16 AIC · ⊞ 21.0K · ◷

🔮 The oracle has spoken through Smoke Codex

@github-actions

github-actions Bot commented Oct 28, 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 Oct 29, 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 Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Copilot BYOK completed. Copilot BYOK mode operational. 🔓

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

Copy link
Copy Markdown
Contributor

💎 Smoke Gemini is crystallizing results on this pull request...

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Smoke Cloud Hypervisor completed. Cloud Hypervisor + Copilot passed.

Cloud Hypervisor + Copilot smoke test by Smoke Cloud Hypervisor

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Copilot BYOK AOAI (Entra) completed. Copilot AOAI BYOK (Entra) mode operational. 🔓

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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

🛡️ Egress verdict from Smoke Copilot Network Isolation

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

Smoke Codex

Outcome: reported_no_action

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.

Generated from Smoke Codex · gpt54 · ~13 AIC · ⊞ 21.0K · ◷

🔮 The oracle has spoken through Smoke Codex

@lpcox
lpcox deployed to aoai-model October 29, 2026 20:13 — with GitHub Actions Active
@github-actions

github-actions Bot commented Oct 29, 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 Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ Build Test Suite completed successfully!

Generated by Build Test Suite for #10776

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

🔌 Smoke Services — All services reachable! ✅

🔌 Service connectivity validated by Smoke Services

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ Smoke Claude passed

Generated by Smoke Claude for #10776

@github-actions

Copy link
Copy Markdown
Contributor

🔑 Smoke Copilot BYOK AOAI (api-key) is testing Azure OpenAI BYOK (api-key) mode on this pull request...

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Claude Engine Validation

  • API status: ✅ PASS
  • GitHub check: ✅ PASS
  • File status: ✅ PASS

Overall result: PASS

Generated by Smoke Claude for #10776 · claude · haiku45 · ~34 AIC · ⊞ 6.1K · ◷
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

EGRESS_RESULT allow=pass deny=pass

  • ✅ Allowed domain (api.github.com → 200)
  • ✅ Blocked domain (example.com blocked)

Overall: PASS — @lpcox

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

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Copilot: PASS

  • ✅ GitHub MCP: "chore: upgrade gh-aw workflow dependencies"
  • ✅ GitHub.com connectivity (200)
  • ✅ File write/read

cc @Copilot @lpcox

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

@lpcox
lpcox deployed to aoai-model October 29, 2026 20:26 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

Smoke Services: ❌ FAIL

  • ❌ Redis PING: connection refused
  • ❌ pg_isready: no response
  • ❌ psql SELECT 1: connection refused

Overall: FAIL

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

@github-actions

Copy link
Copy Markdown
Contributor

@Copilot @lpcox
fix: prebuild local images before smoke services execution
fix: recover retired and unavailable models with compatible choices
MCP: ✅
GitHub.com: ✅
File: ✅
BYOK: ✅
Overall: PASS
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

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

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct Mode) ✅

All tests passed — Running in direct BYOK mode via api-proxy sidecar → api.githubcopilot.com

  • ✅ GitHub MCP connectivity: PR data verified
  • ✅ GitHub.com HTTP 200: Connected
  • ✅ File write/read: Confirmed
  • ✅ BYOK inference: Working (this response confirms it)

Author: @lpcox | Mode: COPILOT_PROVIDER_API_KEY (direct)

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

@github-actions

Copy link
Copy Markdown
Contributor

OTEL Smoke Test

  • ✅ S1 Module loading: otel.js loads; exports startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, routerCallTracing, shutdown, isEnabled, etc.
  • ✅ S2 Tests: otel.test.js 46/46 passed
  • ✅ S3 Env forwarding: GITHUB_AW_OTEL_TRACE_ID/PARENT_SPAN_ID in env-passthrough.ts; OTEL vars in api-proxy-env-config.ts
  • ✅ S4 Token tracker: onUsage present in token-tracker-http.js
  • ✅ S5 Diagnostics: /tmp/gh-aw/otel.jsonl contains 1 line (output present)

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

@github-actions

Copy link
Copy Markdown
Contributor

Cloud Hypervisor + Copilot smoke test

  1. Merged PR lookup: PASS
  2. github.com connectivity: PASS (HTTP 200)
  3. File write/read: PASS
  4. example.com blocked: PASS (HTTP 000)

Overall: PASS

Cloud Hypervisor + Copilot smoke test by Smoke Cloud Hypervisor
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Chroot Version Comparison

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

Result: Not all tests passed (Node.js mismatch), so the smoke-chroot label was not added.

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

@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 ✅ pass ✅ PASS
Go env ✅ pass ✅ PASS
Go uuid ✅ pass ✅ PASS
Java gson ❌ 0/? ❌ FAIL
Java caffeine ❌ 0/? ❌ FAIL
Node.js clsx ✅ pass ✅ PASS
Node.js execa ✅ pass ✅ PASS
Node.js p-limit ✅ pass ✅ PASS
Rust fd ✅ 1/1 passed ✅ PASS
Rust zoxide ✅ 1/1 passed ✅ PASS

Overall: 7/8 ecosystems passed — FAIL

Java failure: ~/.m2 is root-owned, so Maven couldn't create the default local repo (LocalRepositoryNotAccessibleException). Retrying with -Dmaven.repo.local in a writable dir then failed with PluginResolutionException. Likely cause: the prescribed squid-proxy:3128 proxy host is not reachable from this runner.

.NET note: dotnet initially crashed on a missing /run/user/1001 (NuGet mutex). It passed after setting XDG_RUNTIME_DIR to a writable dir.

Generated by Build Test Suite for #10776 · copilot · auto · ~25 AIC · ⊞ 5.7K · ◷
Add label ready-for-aw to run again

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test

  • fix: prebuild local images before smoke services execution
  • fix: recover retired and unavailable models with compatible choices
  • GitHub PR checks ✅
  • Playwright title check ❌
  • File write/read ✅
  • AWF build ✅
  • Overall status: FAIL

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

@lpcox
lpcox merged commit 6b5573a into main Oct 30, 2026
153 of 158 checks passed
@lpcox
lpcox deleted the copilot/fix-ollama-custom-port-issue branch October 30, 2026 03:17

This branch was successfully deployed

1 active deployment
aoai-model — dfc2fedb Deployed Oct 29, 2026 by lpcox via conclusion #2200
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.

BYOK HTTP custom port lost in AWF v0.29.0: Ollama :11434 routed to :80

4 participants