Designing Cross-Site Features That Survive Safari's ITP Storage Partitioning
Safari's ITP partitions cookies and storage by top-level site, silently breaking embeds that assume a shared cookie jar. Here's the smallest architecture that survives it.
20 Apr 2026, 10:02 UTC

If your product embeds a widget, checkout flow, or identity layer on third-party sites, Safari will treat your cookies and storage as partitioned by the top-level site the user is visiting. That means the same user on shop-a.com and shop-b.com gets two independent storage silos for your domain. Any design that assumes a single shared cookie jar across sites will silently break for Safari users — usually as "logged out again" reports, not console errors.
The useful takeaway: partition-aware design is mostly about choosing which state truly needs to be cross-site (hint: almost none of it does), moving the rest to first-party or server-side storage, and verifying behavior in Web Inspector rather than trusting that "it works in Chrome."
Requirements: what a third-party embed actually needs
Take a concrete case: a SaaS widget embedded via an iframe on customer sites, which must (a) remember the visitor's session within that site, (b) personalize content, and (c) report analytics. Teams often assume requirement (c) implies a cross-site persistent identifier. Under Intelligent Tracking Prevention (ITP), Safari's anti-tracking system, that assumption is the bug. Since Safari 14, ITP partitions cookies, LocalStorage, and SessionStorage by the top-level browsing domain, and Safari 16 refined how partition keys are derived to reduce false positives for legitimate embedded resources like CDN-served widgets.
The honest requirement list is usually:
- Session continuity per embedding site — fully supported, because partitioned storage still works within one top-level site.
- Authentication — best handled by a first-party redirect flow, not third-party cookies.
- Cross-site identity for analytics — this is the thing ITP exists to prevent. Design it out rather than around it.
The smallest suitable design
The minimal architecture that survives ITP has three rules:
- Scope all client state to the partition. Treat
(your-domain, top-level-site)as the natural key. Your widget's session token stored in a partitioned cookie works fine for per-site continuity — you just cannot join it across sites, and you should stop trying. - Authenticate via top-level navigation. When the user must log in, open your identity page as a full-page redirect or popup (top-level context), set a first-party cookie there, then return. First-party storage in a top-level context is not partitioned against itself.
- Move durable state server-side. Anything that must survive storage eviction or partitioning lives in your backend, keyed by a server-issued session ID — set as a
Secure; HttpOnly; SameSite=Nonecookie where cross-site delivery is genuinely required, understanding that ITP may still partition or cap its lifetime.
A minimal cookie set from the embed's server response looks like:
Set-Cookie: widget_session=eyJ...; Path=/; Secure; HttpOnly; SameSite=NoneWithout Secure, SameSite=None cookies are rejected by modern browsers entirely, so both attributes are mandatory for any cross-site cookie attempt. Note the research caveat here: HTTP-only cookies without Secure are unaffected by ITP partitioning specifically, but they remain subject to standard same-site policies — they are not an escape hatch, just a different failure mode.
Trust and data boundaries
Partitioning draws a boundary you should formalize in your own data model. The partition key is effectively the registrable domain of the page the user is on. Consequences:
- Never let the embedding page read or write the iframe's storage directly; use
postMessagewith an explicittargetOriginfor any coordination, and validateevent.originon receipt. - Do not smuggle a cross-site identifier through the URL,
postMessage, or fingerprinting to reconstruct what ITP removed. Beyond the policy risk, it is fragile: Apple actively iterates on mitigation, and behavior can shift between WebKit releases. - Server-side, log which top-level site a session belongs to. This is legitimate first-party analytics for your embed and replaces most of what teams wanted cross-site tracking for.
Operational checks: verifying partition behavior
Do not debug ITP from user reports. Reproduce it directly:
- Check the Safari version via Safari → About Safari, and correlate expected behavior with the WebKit release notes for that major version. Partition key derivation changed between Safari 14 and 16, so version matters when triaging inconsistencies.
- Open Web Inspector (Develop → Show Web Inspector; enable the Develop menu in Settings → Advanced if hidden). Load your embed on two different customer test sites.
- In the Storage tab, inspect Cookies and Local Storage for your domain. You should see separate entries per top-level site. If you see a shared value across both sites, something in your stack is bypassing the iframe boundary — find it before users do.
- Exercise the login redirect flow and confirm the first-party cookie set in top-level context persists, while the iframe-context cookie remains partitioned.
No special permissions are needed beyond access to a macOS machine or a Safari-capable test environment; these are read-only inspections with no rollback concerns. Be aware that enabling advanced privacy settings or content blockers can change behavior further, so test the default configuration first, then hardened ones.
Failure modes
- Intermittent "logged out" reports. Often a version-specific partition key change or storage eviction, not your code. Correlate reports with Safari version before changing anything.
- Analytics undercounting Safari users. Expected, not a bug — partitioned sessions inflate unique-visitor counts if your pipeline assumes cross-site identity. Adjust metrics definitions rather than the tracking.
- Silent cookie rejection. A missing
Secureattribute on aSameSite=Nonecookie fails without a server-side error. Check response headers in Web Inspector's Network tab.
What would change the design
Revisit this architecture if: your embed genuinely requires cross-site identity (a sign the product model, not the browser, needs to change); Apple alters partition key derivation again in a way that breaks legitimate per-site sessions; or your traffic shifts such that WebKit's Storage Access API — which lets an iframe request unpartitioned access after a user gesture — becomes worth the UX cost. For most embeds, per-partition state plus server-side sessions remains the smallest design that works, and the one least likely to break on the next Safari release.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.