How to Secure the Open Notebook FastAPI Application with PasswordAuthMiddleware in Production
Deploy Open Notebook in production by enabling PasswordAuthMiddleware with a strong OPEN_NOTEBOOK_PASSWORD, registering it early in the FastAPI application stack, and restricting CORS to your trusted frontend domains.
Open Notebook (lfnovo/open-notebook) ships with a built-in authentication layer for its FastAPI backend. The PasswordAuthMiddleware—implemented in api/auth.py (lines 12–115)—provides password-based protection for all API endpoints, making it ideal for securing personal or small-team deployments without external identity providers.
Set the Authentication Secret
The middleware reads the password using get_secret_from_env from open_notebook/utils/encryption.py, which supports both plain environment variables and Docker secrets.
Environment Variable Configuration
Set a cryptographically strong password in your environment before starting the application:
export OPEN_NOTEBOOK_PASSWORD="your-very-long-random-secret-here"
Docker Secrets Support
For containerized deployments, store the password in a secret file and reference it via the OPEN_NOTEBOOK_PASSWORD_FILE variable:
export OPEN_NOTEBOOK_PASSWORD_FILE=/run/secrets/api_password
The helper function automatically detects the _FILE suffix and reads the secret from disk, falling back to the plain variable if the file is not present.
Register PasswordAuthMiddleware in the FastAPI Stack
Add the middleware early in your application initialization so it executes before any router logic. In api/main.py (lines 73–86), the registration looks like this:
from api.auth import PasswordAuthMiddleware
app.add_middleware(
PasswordAuthMiddleware,
excluded_paths=[
"/", "/health", "/docs", "/openapi.json", "/redoc",
"/api/auth/status", "/api/config",
],
)
The excluded_paths parameter (configured in lines 77–85) ensures that health checks, OpenAPI documentation, and the authentication status endpoint remain publicly accessible. All other routes—including notebook and chat endpoints—require the Bearer token.
Lock Down Production Infrastructure
Enabling the middleware is only the first step. You must also harden the transport layer and access controls.
Enforce TLS Termination
The middleware validates the Authorization: Bearer <password> header, but it does not encrypt traffic. Always run the API behind a reverse proxy such as Nginx or Traefik with TLS termination configured. This prevents the password from being intercepted in transit.
Restrict CORS Origins
By default, the application allows all origins (*), which is insecure for production. Set the CORS_ORIGINS environment variable to your exact frontend URL:
export CORS_ORIGINS="https://notebook.example.com"
The _parse_cors_origins helper in api/main.py (lines 53–59) parses this string and configures FastAPI's CORSMiddleware accordingly.
Audit Failed Authentication Attempts
When authentication fails, the middleware returns a 401 Unauthorized response with a WWW-Authenticate: Bearer header. Configure your reverse proxy or logging infrastructure to capture these 401 responses for security monitoring.
Verify End-to-End Protection
Test the configuration using curl to ensure the middleware blocks unauthorized requests while allowing valid ones.
Check the public status endpoint—implemented in api/routers/auth.py (lines 12–27)—which requires no authentication:
curl http://localhost:5055/api/auth/status
Attempt to access a protected endpoint without credentials:
curl http://localhost:5055/api/notes
# Expected: 401 Unauthorized
Access the same endpoint with the correct Bearer token:
curl -H "Authorization: Bearer $OPEN_NOTEBOOK_PASSWORD" \
http://localhost:5055/api/notes
Summary
- Configure the secret using
OPEN_NOTEBOOK_PASSWORDorOPEN_NOTEBOOK_PASSWORD_FILEviaget_secret_from_envinopen_notebook/utils/encryption.py. - Register the middleware in
api/main.pywithapp.add_middleware(PasswordAuthMiddleware, ...)and verify yourexcluded_pathslist. - Exclude public endpoints such as
/health,/docs, and/api/auth/statusto allow monitoring and documentation access. - Run behind TLS to protect the Bearer token in transit.
- Restrict CORS by setting
CORS_ORIGINSto specific domains rather than the default wildcard.
Frequently Asked Questions
What endpoints are excluded from authentication by default?
The default excluded_paths list in api/main.py includes the root path (/), health check (/health), OpenAPI documentation (/docs, /openapi.json, /redoc), and the authentication status endpoint (/api/auth/status). These remain accessible without a password so that load balancers can perform health checks and developers can inspect the API schema.
Can I use a file-based secret instead of an environment variable?
Yes. The get_secret_from_env utility supports Docker secrets via the OPEN_NOTEBOOK_PASSWORD_FILE environment variable. If this variable is set and points to a readable file, the middleware reads the password from that file. Otherwise, it falls back to the value of OPEN_NOTEBOOK_PASSWORD.
How does the middleware handle missing or incorrect passwords?
When a request lacks the Authorization header or contains an incorrect Bearer token, PasswordAuthMiddleware (defined in api/auth.py) immediately returns a 401 Unauthorized response with a WWW-Authenticate: Bearer header. The response body contains a JSON error message, and the request is not forwarded to any downstream routers.
Is the PasswordAuthMiddleware sufficient for high-security environments?
While PasswordAuthMiddleware provides basic access control suitable for personal deployments, high-security environments should combine it with network-level firewalls, VPNs, or integrate with OAuth2/OpenID Connect providers. The middleware performs no rate limiting or account lockout, so pair it with a reverse proxy that can handle brute-force protection and IP whitelisting.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →