CORS Policy Builder
Configure cross-origin response headers and server snippets entirely in your browser
Examples
Single-origin API with auth and preflight caching
Origins: https://app.example.com
Methods: GET, POST, OPTIONS
Request headers: Content-Type, Authorization
Expose headers: (empty)
Credentials: on
Max-Age: 86400Headers:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Expose-Headers:
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400Even with credentials on, a single explicit origin is safe to echo back. The empty Access-Control-Expose-Headers line is intentional — the browser will not allow any extra response headers to be read by JS.
Multi-tenant API with credentials and three origins
Origins:
https://a.example.com
https://b.example.com
https://c.example.com
Methods: GET, POST, PUT, DELETE, OPTIONS
Request headers: Content-Type, Authorization, X-Request-Id
Expose headers: X-Request-Id, X-RateLimit-Remaining
Credentials: on
Max-Age: 3600Headers:
Access-Control-Allow-Origin: <request-origin>
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Request-Id
Access-Control-Expose-Headers: X-Request-Id, X-RateLimit-Remaining
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
Nginx:
add_header Access-Control-Allow-Origin "$http_origin" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Request-Id" always;
add_header Access-Control-Expose-Headers "X-Request-Id, X-RateLimit-Remaining" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Max-Age "3600" always;Multiple origins trigger the dynamic mode. The header placeholder (<request-origin>) and the Nginx directive ($http_origin) must be validated against a server-side allowlist; do not echo the Origin header verbatim.
Public read-only API with no credentials
Origins: *
Methods: GET, OPTIONS
Request headers: Content-Type
Expose headers: (empty)
Credentials: off
Max-Age: 86400Headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Expose-Headers:
Access-Control-Allow-Credentials: false
Access-Control-Max-Age: 86400
fetch example:
fetch("https://example.com/api/resource", {
method: "GET",
mode: "cors",
credentials: "omit",
headers: {
"Content-Type": "<value>"
},
})
.then((response) => response.json())
.then((data) => console.log(data))With credentials off, * is a valid Access-Control-Allow-Origin value. The fetch example uses credentials: 'omit' to match the chosen policy.
About this tool
CORS (Cross-Origin Resource Sharing) is the browser security protocol that decides whether code running on one origin may read a response from another. A working policy coordinates the allowed origin, methods, request headers, exposed response headers, credentials, and preflight cache duration; a mismatch in any one of them can block a valid frontend or expose an API more broadly than intended.
CORS Policy Builder turns those choices into three practical outputs: raw Access-Control response headers, Nginx add_header directives, and a JavaScript fetch example. Multiple origins require dynamic server logic because Access-Control-Allow-Origin accepts only one origin or a wildcard. For credentialed requests, the server must validate the incoming Origin against an allowlist before echoing it and cannot return *.
Generation is fully client-side, so origin allowlists and API header names never leave your browser. The output is a configuration aid: apply it to the route that handles both the actual request and its OPTIONS preflight, then verify the response in browser developer tools.
How to use
Set origins and methods
Enter one allowed origin per line and toggle the HTTP methods your cross-origin clients may use.
Configure header access
List the request headers accepted by your server and the response headers browser code may read.
Choose credentials and caching
Enable credentials only for trusted explicit origins, then set how long browsers may cache a successful preflight.
Copy the policy
Use the Headers, Nginx, or fetch example tab and copy the generated format you need.
Use cases
Configuring a single-origin API
Document the exact Access-Control headers your frontend needs and ship the matching Nginx or Express snippet so the server block and the frontend code stay in sync.
Hardening a multi-tenant API
Multiple origins with credentials need a dynamic origin echo backed by a server-side allowlist. Use the generated $http_origin placeholder together with a custom validator in Nginx or your application layer.
Documenting a public read-only endpoint
A CDN-backed, public, read-only API can ship Access-Control-Allow-Origin: * with no credentials. The Headers tab gives you a copy-paste block for the spec.
Bootstrapping a new frontend client
Use the fetch example to seed a typed API client — the method, mode, credentials, and header names are filled in from the policy so the first request cannot be blocked by a missing preflight response.
Generated CORS formats
| Format | Use |
|---|---|
| Headers | Raw Access-Control response-header lines for documentation or middleware |
| Nginx | add_header directives for an Nginx server or location block |
| fetch example | Browser request snippet using mode: cors and the chosen credential behavior |
Generated locally — no origin or API configuration is uploaded.
Common mistakes
Mistake:Returning Access-Control-Allow-Origin: * together with Access-Control-Allow-Credentials: true.
Fix:The browser blocks the response. With credentials enabled, switch to a single explicit origin or echo the request Origin after validating it against a server-side allowlist.
Mistake:Listing every origin in Access-Control-Allow-Origin as a comma-separated value.
Fix:The header takes a single origin or *. Echo the request Origin header from a server-side allowlist when you need multiple origins with credentials.
Mistake:Forgetting to handle the OPTIONS preflight on the same route.
Fix:Preflight requests are issued against the same URL as the real request. Apply the CORS headers to both the real route and its OPTIONS handler, or use a middleware that short-circuits OPTIONS to 204.
Mistake:Setting Access-Control-Max-Age too short or too long.
Fix:Pick a value that matches how often your policy changes. 600 (10 min) is a safe default while iterating; 86400 (24 h) is fine for a stable policy. Anything past 86400 is clamped by most browsers.
Mistake:Trusting the generated example to be a complete CORS implementation.
Fix:The builder is a documentation aid. You still need to validate the dynamic origin server-side and to apply the policy to every route that the browser may preflight.
Frequently asked questions
Related guides
References & standards
Related tools
AES Encryption
Encrypt and decrypt text with AES-GCM and a passphrase, fully in your browser. Uses PBKDF2 key derivation and the Web Crypto API — your data and keys never leave your device.
Basic Auth Generator
Generate an HTTP Basic Authentication header from a username and password. Produces the Authorization header and ready-to-use curl and fetch snippets. Runs fully client-side.
Bcrypt Generator & Verifier
Hash passwords with bcrypt and verify hashes — choose your cost factor (rounds 4–15), get a secure hash instantly, and check whether a password matches a hash. Runs entirely in your browser.
BIP39 Mnemonic Generator
Generate and validate BIP39 seed phrases locally for testing
Checksum Calculator
Compute file checksums (SHA-1, SHA-256, SHA-384, SHA-512) in your browser with the Web Crypto API
Client-Side File Encryptor
Encrypt any file with AES-256-GCM and PBKDF2 directly in your browser — no uploads, no accounts, wrong passwords fail loudly.