Skip to content
VPNDetection

Should you block iCloud Private Relay? You may already block 64%

A hosting rule refuses 63.7% of iCloud Private Relay's IPv4 exits, all on Akamai, and none of its IPv6. Whether to block it, and code that tells them apart.

Published 4 min read

On this page
  1. How Private Relay works
  2. Which exits a hosting rule catches
  3. Should you block it?
  4. Check relay first
  5. Other relays

If your signup refuses VPN and hosting addresses, it already refuses some of Apple's iCloud Private Relay users and lets the rest through. On October 1, 2026, 67,932 of the 106,692 Private Relay IPv4 addresses in our Relay IP database were also in Hosting IP: 63.7%, every one of them on Akamai's network. None of the exits Cloudflare and Fastly run for Apple were, and none of Private Relay's 6,050 IPv6 ranges.

How Private Relay works

Private Relay comes with every iCloud+ subscription. It sends Safari, DNS lookups and unencrypted app traffic through two relays. The first, run by Apple, sees the user's address but not the site. The second, which Apple's overview says is run by "some of the largest content delivery networks (CDNs) in the world", picks the address your server sees and completes the connection. Apple publishes every exit address in a CSV, and on October 1, 2026 it held 41,822 IPv4 ranges and 243,357 IPv6 ranges.

By default the exit address maps to a coarse city-level area near the user. A user who picks "Use country and time zone" gets one anywhere in their country and time zone. Either way it stays in their own country, holds steady for a browsing session, and may be shared with other Private Relay users nearby, according to Apple's guide for web servers.

Which exits a hosting rule catches

To an IP check, a Private Relay user looks like anyone hiding their address: the address belongs to a CDN, not to their ISP. Our API answers that with its own flag, is_relay, apart from is_vpn and is_hosting. Rules written before anyone looked at that flag split Apple's users by the network Apple sends them through:

Egress partnerPrivate Relay IPv4Also in Hosting IP
Akamai70,87067,932 (95.9%)
Cloudflare19,8120
Fastly16,0100
All106,69267,932 (63.7%)

Every Akamai exit in 172.225.0.0/16 and 172.226.0.0/16 is a hosting address too; the 2,938 in 172.224.0.0/16 aren't. Apple's list serves 585 of its 2,911 IPv4 locations from both kinds of exit, Des Moines, Chicago and New York among them, so two users in the same city can get opposite answers, and neither of them chose the relay that decided it.

We ran the usual first rule, VPN or hosting, with our Express middleware on Node.js 22.22, Express 5.2.1 and vpndetection-express 2.0.7:

js
import express from 'express';
import { vpndetection } from 'vpndetection-express';

const app = express();
app.set('trust proxy', 'loopback');
app.use(vpndetection({
    apiKey: process.env.VPNDETECTION_API_KEY,
    blockCondition: [{ isVpn: true }, { isHosting: true }],
}));

app.post('/signup', (req, res) => {
    res.json({ ok: true });
});

app.listen(3000);

Then we sent it one exit from Apple's list per partner, Akamai in Des Moines, Cloudflare in Chicago and Fastly in Indianapolis, and a Mullvad server in New York from Mullvad's own list:

bash
for ip in 172.225.4.1 104.28.32.92 146.75.128.1 23.165.56.3; do
    printf '%-13s ' "$ip"
    curl -s -X POST localhost:3000/signup -H "X-Forwarded-For: $ip" \
        -w ' %{http_code}\n'
done
172.225.4.1   {"error":"access denied"} 403
104.28.32.92  {"ok":true} 200
146.75.128.1  {"ok":true} 200
23.165.56.3   {"error":"access denied"} 403

Should you block it?

For signup, login and checkout, almost never. Apple's guide says every Private Relay connection comes from an iPhone, iPad or Mac whose owner pays for iCloud+, behind single-use authentication tokens and rate limiting on Apple's side, and that "traditional fraud detection that relies on IP addresses might need to be adjusted to ensure legitimate users aren't impacted."

Three places where it's still worth handling apart:

  • Per-IP rate limits. One exit address can carry several users, so key a limit on the account or session. Apple's guide suggests Private Access Tokens in place of a CAPTCHA.
  • City-level geo rules. Users on "Use country and time zone" show only that. A country rule holds; a city rule doesn't.
  • Ad requests. Pixalate's iP64 report (November 2022) found more than 90% of traffic claiming a Private Relay address looked spoofed, with the addresses written into ad bid requests. That works where an address is a claim inside a request. A connection to your server can't fake its source, as long as you trust X-Forwarded-For only from your own proxies.

Check relay first

blockCondition can't say "hosting, but not relay": a member set to false is ignored, so { isHosting: true, isRelay: false } matches every hosting address. Screen in your own middleware instead, after the lookup:

js
import express from 'express';
import { vpndetection } from 'vpndetection-express';

const app = express();
app.set('trust proxy', 'loopback');
app.use(vpndetection({ apiKey: process.env.VPNDETECTION_API_KEY }));

function screen(req, res, next) {
    const result = req.vpndetection.result;
    if (!result || result.isRelay) {
        return next();
    }
    if (result.isVpn || result.isHosting) {
        return res.status(403).json({ error: 'Turn off your VPN to sign up.' });
    }
    next();
}

app.post('/signup', screen, (req, res) => {
    const { isRelay, isVpn, isHosting } = req.vpndetection.result ?? {};
    res.json({ ok: true, isRelay, isVpn, isHosting });
});

app.listen(3000);

The same four addresses:

172.225.4.1   {"ok":true,"isRelay":true,"isVpn":false,"isHosting":true} 200
104.28.32.92  {"ok":true,"isRelay":true,"isVpn":false,"isHosting":false} 200
146.75.128.1  {"ok":true,"isRelay":true,"isVpn":false,"isHosting":false} 200
23.165.56.3   {"error":"Turn off your VPN to sign up."} 403

A Comcast home line, which we don't print, came back with all three flags false and got in both times. A failed lookup leaves result undefined, so screen lets the request through, as the middleware itself does.

is_relay and is_hosting come with the Starter plan and up (pricing). On Free only is_vpn comes back, so the same code refuses the Mullvad server and nothing else.

Other relays

Relay IP holds more than Apple. On October 1, 2026, all 15,578 IPv4 of VPN by Google and all 768 of Google Fi's VPN were hosting addresses too, and 30,976 of the 166,157 behind Cisco's secure web gateway, which carries a company's own staff. Checking is_relay before is_hosting keeps each of them out of a hosting rule, and leaves what to do with them to a rule of its own.

Look up any address with the API, or read the flags' fields in the docs.

Written by

  • Uman Shahzad

    Founder & CEO

    IP intelligence data expert for over 8 years, former lead engineer at IPinfo, Uman has pioneered many systems and practices used by IP data companies to operate at scale, provide high-quality data and offer the best developer experiences.

Get new posts by email

Or follow along in a feed reader.

RSS feed

Try it on your own traffic.

The detection these posts describe is one API call away, with SDKs for every major language.

00 · No key

Start without signing up.

Paste it into a terminal. No account needed. 1k daily allowance per user, answering ip and is_vpn.

curl "https://api.vpndetection.io/45.83.91.1"
{
"ip": "45.83.91.1",
"is_vpn": true
}
01 · Free key

Sign up and get 50,000 requests a month.

No card and no sales call: the key is issued on signup.
Every request flags VPN IPs.
Upgrade only when you outgrow the allowance.