A Cloudflare Worker-based proxy middleware that forwards API requests to backend services while preserving headers, query parameters, and HTTP methods.
- Standardized Response Format: All responses follow a consistent format with success status, message, timestamp, and data
- Firebase Authentication: Optional Firebase token-based authentication with configurable whitelisting
- Request Forwarding: Proxies all
/api/*
routes to the configured API service - Header Preservation: Maintains original request headers while filtering out internal Cloudflare headers
- Query Parameter Support: Preserves all query parameters in forwarded requests
- HTTP Method Support: Supports all HTTP methods (GET, POST, PUT, DELETE, etc.)
- Request Body Forwarding: Properly handles request bodies for non-GET/HEAD requests
- Observability: Logs response status codes and request duration for monitoring
- Error Handling: Graceful error handling with proper HTTP status codes
- Health Check: Built-in health check endpoint at
/health
All proxied API responses follow a standardized format. The /health
endpoint maintains its original simple format.
{
success: boolean, // true for successful operations, false for errors
message: string | null, // descriptive message, null if no specific message
timestamp: string, // ISO 8601 timestamp
data: any // response payload or null for errors
}
Successful Proxied Response:
{
"success": true,
"message": null,
"timestamp": "2025-07-11T10:30:00.000Z",
"data": {
"users": [{ "id": 1, "name": "John Doe" }]
}
}
Error Response from Proxy:
{
"success": false,
"message": "API returned 404",
"timestamp": "2025-07-11T10:30:00.000Z",
"data": null
}
Health Check Response:
{
"status": "OK",
"timestamp": "2025-07-11T10:30:00.000Z"
}
The basic configuration should be defined in your wrangler.jsonc
:
{
"vars": {
"API_SERVICE_URL": "https://api.example.com",
"API_KEY": "your-api-key-here",
"ALLOWED_ORIGIN": "https://yourdomain.com"
}
}
For production deployments, override the sensitive values using Cloudflare Workers secrets. Check SECRETS_SETUP.md for detailed instructions.
- Development: Uses values from
wrangler.jsonc
vars section - Production: Secrets override the vars with the same name
- Fallback: If secrets aren't set, it falls back to the vars values
- API_SERVICE_URL: The base URL of your target API service
- API_KEY: The API key that will be sent as
X-API-KEY
header to authenticate requests to the target API - ALLOWED_ORIGIN: The allowed CORS origin
- FIREBASE_PROJECT_ID: Your Firebase project ID
- FIREBASE_PRIVATE_KEY: Your Firebase service account private key (with newlines preserved)
- FIREBASE_CLIENT_EMAIL: Your Firebase service account client email
- AUTH_REQUIRED: Set to "false" to disable authentication (default: "true" when Firebase config is present)
The following paths are automatically whitelisted and don't require authentication:
/health
/api/health
/api/public
Security Note: Use placeholder values in
wrangler.jsonc
and set actual production values as secrets. Secrets always take precedence over environment variables.
- GET
/health
- Returns service status and timestamp
- ALL
/api/*
- Forwards requests to the configured API service- Strips
/api
prefix from the forwarded URL - Preserves all query parameters
- Maintains request headers (except internal Cloudflare headers)
- Adds
X-Forwarded-*
headers for transparency - Returns
X-Proxied-By
header in responses - Response Wrapping: JSON responses are automatically wrapped in the standard format
- Format Detection: If the target API already returns standard format, it passes through unchanged
- Strips
# Health check
curl https://your-proxy.workers.dev/health
# Proxy API requests without authentication (if path is whitelisted)
curl https://your-proxy.workers.dev/api/public/status
# Proxy API requests with Firebase authentication
curl https://your-proxy.workers.dev/api/users?limit=10 \
-H "Authorization: Bearer <firebase-id-token>"
# POST request with authentication
curl -X POST https://your-proxy.workers.dev/api/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <firebase-id-token>" \
-d '{"name": "John", "email": "[email protected]"}'
- Client obtains Firebase ID token by authenticating with Firebase Auth
- Client includes token in Authorization header as
Bearer <token>
- Proxy validates token against Firebase before forwarding request
- Whitelisted paths bypass authentication automatically
# Install dependencies
yarn install
# Start development server
yarn dev
# Deploy to Cloudflare Workers
yarn deploy
- Preserved: All application headers (Authorization, Content-Type, etc.)
- Filtered Out: Internal Cloudflare headers (cf-ray, cf-connecting-ip, etc.)
- Added: X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host, X-API-KEY (from environment)
- Preserved: All response headers from the target API
- Filtered Out: Connection-related headers (transfer-encoding, connection, etc.)
- Added: X-Proxied-By header for identification
- 401: Authentication failed (invalid or missing Firebase token)
- 500: Service configuration errors (missing API_SERVICE_URL, API_KEY, or Firebase config)
- 502: Proxy request failures (network errors, invalid responses)
- 404: Non-API routes (only
/api/*
and/health
are supported)
Missing Authorization Header:
{
"success": false,
"message": "Authorization header with Bearer token is required",
"timestamp": "2025-07-12T10:30:00.000Z",
"data": null
}
Invalid Firebase Token:
{
"success": false,
"message": "Invalid or expired authentication token",
"timestamp": "2025-07-12T10:30:00.000Z",
"data": null
}
The proxy logs all requests in the format:
[PROXY] METHOD /api/path -> STATUS_CODE (DURATIONms)
For errors:
[PROXY ERROR] METHOD /api/path: Error details