CORS (Cross-Origin Resource Sharing)
Bulwark handles CORS automatically for SDK users. If you use a publishable key, CORS works out of the box — no domains to configure.
How it works
CORS headers are included on responses that match one of these conditions:
- Publishable key header — requests with
X-Bulwark-Publishable-Key(the SDK sends this automatically) - Public auth endpoints —
/api/v1/auth/*,/oauth2/*,/hosted/*,/.well-known/* - Tenant header — requests with a valid
X-Bulwark-TenantUUID - Global origin allowlist — origins listed in
BULWARK_CORS_ORIGINS - OPTIONS preflight — always allowed
This means:
- SDK users — CORS works automatically via the publishable key
- Auth endpoints — login, register, identify, SSO all work cross-origin
- localhost — works during development
- No "add this domain" configuration when using the SDK
Requests without any of the above identifiers do not receive CORS headers. This prevents credential theft via malicious cross-origin requests.
Preflight requests
Bulwark handles OPTIONS preflight requests automatically with a 204 No Content response, full CORS headers, and a 24-hour cache (Access-Control-Max-Age: 86400), minimizing preflight overhead.
Response headers
Matching responses include:
| Header | Value |
|--------|-------|
| Access-Control-Allow-Origin | The requesting origin (echoed back) |
| Access-Control-Allow-Credentials | true |
| Access-Control-Allow-Headers | Content-Type, Authorization, X-Bulwark-Tenant, X-Bulwark-App-Id, X-Bulwark-Publishable-Key |
| Access-Control-Allow-Methods | GET, POST, PATCH, PUT, DELETE, OPTIONS |
| Access-Control-Max-Age | 86400 (24 hours) |
| Vary | Origin (for correct caching) |
SDK integration
All Bulwark SDKs work automatically. Just initialize the provider:
<BulwarkProvider publishableKey="pk_live_...">
<App />
</BulwarkProvider>
No CORS configuration needed. The SDK sends the publishable key as a header on every request.
Server-side requests
Server-side requests (Node.js, Go, Python) are not subject to CORS — browsers enforce CORS, servers don't. Your backend API calls to Bulwark work without any configuration.
Self-hosted deployments
For self-hosted Bulwark instances, you can restrict CORS to specific origins by setting the BULWARK_CORS_ORIGINS environment variable:
BULWARK_CORS_ORIGINS=https://app.example.com,https://admin.example.com
When set, only these origins (plus publishable key and auth endpoints) receive CORS headers. Set to * to allow all origins without credentials.