fix(agent-endpoint): correctly handle bracketed IPv6 hosts with port in allowed list - #330
Open
Ayush7614 wants to merge 1 commit into
Open
Conversation
…in allowed list AGENT_ENDPOINT_ALLOWED_HOSTS is a list of hosts optionally with a port. For IPv6 the host is bracketed as [::1]:8080. The previous normalization did host.replace(/^\[/, "").replace(/\]$/, ""), which stripped the opening bracket but left the closing bracket when a port followed: "[::1]:8080" became "::1]:8080". The check in endpoint.ts did a different strip, producing "::1:8080", so the two sides never matched and a named IPv6 endpoint was always refused. Similarly, endpoint.ts derived host as url.host with a one-sided replace, which for Bun's URL.hostname="[::1]" produced a mismatched form versus the stored entry. Normalize both sides consistently: store the host as hostname (without brackets) plus optional :port, and derive the same from URL.hostname/ URL.port. This makes [::1]:8080 pin that port (and [::1] cover any port, per "host without port covers any port"), and fixes the bracket stripping for the allowed-host path.
Ayush7614
requested review from
MikeRyanDev,
davidmckayv,
guidovizoso and
tylerslaton
as code owners
September 2, 2026 08:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
AGENT_ENDPOINT_ALLOWED_HOSTSis the narrow allow-list that lets a deployment reach a private agent address without opening the whole network (AGENT_COMPUTER_ALLOW_PRIVATE_HOSTS). For IPv6 the host is written bracketed as[::1]:8080or[::1].The previous normalization did:
For
[::1]:8080that stripped the leading[to::1]:8080and left the]because the string ends with0, not]. The stored entry became::1]:8080.endpoint.ts:52did a different strip:which for
[::1]:8080produced::1:8080. The two sides never matched, so a named IPv6 endpoint wasrefusedwith "inside this deployment's own network" even though the deployment had explicitly named it. A deployment reaching its own LangGraph or BYO agent over IPv6 loopback or ULA could not be configured at all.This normalizes both sides consistently:
server/src/config.ts:619): parse[host]:portexplicitly — find the closing], take the IPv6 inside and the optional:portafter it.[::1]:8080stores as::1:8080,[::1]as::1.server/src/agents/endpoint.ts:51): derivehostnameasurl.hostnamestripped of brackets, andhostashostname + (port ? :port)rather than string-replacingurl.host. This matches the stored form on both Bun (hostname[::1]) and Node.Behaviour after:
AGENT_ENDPOINT_ALLOWED_HOSTS=[::1]:8080allowshttp://[::1]:8080/ag-uiand refuseshttp://[::1]:9090/ag-ui(port pinned).AGENT_ENDPOINT_ALLOWED_HOSTS=[::1]allows any port on::1— the existing "host without port covers any port" rule.10.0.0.42:9000pins that port,10.0.0.42andagents.internalcover any port, exactly as before.Why it matters
Private IPv6 loopback (
::1) and ULAs (fc00::/7) are the IPv6 answers to10/8/192.168/16. A deployment whose BYO agent or LangGraph runs in a container reached overhttp://[::1]:4201had no way to name that address — the one host it legitimately needs is the one the check rejected. The failure is silent at config time and surfaces as a refused agent at runtime, with nothing in the trail naming the mis-normalization.Proof
Before:
After (verified inline against
loadConfig+checkAgentEndpoint):bun test server/tests/config.test.ts— 72 pass, 0 fail.bun run typecheck·bun run lint·bun run format:checkclean. No other caller uses the stripped form.Checklist
checkNavigationTargetAGENT_ENDPOINT_ALLOWED_HOSTSexact-match semantics preserved (host with port pins, without covers any port)