Password-Based Authentication for Open Notebook API Endpoints: Implementation Guide
Open Notebook protects its HTTP API using a lightweight Bearer token scheme that reads credentials from environment variables or Docker secrets, enforced globally via PasswordAuthMiddleware in api/auth.py.
The lfnovo/open-notebook repository implements a deliberately simple password-based authentication layer designed for development flexibility while supporting secure production deployments. This mechanism guards all API endpoints through a single environment variable and standard HTTP Authorization headers.
How Password-Based Authentication Works
The authentication system centers on three core components: a secret loading utility, a FastAPI middleware, and an optional route-level dependency.
Password Source and Configuration
The system retrieves credentials using the get_secret_from_env function defined in open_notebook/utils/encryption.py (lines 29-38). This helper first checks for a *_FILE variant of the environment variable—specifically OPEN_NOTEBOOK_PASSWORD_FILE—enabling Docker secret patterns. If the file path exists, the password is read from disk; otherwise, it falls back to the raw OPEN_NOTEBOOK_PASSWORD value.
# Docker secret pattern
export OPEN_NOTEBOOK_PASSWORD_FILE=/run/secrets/open_notebook_password
# Standard environment variable
export OPEN_NOTEBOOK_PASSWORD=my-secure-password
Global Middleware Protection
Every incoming request passes through PasswordAuthMiddleware, implemented in api/auth.py (lines 19-71). During initialization, the middleware stores the password retrieved by get_secret_from_env. If no password is configured, the middleware short-circuits and allows all requests to proceed, leaving the API open by default.
The middleware explicitly excludes specific routes from authentication checks:
- Root path (
/) - Health checks (
/health) - Documentation endpoints (
/docs,/redoc,/openapi.json) - CORS pre-flight
OPTIONSrequests
These exclusions are hardcoded in api/auth.py (lines 35-38).
Request Validation Flow
For protected endpoints, the middleware inspects the Authorization header for the format Bearer <password>. Missing, malformed, or incorrect tokens trigger a 401 Unauthorized response with a WWW-Authenticate: Bearer header, as implemented in api/auth.py (lines 44-71).
Example error responses include:
{"detail": "Missing authorization header"}
{"detail": "Invalid password"}
Optional Per-Route Validation
Individual routes can bypass the global middleware and instead depend on the check_api_password helper function (lines 82-94 in api/auth.py). This function performs identical verification logic but allows granular control, applying authentication only where explicitly injected.
Authentication Status Endpoint
The router in api/routers/auth.py exposes a public GET /auth/status endpoint (lines 13-27) that reports whether authentication is enabled. This allows clients to probe the server's configuration before attempting protected operations.
Configuration Reference
| Variable | Description | Example |
|---|---|---|
OPEN_NOTEBOOK_PASSWORD |
Plain-text password for API access | super-secret-pwd |
OPEN_NOTEBOOK_PASSWORD_FILE |
Path to Docker secret file | /run/secrets/open_notebook_password |
If neither variable is set, the API runs without authentication—suitable for local development but requiring immediate attention before production deployment.
Security Considerations
The password-based authentication implementation follows specific security patterns:
- Memory-only storage: The password is read once at startup and stored in memory; it is never logged to disk or persisted in application state.
- No rate limiting: The mechanism does not implement account lockout or brute-force protection. Production deployments must add these controls at a reverse-proxy or API gateway layer.
- TLS requirement: Because credentials use the Bearer scheme transmitted in HTTP headers, all production traffic must terminate TLS before reaching the Open Notebook API. The default development server runs on unencrypted HTTP.
Implementation Examples
Enabling Authentication with Docker Secrets
Create a secret file and reference it via environment variable:
echo "my-strong-pwd" > /run/secrets/open_notebook_password
export OPEN_NOTEBOOK_PASSWORD_FILE=/run/secrets/open_notebook_password
# Start via Docker Compose
docker compose up api
Enabling Authentication via Environment Variable
export OPEN_NOTEBOOK_PASSWORD=my-strong-pwd
uvicorn api.main:app --host 0.0.0.0 --port 5055
Calling Protected Endpoints with curl
curl -H "Authorization: Bearer my-strong-pwd" \
http://localhost:5055/notebooks
Checking Authentication Status Programmatically
import httpx
resp = httpx.get("http://localhost:5055/auth/status")
print(resp.json())
# => {"auth_enabled": true, "message": "Authentication is required"}
Summary
- Open Notebook uses
OPEN_NOTEBOOK_PASSWORDorOPEN_NOTEBOOK_PASSWORD_FILEenvironment variables to configure API protection. - The
PasswordAuthMiddlewareinapi/auth.pyenforces Bearer token validation on all routes except documentation, health checks, and CORS pre-flight requests. - Authentication is disabled by default when no password is configured, making the system open for local development.
- The
/auth/statusendpoint provides a programmatic way to detect if authentication is active. - Production deployments require TLS termination and external rate limiting, as the built-in system lacks brute-force protection.
Frequently Asked Questions
How do I enable password-based authentication in Open Notebook?
Set the OPEN_NOTEBOOK_PASSWORD environment variable to a non-empty string before starting the API server. Alternatively, use OPEN_NOTEBOOK_PASSWORD_FILE to point to a Docker secret file. The middleware automatically detects these variables at startup via the get_secret_from_env function in open_notebook/utils/encryption.py.
Which API routes are excluded from authentication?
The PasswordAuthMiddleware explicitly bypasses authentication for the root path (/), health endpoint (/health), documentation interfaces (/docs, /redoc), the OpenAPI specification (/openapi.json), and all OPTIONS requests. These exclusions allow health checks and CORS pre-flight requests to succeed without credentials.
Can I use Docker secrets instead of environment variables?
Yes. The get_secret_from_env utility supports the Docker secret pattern. Set OPEN_NOTEBOOK_PASSWORD_FILE to the path of your secret file (e.g., /run/secrets/open_notebook_password). The system reads the file content and uses it as the authentication password, falling back to the raw OPEN_NOTEBOOK_PASSWORD variable only if the file path is unspecified or inaccessible.
Does Open Notebook implement rate limiting for failed authentication attempts?
No. The authentication layer does not include rate limiting, account lockout, or IP-based throttling. For production deployments, implement these protections at a reverse proxy (such as Nginx or Traefik) or API gateway layer to prevent brute-force attacks against the password-based authentication endpoints.
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 →