Setting Up Password Protection for Public Deployments in Open Notebook

Open Notebook implements optional password protection via Bearer token middleware that activates when the OPEN_NOTEBOOK_PASSWORD environment variable is set, supporting both plain text and Docker secret file injection for secure public deployments.

When deploying Open Notebook to publicly accessible servers, restricting access is essential. The application provides a lightweight authentication layer that can be enabled through environment configuration without requiring external identity providers. This guide explains the architecture behind setting up password protection for public deployments using the built-in middleware and secret resolution utilities.

Authentication Middleware Architecture

The core enforcement logic resides in api/auth.py, which defines the PasswordAuthMiddleware. This Starlette-based middleware intercepts every incoming HTTP request before it reaches route handlers. When the OPEN_NOTEBOOK_PASSWORD environment variable is configured, the middleware validates the Authorization header for Bearer tokens. Missing or invalid tokens result in a 401 Unauthorized response with a WWW-Authenticate: Bearer header, while valid passwords allow the request to proceed.

Secret Resolution and Docker Support

To handle both direct environment variables and container secrets, the system uses open_notebook/utils/encryption.py. The get_secret_from_env function first checks for a _FILE suffix variant (e.g., OPEN_NOTEBOOK_PASSWORD_FILE), reading the secret from the referenced file path if present. This pattern enables Docker secrets support while falling back to standard environment variables when the file variant is absent.

Configuring Password Protection

Environment Variable Activation

The simplest activation method involves setting the OPEN_NOTEBOOK_PASSWORD variable. When this variable is empty or unset, authentication is completely disabled, making local development seamless. This default behavior is verified in the test fixtures found in tests/conftest.py.

Docker Secrets Integration

For production deployments using Docker secrets or mounted secret files, export OPEN_NOTEBOOK_PASSWORD_FILE pointing to the secret's location (e.g., /run/secrets/notebook_password). The middleware loads the password from this file path, eliminating the need to expose credentials in environment variables.

Protected Routes and Status Monitoring

Whitelisted Public Endpoints

Certain endpoints remain accessible without authentication to support health checks and API discovery. According to the middleware implementation in api/auth.py, the system automatically excludes the root path (/), health checks (/health), interactive documentation (/docs), Redoc (/redoc), and the OpenAPI schema (/openapi.json) from Bearer token requirements.

Authentication Status Endpoint

The router defined in api/routers/auth.py exposes a /auth/status endpoint that returns the current authentication state. This allows clients to detect whether password protection is active before attempting protected operations, returning {"auth_enabled": true} when the middleware is enforcing credentials.

Middleware Registration

The FastAPI application registers the middleware in api/main.py, ensuring it executes for all incoming requests. The registration occurs during application startup, binding the PasswordAuthMiddleware to the ASGI stack before any route handlers process traffic.

Practical Configuration Examples

Enable protection with a plaintext environment variable:

export OPEN_NOTEBOOK_PASSWORD="secure-password-123"
uvicorn api.main:app --host 0.0.0.0 --port 8000

Use a Docker secret instead of plaintext:


# Create secret

echo "secure-password-123" | docker secret create notebook_password -

# Run with file reference

docker run -e OPEN_NOTEBOOK_PASSWORD_FILE=/run/secrets/notebook_password -p 8000:8000 open-notebook

Access protected endpoints with a Bearer token:

curl -H "Authorization: Bearer secure-password-123" http://localhost:8000/notebooks

Verify authentication status:

curl http://localhost:8000/auth/status

Disable authentication for public demos:

unset OPEN_NOTEBOOK_PASSWORD
uvicorn api.main:app

Summary

  • Open Notebook uses PasswordAuthMiddleware in api/auth.py to enforce Bearer token authentication when OPEN_NOTEBOOK_PASSWORD is set.
  • The get_secret_from_env utility in open_notebook/utils/encryption.py supports both direct environment variables and Docker secret files via _FILE suffix variants.
  • Authentication is disabled by default when the password variable is unset, enabling zero-config local development.
  • Public endpoints including /docs, /redoc, /health, and /auth/status remain accessible without credentials.
  • Clients must include Authorization: Bearer <password> headers for all protected routes; otherwise, the middleware returns a 401 response with WWW-Authenticate: Bearer.

Frequently Asked Questions

What happens if I don't set OPEN_NOTEBOOK_PASSWORD?

If the environment variable is unset or empty, the middleware automatically disables authentication, allowing unrestricted access to all endpoints. This default behavior is verified in the test fixtures found in tests/conftest.py.

How do I use Docker secrets instead of plain text environment variables?

Export OPEN_NOTEBOOK_PASSWORD_FILE with the path to your secret file (e.g., /run/secrets/my_secret). The application reads the password from this file rather than the environment, following the pattern implemented in open_notebook/utils/encryption.py.

Which endpoints are excluded from password protection?

The middleware whitelists the root path (/), health checks (/health), API documentation (/docs), Redoc (/redoc), and the OpenAPI schema (/openapi.json), plus the /auth/status endpoint itself. All other routes require valid Bearer tokens.

How do I verify that password protection is active?

Send a GET request to /auth/status as implemented in api/routers/auth.py. The endpoint returns {"auth_enabled": true} when protection is active, or false when the application is running in open mode.

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 →