How the Password Authentication Middleware Protects API Endpoints in Open Notebook

Open Notebook uses a shared-secret Bearer token system through a custom FastAPI middleware that automatically gates every API endpoint without requiring individual route decorators.

The lfnovo/open-notebook repository secures its FastAPI backend using a lightweight yet effective password authentication middleware. This custom PasswordAuthMiddleware ensures that all HTTP requests—whether accessing notebooks, sources, or search endpoints—must present a valid shared secret before reaching business logic.

Architecture of the Password Authentication Middleware

Core Implementation in api/auth.py

The middleware class is defined in api/auth.py. On initialization, it reads the OPEN_NOTEBOOK_PASSWORD environment variable, falling back to a hard-coded default if the variable is unset. This secret is stored as an instance attribute for subsequent request validation.

Request Interception and Validation

The dispatch method processes every incoming HTTP request before it reaches any router. It performs the following steps:

  1. Extracts the Authorization header from the incoming request.
  2. Validates that the header follows the Bearer <password> format.
  3. Compares the provided password against the stored secret.
  4. Returns a 401 Unauthorized response with {"detail": "Invalid password"} if validation fails.
  5. Passes the request to the next handler if the token matches.

Global Protection via Middleware Stack

In api/main.py, the middleware is registered at the application level before any routers are mounted:


# api/main.py

from fastapi import FastAPI
from .auth import PasswordAuthMiddleware

app = FastAPI()
app.add_middleware(PasswordAuthMiddleware)  # Protects every endpoint

Because the middleware sits at the top of the FastAPI stack, it automatically protects all routes—including notebook, source, search, and transformation endpoints—without requiring repetitive authentication logic in individual route handlers.

Configuration and Development Mode Behavior

The middleware supports flexible deployment scenarios through environment-based configuration:

  • Production/secured mode: Set OPEN_NOTEBOOK_PASSWORD to a strong secret. All clients must include Authorization: Bearer <password> headers.
  • Development mode: If OPEN_NOTEBOOK_PASSWORD is unset, the middleware skips authentication checks entirely, allowing unrestricted local development access.

Client Integration Examples

To access protected endpoints, clients must include the Bearer token in the Authorization header:

import os
import requests

BASE = "http://localhost:5055"
pwd = os.getenv("OPEN_NOTEBOOK_PASSWORD")          # same secret as the server

headers = {"Authorization": f"Bearer {pwd}"}

resp = requests.get(f"{BASE}/api/notebooks", headers=headers)
print(resp.json())   # works only with correct password

When authentication fails, the API returns:

{
  "detail": "Invalid password"
}

The repository includes api/client.py, which demonstrates automatic header injection for programmatic access.

Key Files and Components

  • api/auth.py: Implements PasswordAuthMiddleware with secret loading and Bearer token validation logic.
  • api/main.py: Registers the middleware globally before mounting API routers.
  • api/client.py: Provides example client code that automatically injects the Authorization header.
  • docs/5-CONFIGURATION/security.md: Documents the password-based security model for development environments.

Summary

  • The PasswordAuthMiddleware in api/auth.py implements a shared-secret authentication pattern using Bearer tokens.
  • All API endpoints are automatically protected because the middleware is added at the application level in api/main.py before any routers.
  • Authentication requires an Authorization header with the format Bearer <OPEN_NOTEBOOK_PASSWORD>.
  • Missing or incorrect passwords result in a 401 Unauthorized response with the JSON detail "Invalid password".
  • When OPEN_NOTEBOOK_PASSWORD is unset, the middleware bypasses checks to facilitate local development.

Frequently Asked Questions

What happens if the OPEN_NOTEBOOK_PASSWORD environment variable is not set?

If the environment variable is missing, the middleware skips the authentication check entirely. This design allows developers to run the application locally without configuring passwords, while production deployments can enforce security by setting the variable.

Do I need to add authentication logic to each API route individually?

No. Because PasswordAuthMiddleware is registered at the FastAPI application level in api/main.py, it intercepts every incoming request before reaching any router. Individual endpoints do not require additional decorators or authentication checks.

What is the exact format of the Authorization header?

The middleware expects an Authorization header with the value Bearer <password>, where <password> matches the OPEN_NOTEBOOK_PASSWORD environment variable configured on the server. Requests without this header or with an incorrect token receive a 401 Unauthorized response.

Where is the authentication middleware initialized in the codebase?

The middleware class is defined in api/auth.py, and it is instantiated and added to the FastAPI application in api/main.py via app.add_middleware(PasswordAuthMiddleware) before any API routers are mounted.

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 →