The Access-Control-Allow-Origin (ACAO) response header specifies which origin or origins are allowed to access a resource via browser JavaScript.

Syntax options

Access-Control-Allow-Origin: https://dashboard.example.test
Vary: Origin

2. Wildcard (Public data only)

Access-Control-Allow-Origin: *

The credentials rule: Wildcards forbidden

When a request includes credentials (credentials: 'include', cookies, or Authorization headers):

  • The server MUST NOT return Access-Control-Allow-Origin: *.
  • The server MUST return the exact requesting origin (e.g., Access-Control-Allow-Origin: https://app.example.test) along with Access-Control-Allow-Credentials: true.

For a dedicated analysis of this limitation, see our guide on Wildcard Origin with Credentials.

Multi-origin validation pattern

HTTP does not allow a comma-separated list of multiple origins in Access-Control-Allow-Origin. To support multiple origins:

  1. Read the incoming Origin header.
  2. Check if it matches an allowed whitelist.
  3. Echo the matched origin in Access-Control-Allow-Origin.
  4. Always append Vary: Origin to prevent CDN cache poisoning.

How to test with curl

curl -i https://api.example.test/v1/profile \
  -H "Origin: https://dashboard.example.test"

Key takeaway

Access-Control-Allow-Origin is the cornerstone of CORS. Use * only for public, unauthenticated APIs. For authenticated requests, validate the incoming origin against an explicit whitelist and append Vary: Origin.