Configure Cross-Origin Resource Sharing (CORS) to allow browser-based clients to interact with your Nexus server.
[server.cors]
allow_origins = ["https://app.example.com", "http://localhost:3000"]
allow_methods = ["GET", "POST"]
allow_headers = ["authorization", "content-type", "x-request-id"]
allow_credentials = true
max_age = 3600
allow_private_network = false
expose_headers = ["x-request-id", "x-trace-id"]
allow_origins
: List of allowed origins, a single origin, or"*"
for all originsallow_methods
: HTTP methods to allow (can be array or"*"
)allow_headers
: Headers that clients can send (can be array or"*"
)allow_credentials
: Whether to allow credentials in CORS requests (default:false
)max_age
: How long browsers can cache CORS preflight responses (in seconds)allow_private_network
: Allow requests from private networks (default:false
)expose_headers
: Headers to expose to the client (can be array or"*"
)
For allow_origins
, allow_methods
, allow_headers
, and expose_headers
, you can use:
- An array of specific values:
["value1", "value2"]
- A single value:
"value"
- Wildcard to allow all:
"*"
Allow all origins during development:
[server.cors]
allow_origins = "*"
allow_methods = "*"
allow_headers = "*"
allow_credentials = false
Restrict to specific domains in production:
[server.cors]
allow_origins = [
"https://app.yourdomain.com",
"https://admin.yourdomain.com"
]
allow_methods = ["GET", "POST", "OPTIONS"]
allow_headers = ["authorization", "content-type"]
allow_credentials = true
max_age = 86400 # 24 hours
expose_headers = ["x-request-id"]
Configuration for a typical SPA:
[server.cors]
allow_origins = "https://spa.example.com"
allow_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allow_headers = ["authorization", "content-type", "x-csrf-token"]
allow_credentials = true
max_age = 3600
expose_headers = ["x-total-count", "x-page-number"]
Allow local development servers:
[server.cors]
allow_origins = [
"http://localhost:3000", # Web dev server
"http://localhost:8081", # React Native
"http://10.0.2.2:8000", # Android emulator
"capacitor://localhost", # Capacitor
"ionic://localhost" # Ionic
]
allow_methods = ["GET", "POST", "OPTIONS"]
allow_headers = ["authorization", "content-type"]
allow_credentials = true
allow_private_network = true # For local network access
When allow_credentials = true
:
- Cannot use
"*"
for origins - must specify exact origins - Browser will reject responses if wildcard is used with credentials
- Each origin must be explicitly listed
The allow_private_network
option controls Chrome's Private Network Access:
[server.cors]
allow_private_network = true # Allow requests from private IPs
Use this when:
- Serving requests to local network clients
- Development with local IP addresses
- Internal corporate networks
Browsers send preflight OPTIONS requests for:
- Custom headers
- Non-simple methods (PUT, DELETE, etc.)
- Requests with credentials
Ensure OPTIONS is included in allow_methods
:
[server.cors]
allow_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
Symptoms: OPTIONS request fails with CORS error
Solution:
[server.cors]
allow_methods = ["OPTIONS", "GET", "POST"] # Include OPTIONS
allow_headers = ["authorization", "content-type"] # Include all headers used
Symptoms: Cookies/auth headers not sent
Solution:
[server.cors]
allow_origins = ["https://specific-origin.com"] # Specific origin, not "*"
allow_credentials = true
Symptoms: Can't read response headers in JavaScript
Solution:
[server.cors]
expose_headers = ["x-custom-header", "x-another-header"]
Symptoms: Old CORS settings persist
Solution:
[server.cors]
max_age = 0 # Disable preflight caching during debugging
fetch('http://localhost:8000/llm/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
},
credentials: 'include', // Send cookies if allow_credentials = true
body: JSON.stringify({
model: 'openai/gpt-4',
messages: [{ role: 'user', content: 'Hello' }]
})
});
import axios from 'axios';
const client = axios.create({
baseURL: 'http://localhost:8000',
withCredentials: true, // If allow_credentials = true
headers: {
'Content-Type': 'application/json'
}
});
- Be Specific in Production: Never use
"*"
for origins in production - Minimize Exposed Headers: Only expose necessary headers
- Use HTTPS: Always use HTTPS origins in production
- Validate Origins: Keep origin list up-to-date
- Monitor CORS Errors: Log and monitor CORS failures
- Test Thoroughly: Test with actual browsers, not just tools
- Document Origins: Maintain documentation of allowed origins
- Enable CSRF Protection for additional security
- Configure OAuth2 for authentication
- Set up Rate Limiting to prevent abuse