Response header
< Cross-Origin-Opener-Policy: same-originCross-Origin-Opener-Policy
Learn how Cross-Origin-Opener-Policy (COOP) isolates your browsing context from cross-origin documents. Required for SharedArrayBuffer and enhanced security.
- Direction
- Response
- Category
- Security
- Spec
- HTML Standard
On this page
TL;DR:
Cross-Origin-Opener-Policy: same-originseparates your top-level document from incompatible popup/opener contexts. It can break OAuth and payment popup callbacks. Use it with COEP for cross-origin isolation;same-origin-allow-popupspreserves only certain popup relationships.
What is Cross-Origin-Opener-Policy?
COOP determines whether top-level documents share a browsing context group. A group switch severs their window references. This is different from CORS, which controls sharing fetched responses, and from X-Frame-Options, which controls framing. Both documents’ origins and policies matter. HTML defines the matching rules.
Syntax
Cross-Origin-Opener-Policy: same-origin
Return it on the document response. It is not an API access-control header.
Value Guide
unsafe-noneis the default. It does not request isolation, but another document’s policy can still force a group switch.same-originshares a group only with same-origin documents that have a matching policy.same-origin-allow-popupsmatches same-origin documents with that same policy, and permits popups opened withwindow.open()to remain connected when the popup usesunsafe-none.noopener-allow-popupssevers the incoming opener relationship, including from same-origin openers, while allowing the document to openunsafe-nonepopups.
These are behavioral rules, not guarantees of a particular OS process layout. Consult MDN’s navigation and window.open tables for combinations.
Example
Illustrative document response header excerpt:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Verify in the document:
console.log(window.isSecureContext, window.crossOriginIsolated)
Implementation
Inside the nginx server or location serving HTML:
add_header Cross-Origin-Opener-Policy "same-origin" always;
Use nginx’s header directive and inspect the final response after proxies or middleware have run. Duplicate or overridden policy headers are harder to diagnose than a single policy owned by one layer.
For an existing Express app, register document middleware before the route serving HTML:
app.use('/isolated', (_req, res, next) => {
res.set({
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp'
})
next()
})
app.get('/isolated', (_req, res) => {
res.sendFile('isolated.html', { root: '/srv/app/public' })
})
Create /srv/app/public/isolated.html for this route. Express supports header middleware and rooted file responses. Scope these headers to the documents that need isolation, then test their resources and popup flows.
Operational Impact
For a popup flow, inspect the document response after every navigation, including the identity-provider page and callback. A group switch can make window.opener null and make the opener’s retained window handle appear closed. MDN documents severed window.open references.
Calling window.opener.postMessage(...) when window.opener is null throws; it does not silently deliver or silently succeed. Log the opener value on the callback page before investigating message handlers.
COOP, COEP, and CORP Together
COOP controls window relationships. COEP controls resource embedding requirements. CORP is one resource-side way to satisfy no-cors embedding requirements. A global CORP header is not a third mandatory switch for isolation; successful CORS loads can satisfy the resource checks instead.
COOP and Cross-Origin Isolation
For a secure top-level document, use COOP same-origin with COEP require-corp or credentialless. The cross-origin-isolated permissions policy must also allow the capability. Check crossOriginIsolated before selecting a SharedArrayBuffer path.
same-origin-allow-popups does not provide that isolation capability. It can preserve an OAuth popup using unsafe-none, but cannot override a restrictive policy sent by the provider. Test the actual provider and callback rather than assuming that changing the opener header repairs every flow. Redirect-based login avoids depending on a surviving popup opener reference.
Related Headers
Frequently asked questions
What is Cross-Origin-Opener-Policy?
COOP controls whether top-level documents share a browsing context group. Matching depends on both documents policies and origins, and a group switch severs window references.
What values can COOP have?
The values are unsafe-none, same-origin, same-origin-allow-popups, and noopener-allow-popups. unsafe-none is the default; popup exceptions depend on the other document policy.
Why use COOP?
COOP limits opener relationships and helps mitigate cross-window attacks. COOP same-origin combined with an appropriate COEP policy can enable cross-origin isolation.
What is cross-origin isolation?
In a secure context, COOP same-origin plus COEP require-corp or credentialless can enable the capability, unless permissions policy blocks it. Verify window.crossOriginIsolated rather than headers alone.
Sources
Related
Reporting-Endpoints Header: Reporting API Setup
Reporting-Endpoints names the URLs where browsers send CSP, COOP, deprecation and crash reports. Syntax, the default endpoint, and replacing Report-To.
Access-Control-Allow-Credentials Header
Learn how Access-Control-Allow-Credentials controls whether browsers expose responses when credentials (cookies, auth headers) are included in CORS requests.
Access-Control-Allow-Headers Header
Learn how Access-Control-Allow-Headers specifies which custom HTTP headers can be used during cross-origin requests in CORS preflight responses.
Access-Control-Allow-Methods Header
Learn how Access-Control-Allow-Methods specifies which HTTP methods are permitted for cross-origin requests in CORS preflight responses.