Access-Control-Allow-Credentials: cookies across origins
Access-Control-Allow-Credentials: true lets page code read a cross-origin response that was sent with cookies or an Authorization header. The only valid value is true.
At a glance
- Direction
- Response, on both the preflight and the actual response.
- Defined in
- The Fetch standard (WHATWG)
- When absent
- A credentialed response is blocked from page code, even if every other CORS header is correct.
- Only valid value
- true, lowercase. Sending false is the same as omitting the header.
- Disables wildcards in
- Access-Control-Allow-Origin, -Methods, -Headers and -Expose-Headers
- Client must also
- Set credentials to include on fetch, or withCredentials on an XHR.
- Cookies still need
- SameSite=None and Secure to be sent cross-site at all
In detail
Credentials means cookies, TLS client certificates and the Authorization header. By default a cross-origin fetch omits all of them, so the request arrives unauthenticated no matter what the browser holds. Turning credentials on is a decision by both sides: the client asks for them to be sent, and the server acknowledges with this header, or the response is unreadable.
Once credentials are in play, every wildcard in CORS stops being a match. The allow origin header must name one origin exactly, and the methods, headers and exposed headers lists must name their entries. This is the rule behind the common report that a request works until cookies are added and then fails with no other change.
There is a second layer that has nothing to do with CORS. A cookie is only sent on a cross-site request if it was set with SameSite=None and Secure, so a correct CORS configuration in front of a Lax cookie still produces an unauthenticated request. The browser sends nothing and the server sees an anonymous call.
Because the response must be origin specific, it must also carry Vary: Origin. Skipping that with credentials enabled is the most damaging version of the caching mistake, since a shared cache could hand a response prepared for one origin to a page on another.
Examples
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: X-Request-Id
Vary: Originfetch('https://api.example.com/me', { credentials: 'include' })Without this option the browser sends no cookies and the server sees an anonymous request.
Things that catch people out
- A wildcard allow origin with this header set is always rejected. The browser will not fall back to allowing the request.
- The value must be the literal true. There is no false mode, and any other value is treated as the header being absent.
- Getting CORS right does not make the cookie travel. A cookie without SameSite=None and Secure is never sent cross-site.
Try it: HTTP Headers Checker
Check a live URL or paste headers you already have. It grades six security headers from A+ to F and lists every other header the response returned.
HTTP Headers Checker
LOCAL · Browser-OnlyView HTTP response headers for any URL
Enter any website URL to fetch and analyze its HTTP response headers. We'll automatically add https:// if needed.
Why Check Security Headers?
Security headers protect your website against common attacks like XSS, clickjacking, and MIME sniffing. They're set by your web server and cost nothing to implement. Missing security headers are one of the most common findings in security audits.
Related HTTP headers
All http headers →Access-Control-Allow-Origin: who may read this response
How the allow origin header is matched, why a wildcard fails with credentials, why it takes only one origin, and why Vary: Origin is mandatory when you echo.
Set-Cookie: attributes, SameSite and cookie prefixes
Every Set-Cookie attribute explained, why SameSite=None needs Secure, what the __Host- prefix guarantees, and how Max-Age and Expires interact.
Cookie: what the browser sends back
How the Cookie header is formatted, why attributes never come back, how the browser decides which cookies to include, and what the size limits are.
Authorization: credentials on a request
How the Authorization header is structured, how Basic and Bearer differ, why it is dropped across a cross-host redirect, and how it interacts with caching.
Access-Control-Expose-Headers: reading response headers
Which response headers page code can read cross-origin by default, how to expose more, and why a pagination or request id header appears empty without it.
Access-Control-Max-Age: caching the preflight result
How long a browser may reuse a preflight result, the caps Chrome and Firefox apply, what minus one means, and why a doubled request count is normal.
Tools for this
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL