RoastMyOpsec

Safety

COOP vs COEP for Cross-Origin Isolation on Public Sites

September 5, 2022

COOP vs COEP is not a paired mandatory stack for every public site. Cross-Origin-Opener-Policy (COOP) same-origin puts the document in its own browsing context group so window.opener and some cross-origin window tricks stop working. Cross-Origin-Embedder-Policy (COEP) require-corp (with CORP on subresources) is how you opt into cross-origin isolation for high-risk APIs — and it is how tag managers, fonts, and embeds break. Marketing sites should usually ship COOP same-origin-allow-popups or same-origin after testing popups, and treat COEP as a product decision, not a default. RoastMyOpsec's free header audit focuses on CSP, HSTS, framing, Referrer-Policy, nosniff, and Permissions-Policy on the primary HTML response. COOP/COEP are extra isolation; missing them is not the same as missing HSTS.

The practical difference

COOP is about who shares your top-level window. same-origin is the usual lock. same-origin-allow-popups is the compromise when you still open payment or OAuth windows. unsafe-none is the historical default.

COEP is about what you may embed. require-corp demands Cross-Origin-Resource-Policy (or CORS) on every cross-origin subresource. That is correct for a document that needs SharedArrayBuffer-class isolation. It is hostile to a CMS full of third-party scripts. CORP on the HTML itself (same-origin or same-site) is a smaller relative of this story — it tells other sites whether they may embed your resource.

How to choose based on the page

Brochure homepage, blog, docs: try COOP same-origin (or allow-popups if checkout opens a window). Leave COEP off until you have a reason. App shells that need isolation: COEP + CORP on assets, plus COOP, tested in staging against every embed.

Do not copy a 'maximum isolation' snippet onto a site whose revenue is a pixel. You will spend a week on font CORS.

HeaderJobWhen it winsTakeaway
COOP same-originSeparate browsing context; drop openerMost public HTML that should not be window-tiedFirst isolation header to try
COOP allow-popupsSame, but OAuth/pay popups still workLogin or checkout that window.opensTest the popup flow before enforcing
COEP require-corpCross-origin isolation / strict embedsApp surfaces that need it and control every assetNot a marketing-site default
CORP on documents/assetsWho may load this resource as a subresourceAPIs and static files you do not want hotlinked as embedsPair with COEP only when you chose isolation

What a RoastMyOpsec header pass means

A clean free header pack means the core browser guardrails were present on that response. It does not grade COOP/COEP. Framing is still CSP frame-ancestors / X-Frame-Options — COOP is not a clickjacking substitute. See the CSP vs X-Frame-Options guide.

Common mistakes

The first mistake is COEP on www and a broken GTM container as the 'security win.'

The second mistake is COOP unsafe-none forever because a popup was never retested.

The third mistake is treating isolation headers as equal to CSP.

Free audit the URL you own

RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.

Free audit now

FAQ

Should every marketing site ship COEP?
Usually no. COEP require-corp breaks third-party tags unless every asset sends CORP or CORS. Start with COOP if you want isolation at all.
Does RoastMyOpsec score COOP and COEP?
The free header checklist is CSP, HSTS, framing, Referrer-Policy, nosniff, and Permissions-Policy. COOP/COEP are additional; confirm them in staging and at the CDN.
Is COOP the same as X-Frame-Options?
No. Framing controls who may iframe you. COOP controls browsing-context groups and opener. Ship framing either way.

Sources

Related guides