Cross-Origin Isolation Headers Guide
What COEP, COOP, CORP, and Origin-Agent-Cluster actually do, how they work together, and when your site genuinely needs them.
Why the Default Same-Origin Policy Isn't Enough
Browsers have always enforced a same-origin policy that prevents one site's JavaScript from directly reading another site's data — but "directly reading" turns out to be a narrower protection than it sounds. Side-channel attacks, most famously the Spectre class of CPU-level vulnerabilities disclosed in 2018, can potentially extract data across origins by measuring timing differences in shared process memory, entirely bypassing the same-origin policy's data-access restrictions since they never actually read the data through a JavaScript API at all.
Browser vendors' response was process isolation: running each origin in its own operating system process, so there's no shared memory for a side-channel attack to exploit in the first place. But full, aggressive process isolation for every cross-origin resource on a page has real performance costs, so browsers made it opt-in for pages that want the strongest available guarantees — which is exactly what this family of headers enables.
require-corp mode without first auditing every cross-origin image, script, and iframe your page loads. Any resource that doesn't explicitly opt in will simply fail to load, often silently, breaking the page in ways that are easy to miss during casual testing.Cross-Origin-Opener-Policy (COOP): Isolating Your Browsing Context
COOP controls whether your page shares a browsing context group — the underlying process and memory space a browser may use for related windows — with cross-origin windows that open it or that it opens, such as through window.open() or a link with target="_blank". Setting Cross-Origin-Opener-Policy: same-origin ensures your page gets its own dedicated browsing context group, cut off from cross-origin windows entirely, which closes off a category of attacks where a malicious page that opened yours (or that yours opened) could otherwise retain a reference to your window object and probe it for information.
A softer option, same-origin-allow-popups, isolates your page from cross-origin openers while still permitting popups you open yourself to remain connected, useful for legitimate OAuth-style popup flows where your page genuinely needs to communicate with a window it opened. Getting COOP right is also a prerequisite for the strongest cross-origin isolation guarantees, which require COOP and COEP working together, covered next.
Cross-Origin-Embedder-Policy (COEP): Locking Down What You Embed
COEP controls the reverse direction from COOP: instead of governing who can open or reference your page, it governs which cross-origin resources your page is allowed to embed — images, scripts, iframes, and similar. Setting Cross-Origin-Embedder-Policy: require-corp means every cross-origin resource your page loads must explicitly opt in via its own CORP header (covered next) or a CORS response, or the browser blocks it from loading at all. This is the header that most directly enables full process-level cross-origin isolation, since it guarantees every embedded resource has affirmatively agreed to being embedded under these stricter conditions.
COEP's practical cost is real: any third-party embed, widget, ad, or font that doesn't serve the right headers will simply break once require-corp is enabled, which is why rolling it out on an existing, resource-heavy page requires a genuine audit rather than a one-line header change. A newer, less disruptive option, credentialless, allows cross-origin resources to load without requiring their explicit opt-in, but strips credentials (cookies, client certificates) from those requests — a middle ground that preserves more compatibility while still enabling cross-origin isolation for resources that don't need to be loaded with credentials.
Cross-Origin-Resource-Policy (CORP): The Opt-In Your Resources Need to Send
CORP is set by the resource being embedded, not by the page doing the embedding — it's how an image, script, or font hosted on one origin explicitly states which other origins are permitted to embed it. Setting Cross-Origin-Resource-Policy: same-site permits embedding by pages on the same site (including different subdomains), while cross-origin permits embedding from any origin, and same-origin restricts it to the exact same origin only. Without a CORP header at all, a page with COEP's require-corp enabled will simply refuse to load that resource, regardless of how permissive the resource owner might actually want to be.
This makes CORP a genuinely two-sided coordination problem: a page can enable COEP all it wants, but every cross-origin resource it depends on also needs its own server correctly configured with a compatible CORP header, which is precisely why third-party embeds — ones you don't control the server configuration for — are the most common point of failure when adopting cross-origin isolation.
How COOP, COEP, and CORP Work Together
| Header | Who Sets It | What It Controls |
|---|---|---|
| COOP | Your page | Whether cross-origin windows share your browsing context group |
| COEP | Your page | Whether embedded cross-origin resources must explicitly opt in |
| CORP | The embedded resource's own server | Which origins are permitted to embed that specific resource |
Full "cross-origin isolation" — the state that unlocks certain powerful browser APIs like SharedArrayBuffer and high-resolution timers, both restricted specifically because of their historical role in Spectre-style timing attacks — requires both COOP set to same-origin and COEP set to require-corp or credentialless simultaneously. Your page can check whether it achieved this state at runtime via self.crossOriginIsolated, which returns true only when both conditions are actually met.
Origin-Agent-Cluster: A Related but Distinct Isolation Signal
Origin-Agent-Cluster is a separate header that requests origin-keyed process isolation specifically, rather than the document-level embedding controls COOP/COEP/CORP provide. Setting Origin-Agent-Cluster: ?1 asks the browser to place your page in its own dedicated agent cluster keyed to the exact origin (scheme, host, and port together), rather than the coarser same-site grouping browsers use by default, which can improve both security isolation and, in some cases, memory management for pages with heavy JavaScript workloads.
Unlike COOP and COEP, Origin-Agent-Cluster doesn't affect what your page can embed or who can open it — it's purely a hint about process isolation granularity, and browsers are free to honor or ignore it based on their own resource constraints, making it a "request" for stronger isolation rather than a guarantee in the way COOP and COEP's blocking behavior is.
Report-Only Modes for Safer Rollout
Several of these headers support a reporting-focused variant that logs what would have been blocked without actually enforcing the restriction, letting you observe real-world impact before committing to enforcement. Cross-Origin-Opener-Policy-Report-Only and Cross-Origin-Embedder-Policy-Report-Only, paired with a configured reporting endpoint, surface exactly which cross-origin interactions would be affected by the corresponding enforcing header, based on real production traffic rather than manual testing alone, which tends to miss edge cases that only show up under genuine usage patterns.
This reporting-first approach is particularly valuable for COEP specifically, given how disruptive an unexpected enforcement rollout can be on a page with many third-party dependencies — running in report-only mode for a meaningful observation period before switching to full enforcement catches compatibility issues while they're still just log entries, not visible breakage a real visitor encounters.
Real Scenarios for Adopting Cross-Origin Isolation
A web application needs SharedArrayBuffer for a performance-critical feature like in-browser video editing or a WebAssembly-based computation engine, and discovers the API is restricted specifically because it was historically abused as a high-resolution timing primitive for Spectre-style attacks. Enabling full cross-origin isolation via COOP and COEP is the only path to unlocking it in a modern browser.
A media-heavy publisher rolls out COEP and immediately finds several third-party ad and analytics scripts silently fail to load, since those providers hadn't yet configured CORP headers on their own infrastructure. This is resolved either by switching to COEP's credentialless mode where compatible, or by working directly with the third-party providers to confirm their CORP configuration.
A team building an OAuth login popup flow needs their main page to remain able to communicate with a popup window it opens on a different origin during authentication, while still gaining COOP's protection against unrelated cross-origin windows retaining a reference to it — the specific use case same-origin-allow-popups was designed for.
A security team auditing header configuration notices Origin-Agent-Cluster isn't set anywhere on their infrastructure, and adds it as a low-risk, purely additive improvement, since it doesn't change what content loads or breaks anything the way COEP can — it only requests stronger process isolation where the browser is able to provide it.
How Browsers Communicate a Blocked Cross-Origin Load
When COEP's require-corp mode blocks a cross-origin resource that lacks a compatible CORP header, the failure typically surfaces as a generic network error in the browser's developer console — often indistinguishable at a glance from a genuine network failure or a CORS misconfiguration, which makes debugging a COEP rollout meaningfully harder than debugging most other header-related issues. Learning to recognize this specific failure signature (a resource that loads fine with COEP disabled but fails silently once enabled) is a practical skill worth building before attempting a production rollout.
Browser developer tools have gradually improved at surfacing more specific error messages for COEP-related blocks specifically, distinguishing them from generic network failures, but the improvement has been incremental across browser versions rather than universal — testing across multiple current browsers during rollout remains worthwhile rather than assuming one browser's console output tells the complete story.
When You Actually Need This vs When It's Unnecessary Overhead
Full cross-origin isolation is specifically necessary if your application uses APIs that require it, most notably SharedArrayBuffer, high-precision timers beyond the browser's default-restricted resolution, or certain WebAssembly threading features. For a typical content site, blog, or standard web application that doesn't touch these specific APIs, the meaningful security benefit of full COOP+COEP isolation is real but more marginal, while the compatibility cost (breaking third-party embeds that aren't configured for it) can be substantial enough that it's not worth pursuing without a concrete reason.
COOP alone, without COEP, is a more broadly reasonable default for most sites — it provides genuine protection against cross-window reference attacks with far less compatibility risk than the full COEP-driven isolation, since it doesn't require every embedded resource to be reconfigured. CORP, similarly, is worth setting on your own resources (images, fonts, scripts you serve) regardless of whether you ever adopt COEP yourself, since it costs you nothing and helps any other site that does adopt COEP and wants to embed your content safely.
Interaction With Content Security Policy
Cross-origin isolation headers and CSP address genuinely different threat models and operate independently of each other, but a site adopting both should be aware they can interact in subtle ways — a CSP directive restricting frame-src or connect-src too tightly can inadvertently block resources that would otherwise be permitted under a correctly configured CORP policy, producing a failure that looks identical to a cross-origin isolation problem but actually traces back to CSP configuration instead. When debugging an unexpected resource-loading failure on a page using both header families, checking both configurations independently rather than assuming which one is responsible saves real debugging time.
Our companion guide on how Content-Security-Policy works covers CSP's own directive syntax in depth, which is worth understanding alongside this guide specifically because the two header families are commonly deployed together as part of a broader security-hardening effort, even though they're independently specified and enforced.
Checking Your Current Cross-Origin Isolation Status
Whether these headers are actually present, and correctly configured, on your live site is something worth verifying directly rather than assuming from your server configuration files alone — a misconfigured reverse proxy, CDN, or load balancer can silently strip or alter headers between your application and the actual response a browser receives. Our Security Headers Checker and HTTP Headers Checker both show the actual live headers a domain is serving, which is the only reliable way to confirm what's really being sent.
FAQ
ToolsNovaHub guides are researched against primary sources (RFCs, vendor docs) and kept up to date as standards change. Spotted an error? Let us know.
📋 Related Tools & Guides Comparison
| Resource | Type | Link |
|---|---|---|
| Security Headers Checker | Tool | Open Tool → |
| HTTP Headers Checker | Tool | Open Tool → |
| Browser Permissions & Fetch Metadata Headers | Guide | Read Guide → |
| Security Headers Explained | Guide | Read Guide → |