drift Docs
Start
What is Drift?
The tour, if you are new here.
Use cases
Whether Drift does your thing.
Getting started
Nothing to deployed, in one command.
Architecture
How a slice is put together.
What it costs
The free grant, four unit prices, two rules.
Build
Canvas
Static sites, same origin as your API.
Tools
Operate
Auth
Route gates, API keys and your account.
Security
Boundaries, sandboxing and hardening.
Troubleshooting
Error codes
What went wrong, and what to do about it.
Legal
Acceptable use
What a slice may not be used for.
Data processing
The DPA, and every sub-processor.

Edge The IP allowlist

An allowlist closes a slice to every network but the ones you name: an office, a VPN, a partner's range. When the slice lists any range, only clients inside one of them reach it, and everyone else is turned away by the router before the request costs the slice anything.

Declaring it

Driftfile
edge {
  allow = [
    "203.0.113.0/24",  # the office
    "198.51.100.7/32", # one address
    "2001:db8::/32",
  ]
}

Every entry is a CIDR range, IPv4 or IPv6. Present, the list replaces the slice's allowlist, and the apply says how many ranges it holds (✓ inbound allowlist: 3 ranges). allow = [] removes the list, so every address reaches the slice again, and the apply says that too:

  · inbound allowlist cleared: every address reaches the slice

Absent, the slice keeps the list it has. There is no command for it: the Driftfile is the only way to set the list, and drift plan shows the live ranges beside the declared ones, + for a range the apply adds, - for one it removes and a blank mark for one that stays (allow 203.0.113.0/24 added). The attribute is in the Driftfile reference.

Every entry is checked before anything is sent. A bare address is the commonest mistake, and it is refused with its position, so the file is not applied:

Driftfile:6:11: Invalid edge.allow: edge.allow: 0: '203.0.113.7' does not match pattern '^(([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}|[0-9A-Fa-f:]*:[0-9A-Fa-f:]*/[0-9]{1,3})$'

The pattern says what an entry looks like: an address, a slash and a prefix length. The range that admits one IPv4 address is that address with /32, and an IPv6 address takes /128. The platform stores each range as its network (203.0.113.7/24 is kept as 203.0.113.0/24) and drops duplicates.

What a refused client sees

403, never a 404: the host exists, and the client is being told no.

HTTP/1.1 403 Forbidden
Content-Type: application/json
X-Drift-Refused-By: edge.allow

{"error":"this site does not accept requests from your network address","code":"EDGE-ALLOW"}

The X-Drift-Refused-By header is for a person reading curl -i; the code is for a client branching on the body. Either one tells "you are on the wrong network" apart from "there is nothing here", so nobody goes looking for a broken domain.

How it decides

  • First. The allowlist runs before the rate limit and the site gate, so a refused client reaches neither Canvas nor Atomic and spends none of the per-minute budget the admitted addresses share.
  • The client's address is the one the platform's TLS edge records for the request, the same address the rest of the platform trusts, rather than the router's own connection.
  • An IPv4 client arriving in IPv6-mapped form (::ffff:203.0.113.8) is compared as the IPv4 address it is.
  • It fails closed. An address that cannot be read is refused.
  • A fronted host uses its target's list. A hostname one slice fronts for another is admitted by the list of the slice that serves it.
  • It governs the public way in. A call from another slice of yours over a link never passes the router, so it is not compared against this list.

Limits

Limit Value
Ranges per slice256. More is refused: edge.allow lists 300 ranges, and a slice may list at most 256
EntryA CIDR range. A bare address is refused; write it with /32 (IPv4) or /128 (IPv6) to admit that one address.
FamiliesIPv4 and IPv6
Refusal403, code EDGE-ALLOW, header X-Drift-Refused-By: edge.allow