# Recommended Authentication Strategies for Production Deployments of Open Notebook

> Secure your Open Notebook production deployment with robust authentication. Explore strategies like password protection, TLS, CORS, Docker secrets and SSO integration.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: best-practices
- Published: 2026-06-14

---

**Deploy Open Notebook in production using a layered authentication approach that combines password protection via `OPEN_NOTEBOOK_PASSWORD`, TLS termination at a reverse proxy, strict CORS policies, Docker secrets management, and optional enterprise SSO integration.**

Open Notebook provides built-in password protection sufficient for personal use, but production environments require hardened authentication strategies for production deployments. This guide examines the security architecture implemented in the `lfnovo/open-notebook` repository, detailing how to configure each layer from basic API protection to enterprise OAuth integration.

## Password Protection Foundation

Open Notebook guards every API endpoint with a shared secret authentication mechanism. The system checks for the `OPEN_NOTEBOOK_PASSWORD` environment variable at startup, which clients must send as a Bearer token in the `Authorization` header.

In [`api/routers/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/auth.py), the `/auth/status` endpoint reports whether password protection is active, allowing the frontend to detect authentication requirements dynamically. For production hardening, avoid plaintext environment variables and instead use Docker secrets by setting `OPEN_NOTEBOOK_PASSWORD_FILE` to point to a secret mount path (e.g., `/run/secrets/app_password`). The configuration loader in [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) automatically resolves these `_FILE` suffixed variables to their secret contents.

## TLS and Reverse Proxy Configuration

Password protection is ineffective without transport encryption. Production deployments must terminate TLS at a reverse proxy (nginx, Caddy, or Traefik) to prevent credential interception.

The internal API defaults to port **5055**, which should remain unexposed to the public internet. Configure your reverse proxy to forward HTTPS traffic to the internal service over a private network. Complete configuration examples for nginx, Caddy, and Traefik are documented in [`docs/5-CONFIGURATION/reverse-proxy.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/reverse-proxy.md), including certificate handling and WebSocket support for real-time features.

## CORS Hardening

By default, Open Notebook may accept cross-origin requests. Production deployments must restrict `CORS_ORIGINS` to the exact frontend domain to prevent malicious websites from making authenticated requests using stolen tokens.

Set the environment variable in your `.env` file:

```dotenv
CORS_ORIGINS=https://notebook.example.com

```

The [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) file parses this variable into the FastAPI CORS middleware, blocking requests from unauthorized origins even if they present valid Bearer tokens.

## Enterprise Authentication Integration

For organizations requiring per-user accounts, SSO, or audit trails, Open Notebook supports external identity providers via authentication proxies. Deploy Keycloak, Authelia, or Traefik with Forward-Auth in front of the application, configured to inject a Bearer token that the API validates against the `OPEN_NOTEBOOK_PASSWORD` secret.

This approach delegates session management, token revocation, and role-based access control to the enterprise IdP while maintaining Open Notebook's simple password-gate architecture. The proxy handles OAuth 2.0/OIDC flows, then passes requests to Open Notebook with the appropriate authorization headers.

## Network Segmentation and Secrets Management

Defense-in-depth requires limiting direct API access even if credentials are compromised. In [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml), bind the API port to localhost only:

```yaml
services:
  open_notebook:
    ports:
      - "127.0.0.1:5055:5055"

```

Sensitive configuration including the encryption key (`OPEN_NOTEBOOK_ENCRYPTION_KEY`) must never reside in source control. Use Docker secrets via `OPEN_NOTEBOOK_ENCRYPTION_KEY_FILE`, which [`open_notebook/utils/encryption.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/encryption.py) reads to derive encryption keys for API credential storage. The [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) module handles the file-to-variable resolution automatically.

## Production Implementation Examples

Access the API with password authentication using curl:

```bash
curl -H "Authorization: Bearer $OPEN_NOTEBOOK_PASSWORD" \
     http://localhost:5055/api/notebooks

```

Wrap the authentication logic in a Python client:

```python
import requests

class OpenNotebookClient:
    def __init__(self, base_url: str, password: str):
        self.base_url = base_url
        self.headers = {"Authorization": f"Bearer {password}"}

    def list_notebooks(self):
        resp = requests.get(f"{self.base_url}/api/notebooks", headers=self.headers)
        resp.raise_for_status()
        return resp.json()

```

Deploy with Docker secrets and localhost binding:

```yaml
services:
  open_notebook:
    image: lfnovo/open_notebook:v1-latest
    ports:
      - "127.0.0.1:5055:5055"
    environment:
      - OPEN_NOTEBOOK_PASSWORD_FILE=/run/secrets/app_password
      - OPEN_NOTEBOOK_ENCRYPTION_KEY_FILE=/run/secrets/encryption_key
      - CORS_ORIGINS=https://notebook.example.com
    secrets:
      - app_password
      - encryption_key

  reverse_proxy:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - open_notebook

secrets:
  app_password:
    file: ./secrets/app_password.txt
  encryption_key:
    file: ./secrets/encryption_key.txt

```

## Summary

- **Password Protection**: Configure `OPEN_NOTEBOOK_PASSWORD` or `OPEN_NOTEBOOK_PASSWORD_FILE` to gate all API endpoints, with status checking available via `/auth/status` in [`api/routers/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/auth.py).
- **TLS Termination**: Deploy behind a reverse proxy (nginx/Caddy/Traefik) to encrypt traffic to port 5055, preventing credential exposure.
- **Origin Control**: Restrict `CORS_ORIGINS` in [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) to your exact domain to mitigate CSRF attacks.
- **Secret Management**: Store `OPEN_NOTEBOOK_ENCRYPTION_KEY` and passwords as Docker secrets, read via `_FILE` variables by the encryption utilities in [`open_notebook/utils/encryption.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/utils/encryption.py).
- **Enterprise SSO**: Implement OAuth 2.0/OIDC through an authenticating proxy that injects Bearer tokens, as documented in [`docs/5-CONFIGURATION/security.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/security.md).

## Frequently Asked Questions

### Does Open Notebook support native OAuth 2.0 authentication?

Open Notebook does not implement native OAuth 2.0/OIDC. Instead, it supports enterprise authentication through external identity providers deployed as reverse proxies. The proxy handles the OAuth flow and passes a Bearer token to Open Notebook's `Authorization` header, which the API validates against the configured `OPEN_NOTEBOOK_PASSWORD`.

### How do I rotate the authentication password without downtime?

Update the Docker secret file or environment variable, then restart the Open Notebook container. The [`open_notebook/config.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/config.py) module reads the password at startup, so active sessions using the old token will fail after restart. For zero-downtime rotation, deploy a new container with the updated secret behind a load balancer, then drain connections from the old instance.

### What ports should be exposed in a production Docker deployment?

Expose only your reverse proxy port (typically 443 for HTTPS) to the public internet. Bind the Open Notebook API (port 5055) and Streamlit UI (port 8502) to `127.0.0.1` or a private Docker network. This configuration prevents direct access to the API even if the password is compromised, as shown in the Docker security snippets in [`docs/5-CONFIGURATION/security.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/security.md).

### Is the password sent in plaintext between the UI and API?

Without TLS, the Bearer token containing the password travels in plaintext headers. Production deployments must terminate TLS at the reverse proxy to encrypt all traffic. The password itself is never stored in the browser after the initial login; subsequent requests use the token from session storage, which [`api/routers/auth.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/auth.py) validates against the server-side secret.