Atomic 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.
The allowlist is declared, not enforced.
hosts list is validated and recorded, and drift project deploy says so in as many words: it reports the allowlist as declared for N hosts, and not yet enforced by the platform. Every slice reaches the public internet as if the mode were open. Read the block as a statement of intended reach, and keep the authentication and secret hygiene you would have used without it. The private-range block below is a separate mechanism and it is live.atomic:
egress:
mode: allowlist # open | allowlist, default open
hosts:
- api.stripe.com
- hooks.slack.com
- smtp.sendgrid.net:587 # port defaults to 443| Mode | What it declares |
|---|---|
open | Any public host on any port. The default, and what every slice does today. |
allowlist | The intent to reach only the declared hosts, on the declared port (443 when omitted). |
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 carries an EgressDeniedError that wraps a refused dial with the host it was for, so a handler can tell “my allowlist is wrong” from “the remote is down” once the allowlist does gate traffic. It is Go's alone; the other five SDKs return the underlying dial error unwrapped.
var denied *drift.EgressDeniedError
if errors.As(err, &denied) {
return 502, "Bad Gateway", map[string]string{"host": denied.Host}, nil
}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 project deploy reconciles the list when that block changes.
Three edges the list already has.
*.example.com wildcard passes schema validation and egress test reports it as a match, but the resolver skips it, so list concrete hosts. Only IPv4 addresses become rules, so an IPv6-only host is not covered. And addresses are resolved when the list is applied rather than per request, which is what drift atomic egress refresh is for.