Storage Access API: requesting third-party cookie access from an iframe
In one line: The Storage Access API “provides a way for cross-site content loaded in a
third-party context (i.e., embedded in an <iframe>) to gain access to third-party cookies
and unpartitioned state that it would typically only have access to in a first-party
context,” for browsers that block unpartitioned third-party cookies by default.
The problem it solves
Section titled “The problem it solves”Browsers restrict access to unpartitioned third-party cookies — “all cookies for a site
stored in one shared jar” — in a third-party <iframe> context to prevent cross-site
tracking. That breaks legitimate cases such as single sign-on with a federated identity
provider or a personalization service embedded across multiple related sites. The Storage
Access API is, per MDN, “intended to solve this problem” without requiring users to disable
third-party cookie blocking outright.
Checking and requesting access
Section titled “Checking and requesting access”const hasAccess = await document.hasStorageAccess();if (!hasAccess) { await document.requestStorageAccess();}Document.hasStorageAccess() resolves to a boolean indicating whether the document already
has access to third-party cookies. Document.requestStorageAccess() requests the
storage-access permission and resolves if granted, or rejects if denied.
Document.hasUnpartitionedCookieAccess() is documented as the new name for
hasStorageAccess().
Transient activation is required
Section titled “Transient activation is required”Per MDN: “requestStorageAccess() requests are automatically denied unless the embedded
content is currently processing a user gesture such as a tap or click (transient
activation), or if permission was already granted previously.” That is why a real
integration calls it from inside a click handler rather than on page load.
Feature detection and fallback
Section titled “Feature detection and fallback”function doThingsWithCookies() { document.cookie = "foo=bar";}
async function handleCookieAccess() { if (!("requestStorageAccess" in document)) { // Storage Access API unsupported here — fall back to hoping cookies work, // as recommended by MDN for browsers without this API. doThingsWithCookies(); return; } const hasAccess = await document.hasStorageAccess(); if (hasAccess) { doThingsWithCookies(); return; } btn.addEventListener("click", async () => { try { await document.requestStorageAccess(); doThingsWithCookies(); } catch (err) { console.error(`Error obtaining storage access: ${err}. Please sign in.`); } });}Sandboxed iframes need an explicit token
Section titled “Sandboxed iframes need an explicit token”A sandboxed <iframe> must carry the allow-storage-access-by-user-activation sandbox
token (along with allow-scripts and allow-same-origin) for a requestStorageAccess()
call from inside it to succeed:
<iframe sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin"> …</iframe>Grant scope and re-activation
Section titled “Grant scope and re-activation”A grant is keyed by <top-level site, embedded site> — MDN gives the example of embedding
locator.example.com on embedder.com: the grant covers “any subdomain of example.com
embedded on any page of embedder.com.” Even after a grant exists, each new browsing
context (a new tab, or a fresh iframe instance) must call requestStorageAccess() again to
activate it there — though MDN notes that call “won’t require transient activation once
already granted.” A same-origin self-navigation or reload after being granted access carries
the access over without a new call.
Requirements that can cause a rejection
Section titled “Requirements that can cause a rejection”MDN lists several conditions under which requestStorageAccess() is denied: the document
and top-level document must not have a null origin; the window must be a secure context
(HTTPS); the embedded origin must have interacted with the browser as first-party recently;
and access “can be blocked by a storage-access Permissions Policy header set by the
server.” MDN also notes the document “may also be required to pass additional
browser-specific checks” such as allowlists, blocklists, or user settings.
Support
Section titled “Support”MDN documents Document.hasStorageAccess, Document.hasUnpartitionedCookieAccess,
Document.requestStorageAccess, and the non-standard, deprecated
Document.requestStorageAccessFor each with their own browser compatibility table; check
those tables for the current per-browser support position before depending on this API in
production.
Practical checklist
Section titled “Practical checklist”- Feature-detect with
if (!document.hasStorageAccess)before calling any method — MDN’s own example falls back to just trying the cookie operation when the API is absent. - Call
requestStorageAccess()from inside a user-gesture event handler (e.g. a click), not on page load — it is denied outside transient activation unless already granted. - Wrap
requestStorageAccess()intry...catch; the returned promise rejects when the user denies access or the gesture requirement is not met. - Add the
allow-storage-access-by-user-activationsandbox token to a sandboxed<iframe>that needs to call this API, alongsideallow-scriptsandallow-same-origin. - Re-call
requestStorageAccess()in each new tab or iframe instance even after a grant exists elsewhere for the same<top-level site, embedded site>pair. - Note that
Document.requestStorageAccessFor()is non-standard and deprecated; it lets a top-level site request access, for an embed in the same related website set, on behalf of that embed instead of the embed calling the API itself.
Cross-references
Section titled “Cross-references”- Storage persistence — a related storage guarantee
- Storage eviction — a related storage lifecycle guarantee