# Cross-Origin-Opener-Policy Header — Values & Examples

> Isolates your page from cross-origin windows that open it or that it opens.

When one page opens another with `window.open`, the two normally keep references to each other. COOP set to `same-origin` cuts that link for cross-origin windows, which protects against attacks that probe or navigate your window. Together with Cross-Origin-Embedder-Policy it enables cross-origin isolation, which unlocks `SharedArrayBuffer` and high-resolution timers.

- Type: Response header
- Category: Security
- Defined in: [HTML Standard — Cross-origin opener policies](https://html.spec.whatwg.org/multipage/browsers.html#cross-origin-opener-policies)

## Syntax

```http
Cross-Origin-Opener-Policy: unsafe-none | same-origin-allow-popups | same-origin
```

## Values

| Value | Meaning |
|---|---|
| `unsafe-none` | the default: no isolation |
| `same-origin-allow-popups` | isolate from cross-origin openers, but keep references to popups this page opens |
| `same-origin` | isolate from all cross-origin windows |

## Examples

```http
Cross-Origin-Opener-Policy: same-origin
```

full isolation from cross-origin windows

```http
Cross-Origin-Opener-Policy: same-origin-allow-popups
```

keeps sign-in and payment popups working

## Good to know

- `same-origin` breaks popups that report back through `window.opener`, such as many OAuth and payment flows — use `same-origin-allow-popups` on the page that opens them.
- `crossOriginIsolated` requires both COOP `same-origin` and `Cross-Origin-Embedder-Policy: require-corp` (or `credentialless`).

## How to set Cross-Origin-Opener-Policy

### Express

```
res.set("Cross-Origin-Opener-Policy", "same-origin");
```

### Next.js (next.config.js)

```
module.exports = {
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [{ key: "Cross-Origin-Opener-Policy", value: "same-origin" }],
      },
    ];
  },
};
```

### nginx

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

### Apache (.htaccess)

```
Header always set Cross-Origin-Opener-Policy "same-origin"
```

## Check it

Fetch only the response headers and filter for Cross-Origin-Opener-Policy. In the browser, it's under Response Headers in DevTools → Network.

```sh
curl -sI https://example.com/ | grep -i '^cross-origin-opener-policy:'
```

## FAQ

### Why did my login popup stop working?

With COOP same-origin, the popup loses its window.opener reference and can't pass the result back. Use same-origin-allow-popups on the page that opens it.

## Related headers

- [Content-Security-Policy](https://www.devkult.com/headers/content-security-policy.md): Restricts where a page may load scripts, styles, images and frames from — the main defence against cross-site scripting.
- [Permissions-Policy](https://www.devkult.com/headers/permissions-policy.md): Turns browser features such as the camera, microphone and geolocation on or off for a page and its iframes.
- [X-Frame-Options](https://www.devkult.com/headers/x-frame-options.md): Controls whether the page may be shown inside a frame, protecting against clickjacking.

## Further reading

- [Security headers checklist](https://www.devkult.com/blog/security-headers-checklist.md)
- [Security headers generator](https://www.devkult.com/tools/security/security-headers-generator.md)

Open the interactive page: https://www.devkult.com/headers/cross-origin-opener-policy