How to Configure CORS Origins for Production Reverse Proxy in Open Notebook

Set the CORS_ORIGINS environment variable to a comma-separated list of trusted domains before starting the Open Notebook API, and ensure your reverse proxy forwards CORS headers on error responses.

Open Notebook is a FastAPI-based application that relies on environment variables to control cross-origin resource sharing (CORS) behavior. Properly configuring CORS origins is essential when deploying behind a production reverse proxy to prevent browser security errors while maintaining strict access control.

How CORS Origins Are Parsed in Open Notebook

Environment Variable Handling

In api/main.py, the application reads allowed origins from the CORS_ORIGINS environment variable (lines 54-66). If this variable is unset, the system defaults to a permissive wildcard (*), which explicitly logs a warning that unrestricted access is enabled.

The Parsing Logic

The helper function _parse_cors_origins processes the raw string value by splitting on commas and trimming whitespace (lines 54-60). This converts a comma-separated list into a Python list of origin strings suitable for FastAPI's middleware.

def _parse_cors_origins(raw: str) -> list[str]:
    """Parse CORS_ORIGINS env value into a list of origins."""
    value = raw.strip()
    if value == "*":
        return ["*"]
    return [origin.strip() for origin in value.split(",") if origin.strip()]

Middleware Registration Order

The CORSMiddleware is added to the FastAPI application instance using the parsed origins list. According to the source code in api/main.py (lines 37-44), the middleware is registered last in the stack so it processes requests first, with credentials, methods, and headers all permitted.

app.add_middleware(
    CORSMiddleware,
    allow_origins=CORS_ALLOWED_ORIGINS,   # Parsed from CORS_ORIGINS

    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Configuring CORS_ORIGINS for Production Deployment

To restrict cross-origin access to specific domains when running Open Notebook behind nginx, Traefik, or another reverse proxy:

  1. Define the environment variable in your .env file or deployment configuration.
  2. Set the value to a comma-separated list of trusted origins: https://notebook.example.com,https://app.example.com.
  3. Restart the API service, as the origin list is parsed once at module load time.

# .env

CORS_ORIGINS=https://notebook.example.com,https://app.example.com

Reverse Proxy Configuration for CORS Error Responses

When Open Notebook runs behind a reverse proxy, the proxy may return HTTP 413 (Payload Too Large) or other errors before the request reaches FastAPI. In these cases, browsers block the response body if CORS headers are missing.

Configure your reverse proxy to add Access-Control-Allow-Origin headers to error responses. The following nginx configuration intercepts 413 errors and injects the necessary headers, as referenced in api/main.py (lines 255-257):

server {
    listen 80;
    server_name notebook.example.com;

    location / {
        proxy_pass http://localhost:5055;
        proxy_set_header Origin $http_origin;
        proxy_intercept_errors on;
        error_page 413 = @cors_error;
    }

    location @cors_error {
        add_header Access-Control-Allow-Origin $http_origin always;
        add_header Access-Control-Allow-Credentials true always;
        add_header Access-Control-Allow-Methods * always;
        add_header Access-Control-Allow-Headers * always;
        return 413;
    }
}

Summary

  • Open Notebook reads CORS origins from the CORS_ORIGINS environment variable, falling back to wildcard (*) if unset.
  • The _parse_cors_origins function in api/main.py handles comma-separated domain lists by trimming whitespace and splitting on commas.
  • The CORSMiddleware is registered last in the FastAPI app to ensure it processes requests before other middleware.
  • Production reverse proxies must forward CORS headers on error responses (like HTTP 413) to prevent browsers from blocking error details.

Frequently Asked Questions

What happens if I don't set CORS_ORIGINS?

If the CORS_ORIGINS environment variable is not defined, Open Notebook defaults to allowing all origins (*). This configuration is explicitly logged as a warning in api/main.py (lines 54-66). While this works for local development, it creates security vulnerabilities in production environments.

Can I use wildcards in the CORS_ORIGINS list?

Yes. Setting CORS_ORIGINS=* configures the middleware to accept requests from any origin. However, when credentials are enabled (as they are by default in Open Notebook), modern browsers reject wildcard origins for authenticated requests, making explicit domain configuration necessary for production use.

Why does my browser still block requests when the proxy returns a 413 error?

Reverse proxies like nginx often return HTTP 413 (Payload Too Large) before the request reaches FastAPI. Since the error response originates from the proxy rather than Open Notebook, it lacks CORS headers. You must configure proxy_intercept_errors and an error handler in nginx to inject Access-Control-Allow-Origin headers, as documented in the source code comments at api/main.py lines 255-257.

Do I need to restart the API after changing CORS_ORIGINS?

Yes. The CORS origin list is parsed from the environment variable once when the module loads at startup. Any changes to CORS_ORIGINS require a full restart of the Open Notebook API service to take effect.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →