By header

COOP, COEP & CORP: Cross-Origin Isolation Headers

4 min read

Three related headers harden how your page interacts with other origins. Two of them (Cross-Origin-Opener-Policy + Cross-Origin-Embedder-Policy) together enable cross-origin isolation, which is required for SharedArrayBuffer and high-resolution timers.

The headers

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin

Just want opener isolation? (low risk)

COOP alone is safe and worthwhile on its own:

add_header Cross-Origin-Opener-Policy "same-origin" always;

Full cross-origin isolation (needs testing)

Nginx:

add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;

Apache:

Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Embedder-Policy "require-corp"
Header always set Cross-Origin-Resource-Policy "same-origin"

Caddy:

header {
    Cross-Origin-Opener-Policy "same-origin"
    Cross-Origin-Embedder-Policy "require-corp"
    Cross-Origin-Resource-Policy "same-origin"
}

_headers:

/*
  Cross-Origin-Opener-Policy: same-origin
  Cross-Origin-Embedder-Policy: require-corp
  Cross-Origin-Resource-Policy: same-origin

Verify

curl -sI https://yourdomain.com | grep -i cross-origin
# In the browser console, check: self.crossOriginIsolated  // true when COOP+COEP are correct

Only enable COEP if you need it. require-corp commonly breaks embedded YouTube, third-party analytics, and CDN images that don’t send Cross-Origin-Resource-Policy/CORS. If you don’t use SharedArrayBuffer, ship COOP same-origin alone and skip COEP.

Open the full version (with copy buttons) ↗

← All recipes