Cross-Origin Policy Bundle Generator Guide: Build COOP, COEP and CORP Together
Security headers are often added one at a time, over months, by different people, for different reasons. One person adds a COOP header after reading about isolation, another adds COEP months later for a feature that needs it, and a third adds CORP when an embed breaks. The result is a header set that may contain contradictions nobody noticed, because no one ever reviewed the three headers as a single decision. The cross-origin policy bundle is the antidote to that drift: COOP, COEP, and CORP chosen together, as one coherent policy, with values that agree about how strict the site intends to be.
The Cross-Origin Policy Bundle Generator tool lets you pick COOP, COEP and CORP values and generates a matching set of response headers. It is a generator, not a deployment tool: it produces the header text for you to review and then apply in your server configuration. That distinction matters, because generated text has no effect until it is served, and a bundle sitting in a generator output is not protecting anything. The generator's value is in consistency. By choosing the three values side by side, you see the whole policy at once, and contradictions become visible before they reach production.
Each header in the bundle guards a different layer. COOP, the Cross-Origin-Opener-Policy, separates the top-level page's browsing context group from cross-origin windows, and its usual values are same-origin and same-origin-allow-popups. COEP, the Cross-Origin-Embedder-Policy, controls which cross-origin resources the page may load, with require-corp as the strict value and credentialless as the more compatible one. CORP, the Cross-Origin-Resource-Policy, works from the other side: it is sent by a resource to declare which origins may load it, with same-origin, same-site, and cross-origin as its values. COOP and COEP are set by the page that wants isolation; CORP is set by the resource that agrees to be embedded. A bundle generator brings the page-side pair together with the resource-side header so the two sides of the same relationship can be reasoned about together.
Consistency between the values is where most bundle mistakes hide. Consider a page that sets COEP to require-corp, which blocks cross-origin resources that do not opt in, while its own resources are served with CORP set to same-origin, which refuses all cross-origin loads. If another site needs to embed those resources, the combination will block it, which may be intended or may be an accident, but it should never be a surprise. Conversely, a page that sets COEP to credentialless while serving its resources with CORP cross-origin is broadly permissive on both sides, which is a coherent choice for a public embeddable widget, but a poor choice for a page handling sensitive data. The bundle view forces that comparison: strict on one side and permissive on the other is a combination that deserves a written reason, not a silent default.
A worked example you can follow
Take a sample bundle for a documentation site that embeds no sensitive content but wants isolation for a feature that needs it. Choose COOP same-origin, COEP require-corp, and CORP same-site for its own resources. Count the headers: 3 in the bundle. Count the strict choices: COOP same-origin is strict, COEP require-corp is strict, and CORP same-site is moderately permissive, allowing same-site embedding while refusing cross-site embedding. That is 2 strict choices out of 3 headers, or about 67 percent strict, with the remaining header deliberately relaxed for same-site embeds such as a help subdomain. The bundle is coherent because each value can be explained in one sentence, and no value contradicts another.
Now test the bundle against the site's real embeds. Suppose the documentation site embeds 12 third-party resources: 8 of them send their own CORP opt-in or are same-origin, and 4 send no opt-in. Under COEP require-corp, those 4 would be blocked, leaving 8 loading, which is 8 divided by 12, or about 67 percent of embeds working. If 2 of the 4 blocked embeds are essential, such as the search widget and the feedback form, the bundle as drafted breaks the page, and the fix is a decision, not a tweak: either get those providers to opt in, switch COEP to credentialless so all 12 load without credentials, or drop the isolation requirement. Under credentialless, all 12 load, but 4 of them, or about 33 percent, load without cookies, which may break a provider that needs a login. Counting the affected embeds before shipping turns a vague worry into a concrete trade-off with numbers attached.
Take a second sample bundle for a public widget that other sites embed. Choose COOP unsafe-none, COEP credentialless, and CORP cross-origin. The count is again 3 headers, but the strict count is 0 out of 3, or 0 percent strict. That is not a mistake if the widget is genuinely public and carries no user data, because a permissive bundle matches a permissive purpose. It would be a mistake for a banking dashboard, where 0 percent strict would be indefensible. The lesson is that there is no universally correct bundle, only a bundle whose strictness matches the sensitivity of what it protects. Write that reasoning down next to the bundle, because the next person to edit it will otherwise judge it by their own assumptions rather than yours.
Mistakes to avoid
The first mistake is generating a bundle and never applying it, then assuming the site is protected because the generator output looked right. Generated text protects nothing until it is served, so the deployment step is part of the job, not an afterthought. The second mistake is choosing values independently and never comparing them, which produces contradictions such as a strict page policy paired with a permissive resource policy. The third mistake is applying a strict bundle without testing real embeds, and discovering the breakage from visitors. The fourth mistake is copying a bundle from an example without adjusting it to the site's own embeds and sensitivity. A bundle is a policy decision, and a policy copied without thought is not a policy at all.
The Cross-Origin Isolation Checker tool verifies the COOP and COEP halves of a bundle together, and the Cross-Origin Resource Policy Checker tool reads the CORP half on its own. For background on placing the bundle in a wider security review, see How to Configure HTTP Security Headers.
Checking the result before you publish it
Treat a generated bundle as a draft to be tested, not a finished policy. Apply it in a staging environment first, load every page type with its real third-party content, and count what breaks: how many embeds blocked, how many popup flows affected, how many features lost. Adjust one value at a time and re-check the bundle after each change, so the effect of each choice stays visible. When the bundle passes staging, confirm the same 3 headers on the live response, and keep the bundle text and its reasoning together in your configuration notes. A bundle that is generated, tested, confirmed live, and documented is a policy the team can maintain; a bundle that exists only as generator output is a plan nobody executed.