How to Configure Password Authentication for Production in Open Notebook
To configure password authentication for production in Open Notebook, set the OPEN_NOTEBOOK_PASSWORD or OPEN_NOTEBOOK_PASSWORD_FILE environment variable and ensure the PasswordAuthMiddleware is enabled in your FastAPI application.
Open Notebook provides a lightweight yet robust password protection mechanism for its API endpoints. While authentication is optional during development, enabling it is mandatory for production deployments to prevent unauthorized access to your notebook data. This guide walks through configuring production-ready password authentication using environment variables or Docker secrets as implemented in the lfnovo/open-notebook repository.
How Password Authentication Works in Open Notebook
The authentication system relies on two core components defined in api/auth.py that validate Bearer tokens against a secret stored outside your source code.
The PasswordAuthMiddleware Component
The PasswordAuthMiddleware is a FastAPI BaseHTTPMiddleware that intercepts every incoming request before it reaches route handlers. It automatically extracts the password from environment variables or secret files and validates the Authorization: Bearer <token> header.
The middleware maintains an excluded_paths list containing public UI endpoints like / and /docs, ensuring these remain accessible while protecting all API routes. When enabled, it runs globally across the entire application without requiring individual route modifications.
The check_api_password Dependency
For fine-grained control, the check_api_password function provides a reusable FastAPI dependency. This allows you to apply authentication selectively to specific routes rather than using the global middleware approach.
Secret Retrieval Mechanism
Both authentication methods rely on get_secret_from_env located in open_notebook/utils/encryption.py. This helper supports two configuration patterns:
OPEN_NOTEBOOK_PASSWORD– Plain-text environment variable suitable for local testingOPEN_NOTEBOOK_PASSWORD_FILE– Path to a file containing the secret, following Docker secrets conventions
If neither variable is set, the middleware bypasses authentication entirely, which explains why development servers run without passwords by default.
Production Configuration Steps
Follow these steps to secure your Open Notebook API for production environments.
1. Generate a Strong Password
Create a cryptographically secure password using OpenSSL:
openssl rand -base64 32 > ./secrets/open_notebook_password.txt
2. Configure the Secret
Option A: Docker Secret (Recommended for Production)
Create a secrets directory and reference it in your docker-compose.yml:
version: "3.8"
services:
api:
build: .
env_file: .env
secrets:
- open_notebook_password
secrets:
open_notebook_password:
file: ./secrets/open_notebook_password.txt
Option B: Environment Variable
Add the following to your deployment environment, Kubernetes Secret, or .env file:
OPEN_NOTEBOOK_PASSWORD=your-secret-here
3. Enable the Middleware
The middleware registration typically occurs in api/main.py. Verify or add the following configuration:
from fastapi import FastAPI
from api.auth import PasswordAuthMiddleware
app = FastAPI()
app.add_middleware(PasswordAuthMiddleware)
The middleware automatically detects your configured secret without requiring additional code changes.
Docker Secret Configuration (Recommended)
Using Docker secrets prevents sensitive credentials from appearing in container environment variables or process listings. When using OPEN_NOTEBOOK_PASSWORD_FILE, ensure your container orchestration mounts the secret to the expected path.
The get_secret_from_env helper reads the file content directly, satisfying production security best practices by keeping the clear-text password out of logs and inspection tools.
Route-Level Authentication (Optional)
If you prefer to protect specific endpoints rather than using global middleware, apply the dependency directly to routes:
from fastapi import APIRouter, Depends
from api.auth import check_api_password
router = APIRouter()
@router.get("/admin", dependencies=[Depends(check_api_password)])
async def admin_panel():
return {"msg": "You are admin"}
This approach is useful for mixed-public/private APIs where only certain resources require authentication.
Verifying Your Configuration
Test your production authentication setup using curl commands.
Unauthenticated request (should fail):
curl http://localhost:5055/api/notebooks
Expected response:
{
"detail": "Missing authorization header",
"WWW-Authenticate": "Bearer"
}
Authenticated request (should succeed):
curl -H "Authorization: Bearer $(cat ./secrets/open_notebook_password.txt)" \
http://localhost:5055/api/notebooks
Summary
- Store secrets safely using
OPEN_NOTEBOOK_PASSWORD_FILEwith Docker secrets rather than plain environment variables in production. - Global protection is handled by
PasswordAuthMiddlewareinapi/auth.py, which validates Bearer tokens on every request except excluded public paths. - Flexible authentication allows route-level protection via the
check_api_passworddependency for granular control. - Zero-code configuration means the system automatically enables authentication when environment variables are present, defaulting to open access only when unset.
Frequently Asked Questions
How do I disable authentication for local development?
Simply ensure neither OPEN_NOTEBOOK_PASSWORD nor OPEN_NOTEBOOK_PASSWORD_FILE is set in your environment. The PasswordAuthMiddleware automatically bypasses authentication when no secret is configured, allowing the development server to run without credentials.
Can I use both the middleware and route-level dependencies together?
Yes, though it creates redundant checks. The middleware runs first for global protection, while check_api_password provides additional validation for specific routes. This pattern is useful when layering authentication strategies or requiring additional validation logic beyond the basic password check.
What file format does the password file require?
The file specified in OPEN_NOTEBOOK_PASSWORD_FILE should contain only the raw password string without quotes, newlines, or additional formatting. The get_secret_from_env helper in open_notebook/utils/encryption.py reads the entire file content as the secret value.
Why does my authenticated request still return 403 errors?
Verify that your Authorization header uses the exact format Bearer <password> with a single space between the scheme and token. The middleware performs case-sensitive matching against the secret stored in your environment or file, ensuring no extra whitespace or encoding issues corrupt the validation.
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 →