Outbound egress
Calling Stripe, Slack or an SMTP host is ordinary work for a function. What a slice may dial is declared in the Driftfile.
atomic:
egress:
mode: allowlist # open | allowlist, default open
hosts:
- api.stripe.com # every port on this address
- hooks.slack.com
- smtp.sendgrid.net:587 # only this port| Mode | What it declares |
|---|---|
open | Any public host on any port. The default, and what every slice does today. |
allowlist | Reach only the declared hosts. A bare host admits every port on it; add :port to narrow it to that one. |
The allowlist is enforced, not a hint.
drift file apply resolves every declared host to its current IPs and renders them into the slice's own outbound rule, so allowlist mode genuinely confines the slice's outbound traffic to what you named. A wildcard host (*.example.com) cannot become one of those rules, so it is refused rather than silently dropped: drift file lint rejects it offline, and the platform refuses it again if one somehow arrives. List concrete hostnames instead. A deploy reports what it did: egress allowlist applied (N hosts), or egress mode open when the block is absent or set back to open.Private address space is blocked either way, and that block is real. RFC-1918 ranges, link-local (including the cloud metadata endpoint) and CGNAT are excepted from the slice's outbound network rule, so a function cannot reach the platform's internal services or anything on a private network whatever the Driftfile says.
The Go SDK's drift.HTTPRequest helper wraps a dial the allowlist refused in an EgressDeniedError carrying the host it was for, so a handler can reach for errors.As instead of parsing a message:
var denied *drift.EgressDeniedError
if errors.As(err, &denied) {
return 502, "Bad Gateway", map[string]string{"host": denied.Host}, nil
}It is a best-effort signal rather than a certain one: the wrapping fires on the same underlying error a genuinely down host produces, so a host that is allowlisted but simply unreachable can be wrapped too. It also only covers calls made through that one SDK helper. A Go handler that opens its own http.Client sees the plain dial error instead, exactly as every other language's SDK always does.
Inspect and repair the list from the CLI:
drift atomic egress list # mode, declared hosts, resolved IPs
drift atomic egress test api.stripe.com # local pattern match, no DNS lookup
drift atomic egress refresh # re-resolve DNS and re-applyThere is deliberately no add or remove: the Driftfile is the source of truth, and drift file apply reconciles the list when that block changes.
Two edges the list still has.
drift atomic egress refresh is for: reach for it when an allowlisted CDN's IPs have moved.