How Open Notebook's CORS Middleware Adapts to Production and Development Environments

Open Notebook's FastAPI application dynamically configures Cross-Origin Resource Sharing (CORS) by checking the CORS_ORIGINS environment variable, automatically defaulting to a permissive wildcard (*) for local development while enforcing strict origin restrictions in production when specific domains are configured.

The lfnovo/open-notebook repository implements an intelligent CORS middleware configuration that seamlessly transitions between development and deployment environments. By leveraging environment variable detection in api/main.py, the application eliminates manual code changes when moving from local testing to production servers. This approach ensures developers can immediately run frontend and backend on separate ports during development while maintaining security best practices in live deployments.

Parsing the CORS_ORIGINS Environment Variable

At module load time, the application parses the CORS_ORIGINS environment variable using the helper function _parse_cors_origins defined in api/main.py. This function converts a comma-separated string into a list of allowed origins, defaulting to a wildcard ("*") when the variable is absent.

The implementation tracks whether the default was applied using the CORS_IS_DEFAULT_WILDCARD flag:


# api/main.py (lines 54-66)

def _parse_cors_origins(raw: str) -> list[str]:
    """Parse CORS_ORIGINS env value into a list of origins."""
    ...

_cors_origins_raw = os.getenv("CORS_ORIGINS")
CORS_ALLOWED_ORIGINS = _parse_cors_origins(_cors_origins_raw or "*")
CORS_IS_DEFAULT_WILDCARD = _cors_origins_raw is None

When _cors_origins_raw is None, the CORS_IS_DEFAULT_WILDCARD boolean evaluates to True, signaling that the application is running in development mode without explicit origin restrictions.

Development Mode: Permissive Wildcard Configuration

When CORS_ORIGINS is not set, the application logs a startup warning to inform developers that the API accepts cross-origin requests from any origin. This configuration supports common local development workflows where the frontend runs on http://localhost:3000 and the API on http://localhost:5055.

The startup logic in api/main.py (lines 212-221) handles this detection:

if CORS_IS_DEFAULT_WILDCARD:
    logger.warning(
        "CORS_ORIGINS is not set — API accepts cross-origin requests from any "
        "origin (default: '*'). For production deployments, set CORS_ORIGINS to "
        "your frontend origin(s), e.g. CORS_ORIGINS=https://notebook.example.com"
    )
else:
    logger.info(f"CORS allowed origins: {CORS_ALLOWED_ORIGINS}")

This warning ensures developers are aware of the permissive configuration before deploying to production environments.

Production Mode: Strict Origin Validation

Setting the CORS_ORIGINS environment variable triggers production mode, where the middleware restricts cross-origin requests to explicitly declared domains. Multiple origins are supported via comma-separated values.

In api/main.py (lines 237-244), the FastAPI CORSMiddleware is instantiated with the parsed origin list:

app.add_middleware(
    CORSMiddleware,
    allow_origins=CORS_ALLOWED_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Configuration example for production:


# .env (production)

CORS_ORIGINS=https://app.example.com,https://admin.example.com
FASTAPI_PORT=5055

When the server starts with this configuration, it logs the specific allowed origins instead of the wildcard warning:


2024-07-04 12:00:00.000 | INFO | CORS allowed origins: ['https://app.example.com', 'https://admin.example.com']

Error Handling with CORS Compliance

The application includes a custom exception handler that augments every error response with appropriate CORS headers. This ensures that even failed requests respect the same-origin policy, preventing browsers from blocking error details due to missing CORS headers on 4xx or 5xx responses.

This handler is implemented in api/main.py (lines 247-263) and operates independently of the middleware to ensure consistent header application across all response paths.

Summary

Open Notebook's CORS middleware adapts to different environments through the following key mechanisms:

  • Environment variable detection: The CORS_ORIGINS variable toggles between development and production modes without code changes.
  • Automatic wildcard fallback: Missing configuration defaults to * for development convenience, with clear logging warnings.
  • Strict origin enforcement: Explicit comma-separated origins in production restrict access to declared domains only.
  • Consistent header application: Custom error handling ensures CORS headers are present even on failed requests.

Frequently Asked Questions

What happens if I don't set CORS_ORIGINS in my environment?

If CORS_ORIGINS is not set, the application defaults to allowing requests from any origin (*). It logs a warning at startup indicating that the API accepts cross-origin requests from any origin, which is suitable for local development but not recommended for production deployments.

How do I configure multiple allowed origins for production?

Set the CORS_ORIGINS environment variable to a comma-separated list of URLs without spaces. For example: CORS_ORIGINS=https://app.example.com,https://admin.example.com. The _parse_cors_origins function in api/main.py splits this string into a list passed to the FastAPI CORSMiddleware.

Why does the API require allow_credentials=True when using specific origins?

The allow_credentials=True setting in the CORSMiddleware configuration (line 239) enables cookies and authorization headers to be included in cross-origin requests. When combined with a specific CORS_ORIGINS list rather than a wildcard, this allows secure authentication flows between your frontend and API while maintaining origin restrictions.

How does the custom error handler ensure CORS compliance?

According to the implementation in api/main.py (lines 247-263), the custom exception handler adds CORS headers to error responses that might otherwise lack them. This prevents browsers from blocking error details due to CORS policy violations when requests fail authentication or validation, ensuring frontend applications can properly handle error messages from the API.

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 →