# Setting Up Password Protection for Public Deployments in Open Notebook

> Secure your public Open Notebook deployments with password protection. Learn how to implement Bearer token middleware using environment variables or Docker secrets.

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

---

**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](https://github.com/lfnovo/open-notebook/blob/main/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](https://github.com/lfnovo/open-notebook/blob/main/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](https://github.com/lfnovo/open-notebook/blob/main/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](https://github.com/lfnovo/open-notebook/blob/main/api/auth.py), the system automatically excludes the root path (`/`), health checks (`/health`), interactive documentation (`/docs`), Redoc (`/redoc`), and the OpenAPI schema ([`/openapi.json`](https://github.com/lfnovo/open-notebook/blob/main//openapi.json)) from Bearer token requirements.

### Authentication Status Endpoint

The router defined in [api/routers/auth.py](https://github.com/lfnovo/open-notebook/blob/main/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](https://github.com/lfnovo/open-notebook/blob/main/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:

```bash
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:

```bash

# 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:

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

```

Verify authentication status:

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

```

Disable authentication for public demos:

```bash
unset OPEN_NOTEBOOK_PASSWORD
uvicorn api.main:app

```

## Summary

- Open Notebook uses `PasswordAuthMiddleware` in [api/auth.py](https://github.com/lfnovo/open-notebook/blob/main/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](https://github.com/lfnovo/open-notebook/blob/main/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](https://github.com/lfnovo/open-notebook/blob/main/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](https://github.com/lfnovo/open-notebook/blob/main/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`](https://github.com/lfnovo/open-notebook/blob/main//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](https://github.com/lfnovo/open-notebook/blob/main/api/routers/auth.py). The endpoint returns `{"auth_enabled": true}` when protection is active, or `false` when the application is running in open mode.