Storage Partition Boundary
The browser-owned boundary that keys storage, communication APIs, service workers, blob URLs, HTTP cache entries, and network state by origin plus contextual site information rather than by origin alone.
Storage partitioning is often described as stricter third-party storage. That is true, but too narrow. Chromium now treats browser-held state as contextual: the same embedded origin may receive different storage, workers, cache entries, blob URL access, and network warmness under different top-level sites and frame contexts.
What It Is
The storage partition boundary is Chromium’s rule that browser-held state is not globally keyed by origin alone. A page from https://chat.example embedded on https://news.example and the same page embedded on https://shop.example may share an origin, but Chromium can place their storage and communication state in different partitions. The origin still matters. It is not the whole key.
For client-side storage, the implementation vocabulary is StorageKey. Chromium’s StorageKey stores the origin plus, when third-party storage partitioning is enabled, a top-level site and an ancestor-chain bit. The top-level site distinguishes the embedding context. The ancestor-chain bit covers nested iframes where an apparently same-site frame is reachable only through a cross-site ancestor. Without that bit, a.com embedded inside b.com inside a.com could look first-party by origin and top-level site. The cross-site middle frame still influences the context.
For the network path, the parallel vocabulary is NetworkIsolationKey and related network partition keys. Chrome’s HTTP cache partitioning uses the top-level site, the current-frame site, and the resource URL. Network State Partitioning applies a similar contextual key to connection and protocol state: HTTP/1, HTTP/2, HTTP/3 and WebSocket connections, DNS cache entries, ALPN and HTTP/2 support data, TLS and HTTP/3 resumption information, Network Error Logging, Reporting, and Expect-CT state. A third-party frame that has seen a connection become warm under one top-level site should not observe that warmness under another.
The boundary reaches more than storage tables. Chrome’s Storage Partitioning documentation lists Local Storage, IndexedDB, Cache Storage, Origin Private File System, Storage Buckets, Clear-Site-Data behavior, BroadcastChannel, SharedWorker, Web Locks, service workers, extension contexts, and Blob URLs. Starting with Chrome 137, cross-partition Blob URL fetching and subresource use are blocked; top-level navigations remain a special case, with noopener enforced for cross-site initiators. The result is a family of partitioned surfaces, not one API.
Why It Matters
The boundary closes a tracking and side-channel path that Site Isolation alone doesn’t close. Site Isolation keeps different sites from sharing renderer address space. It does not, by itself, stop a third-party iframe from using browser-owned state as a cross-site rendezvous point. Before partitioning, an embedded origin could write an identifier in one top-level site and read it when embedded elsewhere. It could also infer state indirectly: whether a cache entry, connection, worker, or shared communication channel already existed.
The concept also clarifies where the authority lives. A renderer may call localStorage, create a BroadcastChannel, register a service worker, fetch a Blob URL, or request a resource. The browser decides which partition that call lands in. That decision is based on browser-side context: origin, top-level site, frame site, ancestor-chain status, and isolation data. The renderer doesn’t get to declare “use the global same-origin bucket” when it runs in a third-party context.
For enterprise Chromium consumers, this boundary explains a class of web-compatibility reports that otherwise look arbitrary. An embedded login flow stops sharing IndexedDB with the same origin under a different top-level site. A BroadcastChannel no longer connects two same-origin iframes on unrelated pages. A service worker registered from a third-party context doesn’t control every same-origin context on the web. A CDN asset misses the HTTP cache because the top-level site changed. Each symptom is different, but the rule is the same: browser-held state is scoped by context.
For AI coding agents, the boundary is a common source of invalid assumptions. Training data and older examples often treat origin as the only storage and cache key. That model is now wrong for Chromium. Code that assumes same-origin iframes share all storage, cross-embed Blob URL access, or cache and connection reuse across top-level sites is reasoning against the pre-partitioning web.
How to Recognize It
The word StorageKey is the strongest source-tree signal. third_party/blink/public/common/storage_key/storage_key.h documents the transition directly: when third-party storage partitioning is disabled, a storage key is equivalent to an origin; when enabled, it also contains a top-level site and ancestor-chain bit. Code that asks for a storage key is asking which partition the browser should use.
Network code uses a different name for the same kind of boundary. net/base/network_isolation_key.h documents NetworkIsolationKey as the key used to partition shared network state and names the top-frame site and frame site fields. Request code often reaches this through IsolationInfo, which is why the URLLoaderFactory Trust Boundary article treats factory creation as a security-sensitive moment. A request’s storage and network authority are stamped before the renderer sees the factory.
Privacy Sandbox documentation surfaces the API-level behavior. The boundary is active when a third-party iframe can no longer read IndexedDB data written under another top-level site, navigator.storage.estimate() reports per-partition quota, Clear-Site-Data clears only one partition, or a third-party BroadcastChannel no longer reaches a same-origin context elsewhere.
Blob URL failures are another signal. A Blob URL minted by a third-party iframe on one top-level site may fail when fetched as a subresource from the same embedded origin under another top-level site. A top-level navigation to that Blob URL may still work, but Chromium enforces noopener when the initiator and Blob URL site are cross-site. That split is not accidental; it is the compatibility exception around a partition boundary.
How It Plays Out
An embedded identity provider uses IndexedDB to remember an intermediate authentication state. Before partitioning, an iframe from the provider could store that state while embedded on one relying party and read it while embedded on another. After partitioning, the provider receives a separate storage partition for each top-level site. The login flow now needs an explicit cross-site authentication design, such as Storage Access API integration or a server-side redirect path, rather than assuming origin-wide client storage.
A support widget opens a BroadcastChannel named support-session from iframes embedded across several customer sites. The old design expects one same-origin channel spanning all embeds. Chromium’s partitioning breaks that rendezvous: the iframe under customer-a.example and the iframe under customer-b.example no longer discover each other through the channel. The fix is not to bypass the boundary. The fix is to move cross-site coordination to an explicitly authorized server-side channel or to design the widget so each top-level site has its own session.
A performance engineer sees extra DNS lookups and fewer cache hits for a third-party resource after Network State Partitioning. The finding is real. The HTTP cache and connection pools are now separated by top-frame and frame-site context, so a resource warmed under one top-level site doesn’t guarantee a hit under another. The performance cost is the point the blink-dev Intent named: cross-site iframes may lose reuse, but the previous reuse exposed a tracking side channel.
A document creates a Blob URL inside a third-party iframe and sends it to the same origin embedded elsewhere. The receiving iframe tries to fetch it and gets blocked because the URL is mapped to a different storage key. If the user opens the Blob URL as a top-level navigation, Chromium may allow the navigation but enforce noopener so the opener cannot keep a window handle across the partition. The behavior looks uneven until the distinction is named: subresource fetch and navigation have different compatibility constraints, but both are governed by the storage partition boundary.
Consequences
The benefit is a cleaner privacy and trust model for browser-owned state. A third-party context can no longer treat “same origin” as a global rendezvous point across unrelated top-level sites. State that once carried identity, warmness, timing, or coordination signals now stays inside the contextual partition where it was created.
The boundary also gives reviewers a more precise question. Instead of stopping at origin ownership, review asks which origin, top-level site, frame context, ancestor-chain status, and network isolation data apply. That longer question is harder to ask, but it finds bugs the old origin-only question missed.
The liabilities are real. Partitioning reduces cache and connection reuse, especially in cross-site iframes. It can increase DNS requests, TLS handshakes, server connection load, and page latency when a resource previously benefited from cross-site reuse. It can also break sites that depended on same-origin third-party storage, shared workers, service workers, Blob URLs, or BroadcastChannel behavior across embeds. Chrome’s deprecation-trial path exists because some sites needed migration time.
The model is uneven by design. Cookies have CHIPS and Storage Access API paths; Blob URL top-level navigation has an exception; extension pages have special rules; some network-state surfaces are harder to test in web-platform-tests than API-visible storage. That unevenness doesn’t mean the boundary is incoherent. It means Chromium is migrating a live web platform, where the security and privacy goal has to be paid for through compatibility exceptions, diagnostics, and staged rollout.
Notes for Agent Context
When writing Chromium code that chooses storage or network state, treat origin as necessary but insufficient. Use the browser-owned StorageKey, NetworkIsolationKey, IsolationInfo, or SiteForCookies value already associated with the frame, worker, navigation, or factory; never reconstruct a partition key from renderer-supplied strings.
When generating web code for Chromium-targeted pages, do not assume same-origin iframes share Local Storage, IndexedDB, Cache Storage, BroadcastChannel, SharedWorker, Web Locks, service workers, Blob URLs, HTTP cache entries, DNS warmness, or connection pools across different top-level sites. Treat third-party embeds as partitioned by default. Use explicit standards paths such as Storage Access API or CHIPS only where the platform allows them.
When debugging a storage, worker, Blob URL, or cache miss, ask for the top-level site, frame site, origin, ancestor-chain status, and network isolation data before changing code. If a same-origin operation works under one embed and fails under another, treat partition mismatch as the first hypothesis, not as an incidental browser bug.
Related Articles
Sources
Chrome’s Privacy Sandbox Storage Partitioning documentation is the primary public source for third-party storage and communication API partitioning, including the Chrome 115 rollout, the top-level-site rule, the ancestor bit for nested iframes, the affected storage and communication APIs, service-worker partitioning, Blob URL behavior, and deprecation-trial migration path. Eiji Kitamura’s Chrome for Developers article Gaining security and privacy by partitioning the cache documents HTTP cache partitioning by Network Isolation Key and gives the top-level-site / current-frame-site examples. The blink-dev Intent to Ship: Network State Partitioning thread records the network-state scope, performance cost, debug limitations, and Chromium-specific top-frame-site plus frame-site implementation. The blink-dev Implement and Ship: Blob URL Partitioning: Fetching/Navigation thread records the Blob URL fetch and navigation behavior. The PrivacyCG Client-Side Storage Partitioning proposal supplies the standards-side framing: user-agent state keyed by a single origin or site is a privacy and security bug, so additional keying is needed across storage, network, worker, communication, and Blob URL state.
Technical Drill-Down
- Privacy Sandbox — Storage Partitioning — Chrome’s public guide to third-party storage and communication API partitioning, ancestor-chain behavior, Blob URL behavior, and the deprecation-trial migration path.
- Chrome for Developers — Gaining security and privacy by partitioning the cache — HTTP cache partitioning by Network Isolation Key; the examples show the top-level-site and current-frame-site tuple.
- blink-dev — Intent to Ship: Network State Partitioning — launch record for DNS cache, connections, TLS resumption, ALPN/H2 support, Reporting/NEL, and Expect-CT partitioning by network partition key.
- blink-dev — Implement and Ship: Blob URL Partitioning: Fetching/Navigation — rollout record for cross-partition Blob URL fetching, subresource blocking, top-level navigation behavior, and
noopenerenforcement. - PrivacyCG — Client-Side Storage Partitioning — standards-side work item that collates the user-agent state surfaces affected by additional keying.
third_party/blink/public/common/storage_key/storage_key.h(pinned7b9d891) —StorageKeydefinition and comments for origin, top-level site, ancestor-chain bit, and nonce-based partitioning.third_party/blink/common/storage_key/storage_key.cc(pinned7b9d891) — serialization logic for top-level-site and ancestor-chain-bit partition attributes.net/base/network_isolation_key.h(pinned7b9d891) —NetworkIsolationKeydefinition for partitioning shared network state by top-frame site, frame site, nonce, and network isolation partition.storage/browser/blob/blob_url_store_impl.cc(pinned7b9d891) — Blob URL store code path that blocks cross-partition fetching while preserving top-level navigation exceptions.