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 OPTIONS requests

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_PASSWORD or OPEN_NOTEBOOK_PASSWORD_FILE environment variables to configure API protection.
  • The PasswordAuthMiddleware in api/auth.py enforces 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/status endpoint 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:

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 →