Sign in with Apple moves to private.icloud.com: check your backend
New Sign in with Apple relay addresses now end in private.icloud.com instead of privaterelay.appleid.com. Where this breaks apps (validation, allowlists, fraud rules, email delivery) and a drop-in fix.
When a user picks “Hide My Email” in Sign in with Apple, your app receives a relay address instead of their real one. For years those addresses ended in @privaterelay.appleid.com. Apple has now started issuing new ones on a different domain: @private.icloud.com.
From Apple's developer news update:
- New Sign in with Apple relay addresses are issued on
private.icloud.com. - Existing
privaterelay.appleid.comaddresses keep working. - iCloud+ Hide My Email addresses created outside Sign in with Apple stay on
icloud.com. - Your systems must accept both relay domains.
If you never look at the email domain, nothing changes. Many apps do, often without anyone remembering it.
Where this breaks
- “Is this a relay address?” checks. Code that detects relay users to prompt for a real email, skip marketing, or merge accounts. New users will not match the old domain.
- Allowlists and blocklists. Sign-up validation or fraud rules that allow known domains, or flag unknown ones, may reject or flag new Apple users.
- Disposable email filters. Some block lists treat unfamiliar relay domains as throwaway addresses.
- Analytics and CRM segments built on the email domain will quietly stop counting new Apple users.
- Email delivery. Mail to relay addresses is forwarded only from sources you registered with Apple's private email relay service. Check that your transactional mail still reaches new relay users, and review your configuration in your Apple Developer account.
The fix
Centralise the check in one function and include both domains. Search your frontend and backend for the old domain first:
grep -rn "privaterelay.appleid.com" --include=*.{ts,tsx,js,jsx,py,rb,go,sql} .Then replace every hit with a shared helper:
const APPLE_RELAY_DOMAINS = ['privaterelay.appleid.com', 'private.icloud.com'];
export function isAppleRelayEmail(email: string): boolean {
const domain = email.trim().toLowerCase().split('@').pop() ?? '';
return APPLE_RELAY_DOMAINS.includes(domain);
}Do not match on icloud.com alone, and do not use a loose endsWith('icloud.com'). A regular @icloud.com address is a real mailbox that belongs to the user, not a relay.
If you use Supabase, Firebase Auth or another provider, the provider stores the address as given. The domain checks to worry about are the ones in your own code: sign-up forms, onboarding flows, admin tools and database queries.
Also check the other direction: if you ever show a user their account email and explain that it is a relay address, update that copy and logic too, so new users do not see a confusing “your email” screen.
Shipping the fix in a Capacitor app
Backend fixes deploy as usual. The frontend half is often the part teams forget: the check that decides whether to show “add your real email” during onboarding usually lives in the app's web code.
In a Capacitor app that code is part of the web bundle, so it does not need App Review. With OtaKit you build and release it the same afternoon:
npm run build npx @otakit/cli upload --release
Users get the fix on their next app launch. The native Sign in with Apple plugin is unaffected; it passes through whatever email Apple returns. For the full sign-in setup, see social login and OAuth in Capacitor.