symfonic.capabilities.knowledge.outbound¶
outbound ¶
The outbound URL guard: AS-NET-1 and AS-NET-2, before the socket.
A URL that reaches this module arrived inside model output, a tool result, or a document — somewhere untrusted — and something is about to fetch it. Two contracts apply:
- Scheme allowlist (AS-NET-1).
file:,gopher:, anddata:are refused, so such a URL cannot turn a fetch into a local read. - Host controls (AS-NET-2). Loopback, link-local (
169.254.169.254is the cloud metadata endpoint), private, and unspecified targets are refused, because the interesting SSRF target is never on the public internet.
It lives apart from :mod:.multimodal because it answers a different question.
The wire formatters decide what a provider is allowed to be told; this decides
what the network stack is allowed to be asked for, and the two have no shared
state — only the same OutboundRejected refusal.
Every check here is a string comparison against a canonical spelling, so the order is load-bearing: normalise, then compare. Sections below say why each alternate spelling exists.
check_outbound_url ¶
Return url if it may be fetched, else raise :class:OutboundRejected.
Literal-address checks only. DNS resolution happens in whatever HTTP client performs the fetch, and the resolution-time and per-redirect checks AS-NET-2 also requires belong there, next to the socket — a guard that validates a name here and lets the client resolve it later is a time-of-check gap, not a control.
"Literal address" is read the way a C resolver reads it, not the way
:func:ipaddress.ip_address does. 2130706433, 127.1 and
0177.0.0.1 all reach 127.0.0.1 without any DNS involvement, so a
guard that only understands dotted-quad hands the loopback interface to
anyone who writes the address a different way.
And the host is normalised through IDNA before any of that, because the
same argument applies one level down: 127.0.0.1 is the loopback
address written in fullwidth digits, and every check here is a comparison
against the ASCII spelling. See :func:_normalise_hostname.