Storage Access API: Request Cookie Access in Iframes

The Storage Access API provides a standardized way for cross-site content embedded within <iframe> elements to regain access to first-party storage and unpartitioned cookies under modern browser privacy restrictions. As major browsers phase out or block third-party cookies by default, this API enables legitimate embedded services—such as federated authentication widgets, payment gateways, and social plugins—to explicitly request user permission to access their cookies without bypassing user privacy safeguards.

What is the Storage Access API?

Modern web browsers like Apple Safari, Mozilla Firefox, and Google Chrome restrict third-party cookies to prevent cross-site user tracking. While this improves privacy, it breaks legitimate use cases where embedded <iframe> content needs access to session cookies or local storage associated with its own domain.

The Storage Access API solves this problem by allowing cross-origin iframes to check if they have access to their unpartitioned storage and, if not, request it directly from the user or browser heuristics.

Prerequisites for Using the API

Before requesting storage access via JavaScript, specific conditions must be met:

  1. User Activation: The request must be triggered by a direct user interaction, such as a click or tap. Calling the API programmatically without user intent will automatically fail.
  2. Iframe Sandbox Attributes: If the embedding <iframe> uses the sandbox attribute, it must include allow-storage-access-by-user-activation, alongside allow-scripts and allow-same-origin.
  3. Top-Level Interaction: Most browsers require the user to have previously interacted with the embedded domain as a top-level website.
<iframe 
  src="https://embed.example.com" 
  sandbox="allow-scripts allow-same-origin allow-storage-access-by-user-activation">
</iframe>

The API operates on two primary asynchronous methods attached to the document interface: document.hasStorageAccess() and document.requestStorageAccess().

Step 1: Check for Existing Access

Before requesting access, check whether the iframe already has storage access using document.hasStorageAccess(). This method returns a Promise that resolves to a boolean.

async function checkStorageAccess() {
  if ('hasStorageAccess' in document) {
    const hasAccess = await document.hasStorageAccess();
    if (hasAccess) {
      // Storage access is already granted
      loadAuthenticatedContent();
    } else {
      // Storage access is not available; show UI to prompt user
      showLoginOrAccessButton();
    }
  } else {
    // Fallback for browsers that do not support the API
    loadAuthenticatedContent();
  }
}

Step 2: Request Storage Access on User Interaction

If access is not granted, attach a click listener to a button or interactive element. Calling document.requestStorageAccess() within the event handler initiates the request. The browser will either grant access automatically based on heuristics or display a permission prompt to the user.

const requestButton = document.getElementById('request-access-btn');

requestButton.addEventListener('click', async () => {
  try {
    await document.requestStorageAccess();
    // Access granted: Cookies are now accessible
    loadAuthenticatedContent();
  } catch (error) {
    // Access denied or failed
    console.error('Storage access was denied:', error);
  }
});

Step 3: Access Cookies

Once the promise returned by document.requestStorageAccess() resolves, the iframe gains access to its first-party cookie jar. Standard JavaScript cookie operations, such as document.cookie and network requests made via fetch() or XMLHttpRequest with credentials: 'include', will include the domain’s unpartitioned cookies.