#TypeScript#DevOps

COOP/COEP Cross-Origin Isolation Migration: Resource Closures, Popup Compatibility, and Reversible Rollouts

Adding COOP/COEP to your homepage may enable SharedArrayBuffer, but it can also sever OAuth Popups, third-party iframes, and CDN resources. This article completes the migration using dependency closures, a reporting period, and runtime capability gates.

Key Points

  • Topic Focus: TypeScript、DevOps
  • Suitable for: indie hackers, full-stack engineers, AI application developers
  • Core value: quickly understand background, practical paths, common pitfalls, and engineering advice
Author @admin·Published July 26, 2026·Updated July 26, 2026

SharedArrayBuffer and Wasm threads often require the page to be in a cross-origin isolated state. Directly sending Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp may turn your performance tests green while stripping the OAuth Popup of window.opener, preventing the payment window from returning results, or causing ads, fonts, and nested workers to be blocked by the browser. Web Worker Concurrency Fundamentals explains threading capabilities, and Browser Wasm Asset Integrity only determines whether a particular model needs isolation; this article governs the entire site migration.

First, freeze the real dependency closure

Publish crossOriginIsolationRelease.v1, binding the route/origin scope, COOP/COEP values, browser matrix, required capabilities, top-level and nested documents, static and dynamic sub-resources, worker/Wasm, redirect chains, Popup/opener flows, credential modes, Reporting endpoint, Service Worker release, and fallback. The inventory must come from final network responses and synthetic journeys, not just source-code import scans.

yaml
schema: crossOriginIsolationRelease.v1
release: isolation-7
scope: https://compute.example.com/*
coop: same-origin
coep: require-corp
requiredCapability: wasm-threads@2
resourceInventoryRoot: sha256:61c...
popupFlows: [oauth-full-page-redirect@3]
fallback: single-thread@5

COOP determines whether the top-level page and the opener can still be in the same browsing context group; COEP determines whether the page can embed cross-origin resources without explicit permission. Ordinary cross-origin sub-resources must either go through successful CORS or return an appropriate Cross-Origin-Resource-Policy according to their fetch mode; cross-origin iframes and nested workers must also satisfy their respective document/script policies. credentialless changes the behavior of credentials carried by no-cors requests, and you must not treat it as an "automatic fix when require-corp errors".

Establish flow-level alternatives for OAuth, payment, and editor Popups: prefer same-page redirects, backend code exchange, or isolate to a separate origin that doesn't need SharedArrayBuffer. You must not weaken the policy of the main compute origin for a single Popup while continuing to claim it is cross-origin isolated. CORS and CSP provides general cross-origin boundaries; this contract fixes the owner and exit date for each exception.

Response headers and runtime capabilities together form the acceptance point

The states are INVENTORY -> REPORT_ONLY -> REMEDIATING -> CANARY_ENFORCED -> ENFORCED -> RETIRED. First send COOP/COEP Report-Only in supported browsers and receive versioned reports; a lack of reports does not equal safety, and CI must also run real journeys with enforcing headers. CDNs, reverse proxies, error pages, and redirect targets must all be verified in response fixtures, to avoid only the 200 HTML carrying the correct headers.

Enforcing headers only take effect for new Document navigations and cannot upgrade the current page in place. Before launching threads/SAB, the app should simultaneously validate self.crossOriginIsolated === true, the release ID, and specific API capabilities; otherwise it enters the single-threaded fallback or requires a navigation, never continuing down the shared-memory path after catching an exception. Service Worker cached navigations and resource responses are also part of the closure and must be swapped in sync with Service Worker Release Activation to prevent old caches from masking header changes.

Isolated pages can coexist with non-isolated pages on different origins, but auth tokens, postMessage target origins, and data classification must not be relaxed as a result. If Popups still exist, messages must verify the exact origin, flow nonce, and state; you must not use * to restore the implicit trust severed by COOP. Feature Toggle only selects cohorts; response headers and capability checks are the facts of isolation.

Break third parties and old browsers one by one

The failure matrix removes font CORP, redirects images with 302 to an unapproved CDN, makes worker importScripts pull cross-origin scripts, returns headerless 404s, serves navigations from old SW cache, reads opener in OAuth and payment Popups, applies credentialless to resources that need cookies, makes the browser not support the required threads, and simulates the reporting endpoint dropping events. Assert that eligible forced pages have crossOriginIsolated true, that protected capabilities launch zero times when it is false, and that key third-party journeys succeed with zero unknown cross-origin dependencies.

The release gate requires 100% resource inventory owner coverage, zero synthetic-journey blocks, an eligible cohort isolation success rate of at least 99.99%, a fallback success rate of 100%, Popup login/payment success rate no lower than baseline, and zero uncategorized report-only reports. Start with report-only on an isolated compute origin, then enforce at 1%, 5%, and 25%. Rollback removes the enforcing headers and switches back to the single-threaded release, but existing Documents are not reverse-changed by the response configuration; you must prompt or trigger a new navigation. Keep the CORS/CORP you've already fixed; do not re-open anonymous cross-origin access.

Further Reading

Related

Related Content