# PasswordAuthMiddleware Authentication Flow in Open Notebook: Implementation Guide

> Explore the Open Notebook PasswordAuthMiddleware authentication flow. Learn how to implement Bearer token validation and secure your endpoints effectively.

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

---

**Open Notebook's `PasswordAuthMiddleware` implements a simple Bearer token authentication system that validates `Authorization` headers against environment-configured passwords while automatically exempting health checks and documentation endpoints from security checks.**

Open Notebook secures its FastAPI API using a lightweight password-based middleware defined in [`api/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/auth.py). The `PasswordAuthMiddleware` class provides a transparent security layer that requires no external identity providers, making it ideal for single-user deployments or development environments where simple access control is sufficient.

## Password Loading and Configuration

### Environment-Based Secret Retrieval

The middleware initializes by loading the authentication secret from environment variables. It uses the `get_secret_from_env` helper function to check `OPEN_NOTEBOOK_PASSWORD` directly, or reads from a Docker secret file specified by `OPEN_NOTEBOOK_PASSWORD_FILE` in [`api/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/auth.py).

If neither environment variable is configured, the middleware disables authentication entirely and allows all requests to pass through without validation. This design provides a seamless toggle for development environments without code changes.

## Request Filtering and Public Path Exclusions

### Whitelisted Endpoints and CORS Handling

`PasswordAuthMiddleware` automatically bypasses authentication for specific public paths defined in the source code. These exempt routes include the root endpoint (`/`), `/health`, `/docs`, [`/openapi.json`](https://github.com/lfnovo/open-notebook/blob/main//openapi.json), and `/redoc`.

The middleware also skips CORS pre-flight `OPTIONS` requests to ensure proper cross-origin resource sharing functionality. This filtering occurs before any token validation, allowing public health checks and API documentation to remain accessible without credentials.

## Bearer Token Validation Flow

### Header Verification and Error Responses

For all non-excluded requests, the middleware enforces Bearer token authentication via the `Authorization` header. The system expects the format `Authorization: Bearer <password>`, where the token value must match the password loaded from environment variables.

If the header is missing, malformed, or contains an incorrect token, `PasswordAuthMiddleware` returns a `401 Unauthorized` response with a `WWW-Authenticate: Bearer` challenge header. When the token matches the configured password, the request proceeds to the next handler in the FastAPI pipeline.

## Frontend Authentication Integration

### Checking Authentication Status

The frontend determines whether to prompt for credentials by querying the `/api/auth/status` endpoint defined in [`api/routers/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/auth.py). This endpoint reports whether `OPEN_NOTEBOOK_PASSWORD` is configured, allowing the UI to adapt dynamically to the server's security settings.

```typescript
// src/lib/stores/auth-store.ts – checkAuthRequired()
const response = await fetch(`${apiUrl}/api/auth/status`, {
  cache: 'no-store',
});
const data = await response.json();
const authEnabled = data.auth_enabled;

```

### Client Login Implementation

When authentication is enabled, the frontend submits the user-provided password as a Bearer token in the Authorization header. The store validates credentials by attempting to access a protected endpoint, storing the token only upon successful response.

```typescript
// src/lib/stores/auth-store.ts – login()
const response = await fetch(`${apiUrl}/api/notebooks`, {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${password}`,
    'Content-Type': 'application/json',
  },
});
if (response.ok) {
  // Save token, mark user as authenticated
}

```

## Server-Side Middleware Setup

The middleware is attached to the FastAPI application in [`api/main.py`](https://github.com/lfnovo/open-notebook/blob/main/api/main.py) using the standard middleware pattern. While you can specify additional excluded paths during initialization, the middleware already handles common public routes internally.

```python

# api/main.py (excerpt)

from open_notebook.auth import PasswordAuthMiddleware
app.add_middleware(PasswordAuthMiddleware, excluded_paths=["/health"])

```

When a protected endpoint like `GET /api/notebooks` receives a request, the middleware intercepts the call, validates the Bearer token, and either rejects the request with a 401 status or passes the request to the route handler.

## Summary

- **PasswordAuthMiddleware** loads secrets from `OPEN_NOTEBOOK_PASSWORD` or `OPEN_NOTEBOOK_PASSWORD_FILE` using `get_secret_from_env`
- Public paths including `/health`, `/docs`, and `/redoc` bypass authentication automatically along with `OPTIONS` requests
- Protected endpoints require valid `Authorization: Bearer <password>` headers for access
- The frontend checks authentication requirements via `/api/auth/status` before prompting for credentials
- Invalid or missing tokens trigger `401 Unauthorized` responses with `WWW-Authenticate: Bearer` challenge headers

## Frequently Asked Questions

### What happens if OPEN_NOTEBOOK_PASSWORD is not set?

If neither `OPEN_NOTEBOOK_PASSWORD` nor `OPEN_NOTEBOOK_PASSWORD_FILE` is configured, `PasswordAuthMiddleware` disables authentication entirely and allows all requests to pass through without token validation, effectively running the API in open mode.

### Which endpoints are excluded from PasswordAuthMiddleware checks?

The middleware automatically exempts the root path (`/`), `/health`, `/docs`, [`/openapi.json`](https://github.com/lfnovo/open-notebook/blob/main//openapi.json), `/redoc`, and all CORS pre-flight `OPTIONS` requests from authentication requirements, ensuring health checks and API documentation remain publicly accessible.

### How does the frontend know if authentication is required?

The frontend queries the `/api/auth/status` endpoint to check if a password is configured on the server. This endpoint returns a boolean `auth_enabled` property that determines whether the UI should present a login prompt to the user.

### What response does PasswordAuthMiddleware return for invalid tokens?

For requests with missing, malformed, or incorrect Bearer tokens, the middleware returns a `401 Unauthorized` HTTP status code and includes a `WWW-Authenticate: Bearer` response header to challenge the client for valid credentials according to RFC 6750 standards.