Saphan StudioDocs
Security/Egress control

Limits and known gaps

The section a security officer should turn to first.

The section a security officer should turn to first. None of it is softened, and each item is here because it would otherwise be discovered as a bug.

  • Nothing enforces today. Restated here because it belongs in the same list as every other gap, and it is larger than all of them. See the box at the top of this document.

  • The hard floor is a deny list, so a missing entry fails OPEN. This is the direction of failure, and it is the sentence no other section carries: if a range that ought to be on the floor is absent, traffic to it is permitted, not blocked. The floor is enumerative — a list of ranges, not a rule that derives them — and it has a known gap: ranges that meet the floor's own selection criteria and are not on it. The gap is written down in the engineering record rather than left to be discovered, and it is under review. Closing it — by adding the ranges, or by inverting that half of the floor to a permit-list — is an open decision, not an oversight, and neither option is decided here. ⇒ What this means for you today: the floor is a named list of ranges and not a proof of unreachability. Most reserved IPv6 space is not on it. Outside the globally routable 2000::/3, address space the IETF records as reserved is largely absent from the floor — by decision, not by oversight — so traffic to it is permitted. Read §5's list as the list, never as the category it samples.

  • A v4 address carried inside an operator-chosen IPv6 prefix is not on the floor. The IPv6 transition formats are on the floor as whole ranges under their standardised prefixes. Where a fleet runs NAT64 under its own network-specific prefix (RFC 6052 §2.2), the prefix is not knowable in advance, so there is no range to list and an address under it is not recognised as the IPv4 address it carries. ⇒ On such a fleet the floor is not a barrier to the metadata endpoint by that route. A client naming that address as a literal is still refused unless the policy records it (§6.3.1); an allow-listed name whose single answer is that address is not.

  • Encrypted Client Hello will end the hostname check. The check in §3.5 works by reading the hostname the client announces in cleartext at the start of a TLS handshake. When that field is encrypted there is nothing to read and nothing to compare. Named as a limit with no forecast: no date, no replacement mechanism, recorded so it is not discovered. The destination judgement (§3.1) is unaffected; the check that the connection went where it said it was going is what is lost.

  • macOS will enforce less than Linux — one policy, two strengths. Today neither platform restricts egress at all, so there is no difference to observe. But the ladder in §8 is built from Linux kernel facilities (network namespaces, control groups) that macOS has no equivalent of. ⇒ The same policy will be a weaker guarantee on a macOS runner than on a Linux one, and this document will say which is which rather than blurring the two. If your compliance posture depends on egress being enforced, plan Linux runners for that work.

  • A protocol where the server speaks first is refused. The hostname check waits for the client to send its handshake, so SMTP, some IMAP dialects and MySQL will sit silent until the handshake deadline expires and then be refused. That is the honest price of checking every connection — the alternative, "give up waiting and connect anyway", makes the check optional by stalling.

  • Two of the seven ceilings bind one door and not the other. The header-count and over-long-line bounds describe a line-oriented handshake: the HTTP-style CONNECT door has one and SOCKS5 does not, so no SOCKS5 client can cross either. That is a difference between two wire grammars and not a gap in the judgement: what a destination is judged on is the same on both doors. They ship because they are part of the ratified vocabulary, and because a ceiling added later is a ceiling some deployment already ran without. The request ceiling is not one of the two — it binds both doors, which is why the refusal name they share can appear against a SOCKS5 client.

  • The two ceilings that bound the request are not the same size on both doors. Two wire formats spend different numbers of bytes saying the same thing, so a request ceiling drawn very close to what your clients actually send can refuse on one door and admit on the other. Size it against the larger format — the HTTP-style request line and its header block — not against SOCKS5's compact one.

  • Traffic other than HTTPS is in scope, and admitted per destination. Git, SSH, database connections and anything else TCP is judged the same way: a host and a port. There is no protocol-aware handling and no protocol-based exemption, and — worth stating plainly — one open port never implies another. Permitting a host on 443 does not permit it on 22. For non-TLS traffic the hostname check of §3.5 does not apply, so the guarantee is the destination judgement alone.

  • An address rule accepts every TLS site behind that address (§4.4). A property of what recording an address means, not a defect — but it is the gap most likely to be opened by accident.