CORS and TLS
Examples for configuring CORS and downstream TLS
This page provides practical examples of configuring CORS policies and TLS for your APIs.
Cross-Origin Resource Sharing (CORS)
Enable CORS for browser-based applications:
openapi: 3.0.3
info:
title: CORS-Enabled API
paths:
/test:
get:
responses:
'200':
description: OK
servers:
- url: https://backend.example.com/api
x-proxyconf:
cluster: demo
url: http://localhost:8080/cors
cors:
access-control-allow-origins:
- http://*.foo.com
access-control-allow-methods:
- GET
- POST
access-control-max-age: 600
security:
auth:
downstream:
type: header
name: my-api-key
clients:
testUser:
- 9a618248b64db62d15b300a07b00580b
Testing CORS Preflight
CORS preflight requests (OPTIONS) are unauthenticated:
# Preflight request - returns 200 with CORS headers (no auth required)
curl -X OPTIONS http://localhost:8080/cors/test \
-H "Origin: http://app.foo.com" \
-H "Access-Control-Request-Method: GET"
# Response headers:
# Access-Control-Allow-Origin: http://app.foo.com
# Access-Control-Allow-Methods: GET,POST
# Access-Control-Max-Age: 600
Testing Actual Requests
The actual request still requires authentication:
# Without auth - returns 403
curl http://localhost:8080/cors/test
# Response: RBAC: access denied
# With auth - returns 200
curl http://localhost:8080/cors/test -H "my-api-key: supersecret"
Downstream TLS
Downstream TLS is implicitly configured by using an https URL in x-proxyconf.url. The server certificate is automatically selected by matching the hostname with certificates available in ProxyConf.
openapi: 3.0.3
info:
title: TLS-Enabled API
paths:
/test:
get:
responses:
'200':
content:
application/json:
schema:
type: object
description: OK
post:
requestBody:
content:
application/json: {}
required: true
responses:
'200':
content:
application/json: {}
description: OK
servers:
- url: https://backend.example.com/api
x-proxyconf:
cluster: demo
url: https://localhost:8443/downstream-tls
listener:
address: 127.0.0.1
port: 8443
security:
auth:
downstream: disabled
Certificate Selection
ProxyConf automatically selects the server certificate by matching the hostname in x-proxyconf.url with:
- TLS Common Name (CN)
- TLS Subject Alternative Names (SAN)
Certificates are loaded from the path specified in PROXYCONF_SERVER_DOWNSTREAM_TLS_PATH.
Testing TLS
# GET request over TLS
curl https://localhost:8443/downstream-tls/test --cacert ca.crt
# POST with valid content type
curl https://localhost:8443/downstream-tls/test \
--cacert ca.crt \
-H "Content-Type: application/json" \
-d '{"hello": "world"}'
# POST with invalid content type - returns 404 (no matching route)
curl https://localhost:8443/downstream-tls/test \
--cacert ca.crt \
-H "Content-Type: text/plain" \
-d "hello world"
Full Example: CORS + TLS + Authentication
Combining all security features:
openapi: 3.0.3
info:
title: Secure API
paths:
/data:
get:
responses:
'200':
description: OK
post:
requestBody:
content:
application/json: {}
responses:
'201':
description: Created
servers:
- url: https://backend.example.com/api
x-proxyconf:
cluster: production
url: https://api.example.com:443/v1
listener:
address: 0.0.0.0
port: 443
cors:
access-control-allow-origins:
- https://app.example.com
- https://admin.example.com
access-control-allow-methods:
- GET
- POST
- PUT
- DELETE
access-control-allow-headers:
- Content-Type
- Authorization
- X-API-Key
access-control-allow-credentials: true
access-control-max-age: 3600
security:
allowed-source-ips:
- 10.0.0.0/8
- 192.168.0.0/16
auth:
downstream:
type: jwt
provider-config:
issuer: https://auth.example.com
audiences:
- api.example.com
remote_jwks:
http_uri:
uri: https://auth.example.com/.well-known/jwks.json
timeout: 1s
cache_duration:
seconds: 600
This configuration provides:
- TLS encryption for all traffic
- CORS support for specific web applications
- JWT authentication with caching
- IP filtering for internal networks only