13 KiB
Security Configuration
Open Notebook includes optional password protection and security features for users who need to deploy their instances publicly or in shared environments.
🔒 Password Protection
When to Use Password Protection
Password protection is recommended for:
- Public cloud deployments - PikaPods, Railway, DigitalOcean, AWS, etc.
- Shared network environments - Corporate networks, shared servers
- Team deployments - Multiple users accessing the same instance
- Production environments - Any deployment accessible beyond localhost
When NOT to Use Password Protection
Skip password protection for:
- Local development - Running on your personal machine
- Private networks - Secure, isolated network environments
- Single-user setups - Only you have access to the machine
- Testing environments - Temporary or development instances
🚀 Quick Setup
Docker Deployment
For Docker deployments, add the password to your environment:
# docker-compose.yml
services:
open_notebook:
image: lfnovo/open_notebook:v1-latest-single
ports:
- "8502:8502"
environment:
- OPENAI_API_KEY=your_openai_key
- OPEN_NOTEBOOK_PASSWORD=your_secure_password
volumes:
- ./notebook_data:/app/data
restart: always
Or using a .env file:
# .env file
OPENAI_API_KEY=your_openai_key
OPEN_NOTEBOOK_PASSWORD=your_secure_password
Development Setup
For development installations, add to your .env file:
# .env file in project root
OPEN_NOTEBOOK_PASSWORD=your_secure_password
🔐 Password Requirements
Choosing a Secure Password
- Length: Minimum 12 characters, preferably 20+
- Complexity: Mix of uppercase, lowercase, numbers, and symbols
- Uniqueness: Don't reuse passwords from other services
- Avoid: Common words, personal information, predictable patterns
Password Examples
# Good passwords
OPEN_NOTEBOOK_PASSWORD=MySecure2024!Research#Tool
OPEN_NOTEBOOK_PASSWORD=Notebook$Dev$2024$Strong!
# Bad passwords (don't use these)
OPEN_NOTEBOOK_PASSWORD=password123
OPEN_NOTEBOOK_PASSWORD=opennotebook
OPEN_NOTEBOOK_PASSWORD=admin
Password Management
- Use a password manager to generate and store the password
- Document the password in your team's secure password vault
- Rotate passwords regularly for production deployments
- Share securely - Never send passwords via email or chat
🛡️ How Security Works
React frontend Protection
When password protection is enabled:
- Login form appears on first visit
- Session storage - Password stored in browser session
- Persistent login - Users stay logged in until browser closure
- No logout button - Clear browser data to log out
API Protection
All API endpoints require authentication:
# API calls require Authorization header
curl -H "Authorization: Bearer your_password" \
http://localhost:5055/api/notebooks
Excluded Endpoints
These endpoints work without authentication:
- Health check:
/health- System status - API documentation:
/docs- OpenAPI documentation - OpenAPI spec:
/openapi.json- API schema
🔧 Configuration Examples
Single Container with Security
# docker-compose.single.yml
services:
open_notebook_single:
image: lfnovo/open_notebook:v1-latest-single
ports:
- "8502:8502"
- "5055:5055"
environment:
- OPENAI_API_KEY=sk-your-openai-key
- OPEN_NOTEBOOK_PASSWORD=your_secure_password
- ANTHROPIC_API_KEY=sk-ant-your-anthropic-key
volumes:
- ./notebook_data:/app/data
- ./surreal_single_data:/mydata
restart: always
Multi-Container with Security
# docker-compose.yml
services:
surrealdb:
image: surrealdb/surrealdb:v1-latest
ports:
- "127.0.0.1:8000:8000" # Bind to localhost only
command: start --log warn --user root --pass root file:///mydata/database.db
volumes:
- ./surreal_data:/mydata
restart: always
open_notebook:
image: lfnovo/open_notebook:v1-latest
ports:
- "8502:8502"
- "5055:5055"
environment:
- OPENAI_API_KEY=sk-your-openai-key
- OPEN_NOTEBOOK_PASSWORD=your_secure_password
- SURREAL_URL=ws://surrealdb:8000/rpc
- SURREAL_USER=root
- SURREAL_PASSWORD=root
volumes:
- ./notebook_data:/app/data
depends_on:
- surrealdb
restart: always
Development with Security
# .env file for development
OPEN_NOTEBOOK_PASSWORD=dev_password_2024
# Database
SURREAL_URL=ws://localhost:8000/rpc
SURREAL_USER=root
SURREAL_PASSWORD=root
SURREAL_NAMESPACE=open_notebook
SURREAL_DATABASE=development
# AI Providers
OPENAI_API_KEY=sk-your-openai-key
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key
🌐 Production Security
HTTPS/TLS Configuration
Always use HTTPS in production. Here's an nginx reverse proxy example:
# /etc/nginx/sites-available/open-notebook
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
# React frontend
location / {
proxy_pass http://127.0.0.1:8502;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# API endpoints
location /api/ {
proxy_pass http://127.0.0.1:5055;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Firewall Configuration
Configure your firewall to restrict access:
# UFW (Ubuntu)
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw deny 8502/tcp # Block direct access to Next.js
sudo ufw deny 5055/tcp # Block direct access to API
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
Docker Security
# Production docker-compose.yml with security
services:
open_notebook:
image: lfnovo/open_notebook:v1-latest
ports:
- "127.0.0.1:8502:8502" # Bind to localhost only
- "127.0.0.1:5055:5055"
environment:
- OPEN_NOTEBOOK_PASSWORD=your_secure_password
volumes:
- ./notebook_data:/app/data
restart: always
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
- /var/tmp
deploy:
resources:
limits:
memory: 2G
cpus: "1.0"
🔍 API Authentication
Making Authenticated API Calls
# Get all notebooks
curl -H "Authorization: Bearer your_password" \
http://localhost:5055/api/notebooks
# Create a new 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 a file
curl -X POST \
-H "Authorization: Bearer your_password" \
-F "file=@document.pdf" \
http://localhost:5055/api/sources/upload
Python API Client
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):
data = {"name": name, "description": description}
response = requests.post(
f"{self.base_url}/api/notebooks",
headers=self.headers,
json=data
)
return response.json()
# Usage
client = OpenNotebookClient("http://localhost:5055", "your_password")
notebooks = client.get_notebooks()
🚨 Security Considerations
Important Limitations
Open Notebook's password protection provides basic access control, not enterprise-grade security:
- Plain text transmission - Passwords sent over HTTP (use HTTPS)
- No password hashing - Passwords stored in memory as plain text
- No user management - Single password for all users
- No session timeout - Sessions persist until browser closure
- No rate limiting - No protection against brute force attacks
- No audit logging - No security event logging
Risk Mitigation
- Use HTTPS - Always encrypt traffic with TLS
- Strong passwords - Use complex, unique passwords
- Network security - Implement proper firewall rules
- Regular updates - Keep containers and dependencies updated
- Monitoring - Monitor access logs and system resources
- Backup strategy - Regular backups of data and configurations
Enterprise Considerations
For enterprise deployments requiring advanced security:
- SSO integration - Consider implementing OAuth2/SAML
- Role-based access - Implement user roles and permissions
- Audit logging - Track all user actions and API calls
- Rate limiting - Implement API rate limiting
- Database encryption - Encrypt data at rest
- Network segmentation - Isolate services in secure networks
🔧 Troubleshooting
Common Security Issues
Password Not Working
# Check environment variable is set
docker compose exec open_notebook env | grep OPEN_NOTEBOOK_PASSWORD
# Check container logs
docker compose logs open_notebook | grep -i auth
# Test API directly
curl -H "Authorization: Bearer your_password" \
http://localhost:5055/health
UI Shows Login Form but API Doesn't
# Environment variable might not be set for API
docker compose exec open_notebook env | grep OPEN_NOTEBOOK_PASSWORD
# Restart services
docker compose restart
# Check both services are using the same password
docker compose logs | grep -i password
401 Unauthorized Errors
# Check authorization header format
curl -v -H "Authorization: Bearer your_password" \
http://localhost:5055/api/notebooks
# Verify password matches environment variable
echo $OPEN_NOTEBOOK_PASSWORD
# Check for special characters in password
echo "Password contains: $(echo $OPEN_NOTEBOOK_PASSWORD | wc -c) characters"
Cannot Access After Setting Password
# Clear browser cache and cookies
# Try incognito/private mode
# Check browser console for errors
# Verify password is correct
Security Testing
# Test without password (should fail)
curl http://localhost:5055/api/notebooks
# Test with correct password (should succeed)
curl -H "Authorization: Bearer your_password" \
http://localhost:5055/api/notebooks
# Test health endpoint (should work without password)
curl http://localhost:5055/health
# Test documentation (should work without password)
curl http://localhost:5055/docs
📞 Getting Help
Security Issues
If you discover security vulnerabilities:
- Do not open public issues for security problems
- Contact the maintainer directly via email
- Provide detailed information about the vulnerability
- Allow time for fixes before public disclosure
Community Support
For security configuration help:
- Discord Server - Real-time help
- GitHub Issues - Configuration problems
- Documentation - Additional guides
Best Practices
- Test security thoroughly before production deployment
- Monitor logs regularly for suspicious activity
- Keep updated with security patches and updates
- Follow principle of least privilege in network configuration
- Regular security reviews of your deployment
Ready to secure your deployment? Start with the Quick Setup section above and always use HTTPS in production!