Skip to main content
This guide covers setting up a reverse proxy using Nginx, but the same principles apply to Apache, Caddy, HAProxy, or any other reverse proxy solution.

Prerequisites

  • A server with a reverse proxy (Nginx, Apache, Caddy, etc.)
  • SSL/TLS certificate for your domain
  • Ability to modify proxy configuration

Nginx Configuration

Add the following to your Nginx configuration (typically in /etc/nginx/sites-available/yourdomain.conf):
# Analytics proxy configuration
location /analytics {
    # Forward to Composite API with path intact
    proxy_pass https://prod.alb.us.api.composite.com;

    # SSL configuration for upstream
    proxy_ssl_server_name on;
    proxy_ssl_protocols TLSv1.2 TLSv1.3;

    # Required headers
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host prod.alb.us.api.composite.com;

    # Timeouts
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;

    # Disable buffering for real-time data
    proxy_buffering off;

    # CORS headers for browser extensions
    add_header Access-Control-Allow-Origin * always;
    add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header Access-Control-Allow-Headers 'Content-Type, Authorization' always;

    # Handle preflight requests
    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
        add_header Access-Control-Allow-Headers 'Content-Type, Authorization';
        add_header Content-Length 0;
        add_header Content-Type text/plain;
        return 204;
    }
}
After updating the configuration:
# Test configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

Apache Configuration

For Apache with mod_proxy enabled:
<Location /analytics>
    # Forward to Composite API with path intact
    ProxyPass https://prod.alb.us.api.composite.com/analytics
    ProxyPassReverse https://prod.alb.us.api.composite.com/analytics

    # Required headers
    RequestHeader set X-Forwarded-Proto "https"
    ProxyPreserveHost Off

    # CORS headers
    Header always set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
    Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
</Location>
Enable required modules and reload:
sudo a2enmod proxy proxy_http headers
sudo systemctl reload apache2

Caddy Configuration

Caddy provides a simpler configuration:
yourdomain.com {
    # Your existing site configuration
    # ...

    # Analytics proxy (path preserved)
    handle /analytics/* {
        reverse_proxy https://prod.alb.us.api.composite.com {
            header_up X-Forwarded-For {remote_host}
            header_up X-Forwarded-Proto {scheme}
            header_up X-Real-IP {remote_host}
            header_up Host prod.alb.us.api.composite.com
        }

        header Access-Control-Allow-Origin *
        header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
        header Access-Control-Allow-Headers "Content-Type, Authorization"
    }
}

SDK Configuration

Once your proxy is running, configure the SDK:
await composite.init({
  apiKey: 'pk_your_api_key',
  apiHost: 'https://yourdomain.com/analytics',
  transport: 'chrome-extension'
});
Update your manifest:
"host_permissions": [
  "https://yourdomain.com/*"
]

Required Headers

Your proxy must set these headers on requests to Composite:
HeaderValuePurpose
X-Forwarded-ForClient IPTrack original visitor IP
X-Forwarded-ProtohttpsMaintain protocol information
X-Real-IPClient IPBackup IP header
Hostprod.alb.us.api.composite.comTarget host (do not forward client host)
Do not forward the client’s Host header. This causes routing failures. Always set Host explicitly to prod.alb.us.api.composite.com.

Troubleshooting

The proxy cannot reach Composite’s API:
  1. Verify DNS resolution: nslookup prod.alb.us.api.composite.com
  2. Test connectivity: curl -I https://prod.alb.us.api.composite.com
  3. Check your server’s outbound firewall rules
  4. Ensure SSL/TLS is properly configured for the upstream connection
Check your proxy configuration:
  1. Verify the location/path pattern matches /analytics
  2. Ensure the upstream URL is https://prod.alb.us.api.composite.com
  3. Test with: curl https://yourdomain.com/analytics/health
  4. Check proxy logs for the actual upstream URL being requested
The response is missing CORS headers:
  1. Ensure CORS headers are added to responses (not just requests)
  2. Check that OPTIONS preflight requests return 204 with CORS headers
  3. Verify Access-Control-Allow-Origin is set to * or your extension’s origin
For upstream connections:
  1. Ensure your proxy trusts the CA that signed Composite’s certificate
  2. Enable SNI (Server Name Indication) in your proxy config
  3. For Nginx, verify proxy_ssl_server_name on; is set

Security Considerations

  • Rate limiting: Consider adding rate limits to prevent abuse
  • Logging: Log requests for debugging but avoid logging request bodies (may contain PII)
  • Access control: If your extension is internal, consider IP allowlisting
Example rate limiting in Nginx:
limit_req_zone $binary_remote_addr zone=analytics:10m rate=100r/s;

location /analytics/ {
    limit_req zone=analytics burst=200 nodelay;
    # ... rest of configuration
}

What’s Next?