How PasswordAuthMiddleware Protects API Endpoints with Bearer Tokens in Open Notebook
PasswordAuthMiddleware is a FastAPI/Starlette middleware that intercepts every HTTP request to enforce Bearer token authentication using a single password, while allowing specific paths and CORS pre-flight requests to remain accessible.
The lfnovo/open-notebook project uses PasswordAuthMiddleware to secure its REST API with a simple, environment-based authentication mechanism. This middleware acts as a global gatekeeper, validating Authorization headers against a configured secret before allowing requests to reach route handlers.
Environment-Based Password Configuration
At startup, the middleware initializes by loading the secret password via get_secret_from_env from open_notebook/utils/encryption.py. It checks for the OPEN_NOTEBOOK_PASSWORD environment variable or a corresponding Docker secret file.
If no password is configured, the middleware enters a no-op mode, allowing the API to run without authentication—ideal for local development scenarios.
Path-Based Access Control
The middleware accepts an excluded_paths parameter during registration in api/main.py to whitelist specific endpoints. By default, the root path (/), health checks (/health), documentation (/docs, /redoc, /openapi.json), authentication status (/api/auth/status), and configuration endpoints (/api/config) bypass password verification.
This ensures public accessibility for status checks and API documentation while protecting business logic routes.
Bearer Token Validation Logic
For non-excluded paths, the middleware enforces strict header validation according to the following workflow:
- Missing Header: Returns 401 Unauthorized with a
WWW-Authenticate: Bearerchallenge header. - Invalid Format: Validates the
Authorizationheader follows theBearer {password}format; deviations return 401 with "Invalid authorization header format". - Password Mismatch: Compares the extracted token against the stored secret; mismatches return 401 Invalid password.
- Success: Calls
call_nextto forward the request to the route handler and returns the response unchanged.
CORS Pre-flight Bypass
OPTIONS requests used for CORS pre-flight checks are automatically allowed without authentication validation. This prevents cross-origin request failures during browser-based API interactions while maintaining security for actual data-modifying operations.
Implementing the Middleware in FastAPI
Register the middleware in your FastAPI application entry point to enable global protection:
# api/main.py – middleware registration
app.add_middleware(
PasswordAuthMiddleware,
excluded_paths=[
"/", "/health", "/docs", "/openapi.json", "/redoc",
"/api/auth/status", "/api/config",
],
)
This configuration applies the authentication layer to every incoming request while preserving access to essential metadata and health monitoring endpoints.
Route-Level Authentication with check_api_password
For scenarios requiring explicit authentication on specific routes rather than global middleware, the api/auth.py module exports check_api_password, a FastAPI dependency function. This allows individual endpoints to enforce the same Bearer token validation without affecting the entire application surface.
from api.auth import check_api_password
from fastapi import Depends, APIRouter
router = APIRouter()
@router.get("/admin")
async def admin_panel(valid: bool = Depends(check_api_password)):
return {"msg": "You are authorized"}
Use this approach when mixing public and protected routes within the same router or when you need to bypass the middleware for specific request types.
Client Authentication Examples
Access protected endpoints by including the Bearer token in the Authorization header:
curl -H "Authorization: Bearer my-secret-pw" \
http://localhost:5055/api/notebooks
Failed authentication attempts return clear error messages:
{
"detail": "Invalid password"
}
Missing headers trigger the authentication challenge:
{
"detail": "Not authenticated"
}
Summary
- Global protection:
PasswordAuthMiddlewareinapi/auth.pyintercepts all HTTP requests before they reach FastAPI routers. - Flexible configuration: Supports environment variable (
OPEN_NOTEBOOK_PASSWORD) or Docker secret file loading viaget_secret_from_env. - Selective exemptions: Configurable
excluded_pathsallow public access to health checks, documentation, and status endpoints. - Standard Bearer scheme: Validates
Authorization: Bearer {password}headers with proper 401 responses andWWW-Authenticatechallenges. - Dual implementation: Offers both middleware-level (global) and dependency-level (route-specific) protection via
check_api_password.
Frequently Asked Questions
How does PasswordAuthMiddleware handle missing authentication headers?
When the Authorization header is absent, the middleware returns an HTTP 401 Unauthorized response with a WWW-Authenticate: Bearer header, prompting clients to provide credentials according to RFC 6750.
Can I disable authentication entirely for local development?
Yes. If OPEN_NOTEBOOK_PASSWORD is not set in the environment and no Docker secret file is found, PasswordAuthMiddleware automatically becomes a pass-through (no-op), allowing all requests without validation.
What endpoints are excluded from password protection by default?
The default configuration in api/main.py excludes the root path (/), /health, /docs, /redoc, /openapi.json, /api/auth/status, and /api/config from authentication requirements.
How do I protect a single route without enabling global middleware?
Import check_api_password from api/auth.py and use it as a FastAPI dependency (Depends(check_api_password)) on specific route handlers. This enforces Bearer token validation only for that endpoint while leaving others unprotected.
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 →