# Open Notebook Authentication Middleware: Production Password Protection Explained

> Discover Open Notebook authentication middleware for production password protection. Learn how PasswordAuthMiddleware secures FastAPI endpoints using environment variables.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-21

---

**Open Notebook implements a custom `PasswordAuthMiddleware` that validates Bearer tokens against the `OPEN_NOTEBOOK_PASSWORD` environment variable to secure FastAPI endpoints in production, automatically skipping authentication when the password is not configured for local development.**

The `lfnovo/open-notebook` repository provides a lightweight, environment-driven authentication system for its FastAPI backend. This authentication middleware intercepts every incoming request to verify credentials before they reach protected API routes, while maintaining a zero-configuration default for local development when no password is set.

## How the Password Authentication Middleware Works

### Environment Configuration

The middleware reads the production password from the `OPEN_NOTEBOOK_PASSWORD` environment variable. For Docker deployments, it also supports Docker secrets via the `OPEN_NOTEBOOK_PASSWORD_FILE` variable, allowing the application to read credentials from mounted secret files rather than environment variables. When neither configuration is present, authentication is completely disabled, enabling seamless local development without credential management.

### Authentication Flow

For every incoming request to protected routes, the middleware checks for an `Authorization: Bearer <password>` header. If the provided token matches the configured password, the request proceeds to the handler. If credentials are missing, malformed, or incorrect, the middleware returns HTTP 401 with a `WWW-Authenticate: Bearer` header to trigger client authentication.

## Implementation Details

### Middleware Registration in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py)

The `PasswordAuthMiddleware` is instantiated and added to the FastAPI application early in the startup sequence to ensure it executes before route handlers. This registration occurs in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) with a specific list of excluded paths that bypass authentication:

```python

# api/main.py

from api.auth import PasswordAuthMiddleware

app = FastAPI(...)

# Insert the middleware early so it runs before any router handling

app.add_middleware(
    PasswordAuthMiddleware,
    excluded_paths=[
        "/",
        "/health",
        "/docs",
        "/openapi.json",
        "/redoc",
        "/api/auth/status",
        "/api/config",
    ],
)

```

### Core Logic in [`api/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/auth.py)

The actual authentication logic resides in [`api/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/auth.py), where the `PasswordAuthMiddleware` class processes each request to validate headers against the configured secret. The middleware automatically handles the distinction between production mode (password required) and development mode (authentication disabled).

### Optional Route-Level Dependency

For individual path operations requiring explicit programmatic verification, the `check_api_password` dependency provides direct access to the authentication logic:

```python

# api/auth.py

def check_api_password(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(security),
) -> bool:
    # Returns True if the password is not configured or matches the provided token,

    # otherwise raises HTTPException(401).

    ...

```

## Excluded Routes and Public Endpoints

The middleware automatically bypasses authentication for essential infrastructure and status endpoints. The complete list of excluded paths includes:

- Health checks: `/` and `/health`
- API documentation: `/docs`, `/redoc`, and [`/openapi.json`](https://github.com/lfnovo/open-notebook/blob/main//openapi.json)
- Authentication status: `/api/auth/status`
- Configuration endpoint: `/api/config`

All other routes under `/api/` require valid Bearer tokens in the Authorization header.

## Production Deployment Considerations

When deploying to production, ensure the `OPEN_NOTEBOOK_PASSWORD` environment variable is set to a strong, unique value. The middleware expects tokens in the format `Authorization: Bearer <password>` as demonstrated in this example request:

```http
GET /api/notebooks HTTP/1.1
Host: localhost:5055
Authorization: Bearer my‑production‑password

```

Requests with missing or invalid credentials receive a standard 401 response:

```json
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

{
  "detail": "Missing authorization header"
}

```

## Summary

- Open Notebook uses a custom `PasswordAuthMiddleware` defined in [`api/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/auth.py) to protect FastAPI endpoints
- Authentication is controlled by the `OPEN_NOTEBOOK_PASSWORD` environment variable or Docker secret file via `OPEN_NOTEBOOK_PASSWORD_FILE`
- When unset, the middleware automatically disables authentication for local development convenience
- The middleware excludes health checks (`/health`), documentation (`/docs`, `/redoc`), and status endpoints (`/api/auth/status`, `/api/config`) from password requirements
- Failed authentication returns HTTP 401 with a `WWW-Authenticate: Bearer` header

## Frequently Asked Questions

### What happens if OPEN_NOTEBOOK_PASSWORD is not set?

When the `OPEN_NOTEBOOK_PASSWORD` environment variable and the corresponding Docker secret file are both absent, the authentication middleware automatically disables protection entirely. This design allows developers to run Open Notebook locally without configuring credentials, while production deployments enforce security through mandatory environment configuration.

### How do I make an authenticated request to the Open Notebook API?

Include an `Authorization` header with the Bearer scheme followed by your configured password. The required header format is `Authorization: Bearer <password>`. The middleware validates this token against the `OPEN_NOTEBOOK_PASSWORD` value on every request to protected endpoints, returning 401 for any missing or mismatched credentials.

### Which routes are excluded from password protection?

The middleware specifically excludes the root path (`/`), health checks (`/health`), Swagger UI documentation (`/docs`), ReDoc (`/redoc`), OpenAPI schema ([`/openapi.json`](https://github.com/lfnovo/open-notebook/blob/main//openapi.json)), authentication status (`/api/auth/status`), and the configuration endpoint (`/api/config`). These endpoints remain publicly accessible to support health monitoring, API discovery, and initial setup.

### Can I use Docker secrets to manage the password?

Yes, Open Notebook supports Docker secrets through the `OPEN_NOTEBOOK_PASSWORD_FILE` environment variable. When this variable points to a secret file path, the middleware reads the password from that location instead of the standard `OPEN_NOTEBOOK_PASSWORD` environment variable, enabling secure credential management in containerized production environments according to the source code in [`api/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/auth.py).