Spaces:
Paused
Paused
| # Security Configuration | |
| Protect your Open Notebook deployment with password authentication and production hardening. | |
| --- | |
| ## API Key Encryption | |
| Open Notebook encrypts API keys stored in the database using Fernet symmetric encryption (AES-128-CBC with HMAC-SHA256). | |
| ### Configuration Methods | |
| | Method | Documentation | | |
| |--------|---------------| | |
| | **Settings UI** | [API Configuration Guide](../3-USER-GUIDE/api-configuration.md) | | |
| | **Environment Variables** | This page (below) | | |
| ### Setup | |
| Set the encryption key to any secret string: | |
| ```bash | |
| # .env or docker.env | |
| OPEN_NOTEBOOK_ENCRYPTION_KEY=my-secret-passphrase | |
| ``` | |
| Any string works — it will be securely derived via SHA-256 internally. Use a strong passphrase for production deployments. | |
| ### Default Credentials | |
| | Setting | Default | Security Level | | |
| |---------|---------|----------------| | |
| | Password | `open-notebook-change-me` | Development only | | |
| | Encryption Key | **None** (must be configured) | Required for API key storage | | |
| **The encryption key has no default.** You must set `OPEN_NOTEBOOK_ENCRYPTION_KEY` before using the API key configuration feature. Without it, encrypting/decrypting API keys will fail. | |
| ### Docker Secrets Support | |
| Both settings support Docker secrets via `_FILE` suffix: | |
| ```yaml | |
| environment: | |
| - OPEN_NOTEBOOK_PASSWORD_FILE=/run/secrets/app_password | |
| - OPEN_NOTEBOOK_ENCRYPTION_KEY_FILE=/run/secrets/encryption_key | |
| ``` | |
| ### Security Notes | |
| | Scenario | Behavior | | |
| |----------|----------| | |
| | Key configured | API keys encrypted with your key | | |
| | No key configured | Encryption/decryption will fail (key is required) | | |
| | Key changed | Old encrypted keys become unreadable | | |
| | Legacy data | Unencrypted keys still work (graceful fallback) | | |
| ### Key Management | |
| - **Keep secret**: Never commit the encryption key to version control | |
| - **Backup securely**: Store the key separately from database backups | |
| - **No rotation yet**: Changing the key requires re-saving all API keys | |
| - **Per-deployment**: Each instance should have its own encryption key | |
| --- | |
| ## When to Use Password Protection | |
| ### Use it for: | |
| - Public cloud deployments (PikaPods, Railway, DigitalOcean) | |
| - Shared network environments | |
| - Any deployment accessible beyond localhost | |
| ### You can skip it for: | |
| - Local development on your machine | |
| - Private, isolated networks | |
| - Single-user local setups | |
| --- | |
| ## Quick Setup | |
| ### Docker Deployment | |
| ```yaml | |
| # Add to your docker-compose.yml (requires surrealdb service, see installation guide) | |
| services: | |
| open_notebook: | |
| image: lfnovo/open_notebook:v1-latest | |
| pull_policy: always | |
| environment: | |
| - OPEN_NOTEBOOK_ENCRYPTION_KEY=your-secret-encryption-key | |
| - OPEN_NOTEBOOK_PASSWORD=your_secure_password | |
| # ... rest of config | |
| ``` | |
| Or using environment file: | |
| ```bash | |
| # docker.env | |
| OPEN_NOTEBOOK_ENCRYPTION_KEY=your-secret-encryption-key | |
| OPEN_NOTEBOOK_PASSWORD=your_secure_password | |
| ``` | |
| > **Important**: The encryption key is **required** for credential storage. Without it, you cannot save AI provider credentials via the Settings UI. If you change or lose the encryption key, all stored credentials become unreadable. | |
| ### Development Setup | |
| ```bash | |
| # .env | |
| OPEN_NOTEBOOK_PASSWORD=your_secure_password | |
| ``` | |
| --- | |
| ## Password Requirements | |
| ### Good Passwords | |
| ```bash | |
| # Strong: 20+ characters, mixed case, numbers, symbols | |
| OPEN_NOTEBOOK_PASSWORD=MySecure2024!Research#Tool | |
| OPEN_NOTEBOOK_PASSWORD=Notebook$Dev$2024$Strong! | |
| # Generated (recommended) | |
| OPEN_NOTEBOOK_PASSWORD=$(openssl rand -base64 24) | |
| ``` | |
| ### Bad Passwords | |
| ```bash | |
| # DON'T use these | |
| OPEN_NOTEBOOK_PASSWORD=password123 | |
| OPEN_NOTEBOOK_PASSWORD=opennotebook | |
| OPEN_NOTEBOOK_PASSWORD=admin | |
| ``` | |
| --- | |
| ## How It Works | |
| ### Frontend Protection | |
| 1. Login form appears on first visit | |
| 2. Password stored in browser session | |
| 3. Session persists until browser closes | |
| 4. Clear browser data to log out | |
| ### API Protection | |
| All API endpoints require authentication: | |
| ```bash | |
| # Authenticated request | |
| curl -H "Authorization: Bearer your_password" \ | |
| http://localhost:5055/api/notebooks | |
| # Unauthenticated (will fail) | |
| curl http://localhost:5055/api/notebooks | |
| # Returns: {"detail": "Missing authorization header"} | |
| ``` | |
| ### Unprotected Endpoints | |
| These work without authentication: | |
| - `/health` - System health check | |
| - `/docs` - API documentation | |
| - `/openapi.json` - OpenAPI spec | |
| --- | |
| ## API Authentication Examples | |
| ### curl | |
| ```bash | |
| # List notebooks | |
| curl -H "Authorization: Bearer your_password" \ | |
| http://localhost:5055/api/notebooks | |
| # Create notebook | |
| curl -X POST \ | |
| -H "Authorization: Bearer your_password" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"name": "My Notebook", "description": "Research notes"}' \ | |
| http://localhost:5055/api/notebooks | |
| # Upload file | |
| curl -X POST \ | |
| -H "Authorization: Bearer your_password" \ | |
| -F "file=@document.pdf" \ | |
| http://localhost:5055/api/sources/upload | |
| ``` | |
| ### Python | |
| ```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 get_notebooks(self): | |
| response = requests.get( | |
| f"{self.base_url}/api/notebooks", | |
| headers=self.headers | |
| ) | |
| return response.json() | |
| def create_notebook(self, name: str, description: str = None): | |
| response = requests.post( | |
| f"{self.base_url}/api/notebooks", | |
| headers=self.headers, | |
| json={"name": name, "description": description} | |
| ) | |
| return response.json() | |
| # Usage | |
| client = OpenNotebookClient("http://localhost:5055", "your_password") | |
| notebooks = client.get_notebooks() | |
| ``` | |
| ### JavaScript/TypeScript | |
| ```javascript | |
| const API_URL = 'http://localhost:5055'; | |
| const PASSWORD = 'your_password'; | |
| async function getNotebooks() { | |
| const response = await fetch(`${API_URL}/api/notebooks`, { | |
| headers: { | |
| 'Authorization': `Bearer ${PASSWORD}` | |
| } | |
| }); | |
| return response.json(); | |
| } | |
| ``` | |
| --- | |
| ## Production Hardening | |
| ### Docker Security | |
| ```yaml | |
| # Add to your docker-compose.yml (requires surrealdb service, see installation guide) | |
| services: | |
| open_notebook: | |
| image: lfnovo/open_notebook:v1-latest | |
| pull_policy: always | |
| ports: | |
| - "127.0.0.1:8502:8502" # Bind to localhost only | |
| environment: | |
| - OPEN_NOTEBOOK_PASSWORD=your_secure_password | |
| security_opt: | |
| - no-new-privileges:true | |
| deploy: | |
| resources: | |
| limits: | |
| memory: 2G | |
| cpus: "1.0" | |
| restart: always | |
| ``` | |
| ### Firewall Configuration | |
| ```bash | |
| # UFW (Ubuntu) | |
| sudo ufw allow ssh | |
| sudo ufw allow 80/tcp | |
| sudo ufw allow 443/tcp | |
| sudo ufw deny 8502/tcp # Block direct access | |
| sudo ufw deny 5055/tcp # Block direct API access | |
| sudo ufw enable | |
| # iptables | |
| iptables -A INPUT -p tcp --dport 22 -j ACCEPT | |
| iptables -A INPUT -p tcp --dport 80 -j ACCEPT | |
| iptables -A INPUT -p tcp --dport 443 -j ACCEPT | |
| iptables -A INPUT -p tcp --dport 8502 -j DROP | |
| iptables -A INPUT -p tcp --dport 5055 -j DROP | |
| ``` | |
| ### Reverse Proxy with SSL | |
| See [Reverse Proxy Configuration](reverse-proxy.md) for complete nginx/Caddy/Traefik setup with HTTPS. | |
| ### CORS Origins | |
| The API accepts cross-origin requests from any origin by default (`*`). This is convenient for development and diverse self-hosted setups, but it's not recommended for internet-facing production deployments because any website the user visits can issue authenticated cross-origin requests to your API. | |
| When `CORS_ORIGINS` is not set, the API logs a startup warning prompting you to configure it. | |
| **For production, set `CORS_ORIGINS` to your frontend's actual origin(s):** | |
| ```bash | |
| # Single origin | |
| CORS_ORIGINS=https://notebook.example.com | |
| # Multiple origins (comma-separated) | |
| CORS_ORIGINS=https://notebook.example.com,https://admin.example.com | |
| ``` | |
| **Guidelines:** | |
| - Always use HTTPS origins in production. | |
| - List only the exact origins that should be allowed to call the API. | |
| - Include the scheme and port (if non-default): `https://example.com`, `http://192.168.1.10:3000`. | |
| - Changes require an API restart to take effect. | |
| **Error responses** (401, 404, 500, etc.) also respect the configured origins — they only include `Access-Control-Allow-Origin` for allowed origins, so error bodies are not leaked cross-origin when `CORS_ORIGINS` is configured. | |
| --- | |
| ## Security Limitations | |
| Open Notebook's password protection provides **basic access control**, not enterprise-grade security: | |
| | Feature | Status | | |
| |---------|--------| | |
| | Password transmission | Plain text (use HTTPS!) | | |
| | Password storage | In memory | | |
| | User management | Single password for all | | |
| | Session timeout | None (until browser close) | | |
| | Rate limiting | None | | |
| | Audit logging | None | | |
| ### Risk Mitigation | |
| 1. **Always use HTTPS** - Encrypt traffic with TLS | |
| 2. **Strong passwords** - 20+ characters, complex | |
| 3. **Network security** - Firewall, VPN for sensitive deployments | |
| 4. **Regular updates** - Keep containers and dependencies updated | |
| 5. **Monitoring** - Check logs for suspicious activity | |
| 6. **Backups** - Regular backups of data | |
| --- | |
| ## Enterprise Considerations | |
| For deployments requiring advanced security: | |
| | Need | Solution | | |
| |------|----------| | |
| | SSO/OAuth | Implement OAuth2/SAML proxy | | |
| | Role-based access | Custom middleware | | |
| | Audit logging | Log aggregation service | | |
| | Rate limiting | API gateway or nginx | | |
| | Data encryption | Encrypt volumes at rest | | |
| | Network segmentation | Docker networks, VPC | | |
| --- | |
| ## Troubleshooting | |
| ### Password Not Working | |
| ```bash | |
| # Check env var is set | |
| docker exec open-notebook env | grep OPEN_NOTEBOOK_PASSWORD | |
| # Check logs | |
| docker logs open-notebook | grep -i auth | |
| # Test API directly | |
| curl -H "Authorization: Bearer your_password" \ | |
| http://localhost:5055/health | |
| ``` | |
| ### 401 Unauthorized Errors | |
| ```bash | |
| # Check header format | |
| curl -v -H "Authorization: Bearer your_password" \ | |
| http://localhost:5055/api/notebooks | |
| # Verify password matches | |
| echo "Password length: $(echo -n $OPEN_NOTEBOOK_PASSWORD | wc -c)" | |
| ``` | |
| ### Cannot Access After Setting Password | |
| 1. Clear browser cache and cookies | |
| 2. Try incognito/private mode | |
| 3. Check browser console for errors | |
| 4. Verify password is correct in environment | |
| ### Security Testing | |
| ```bash | |
| # Without password (should fail) | |
| curl http://localhost:5055/api/notebooks | |
| # Expected: {"detail": "Missing authorization header"} | |
| # With correct password (should succeed) | |
| curl -H "Authorization: Bearer your_password" \ | |
| http://localhost:5055/api/notebooks | |
| # Health check (should work without password) | |
| curl http://localhost:5055/health | |
| ``` | |
| --- | |
| ## Reporting Security Issues | |
| If you discover security vulnerabilities: | |
| 1. **Do NOT open public issues** | |
| 2. Contact maintainers directly | |
| 3. Provide detailed information | |
| 4. Allow time for fixes before disclosure | |
| --- | |
| ## Related | |
| - **[Reverse Proxy](reverse-proxy.md)** - HTTPS and SSL setup | |
| - **[Advanced Configuration](advanced.md)** - Ports, timeouts, and SSL settings | |
| - **[Environment Reference](environment-reference.md)** - All configuration options | |