mirror of
https://github.com/apidoorman/doorman.git
synced 2026-02-07 09:38:50 -06:00
202 lines
8.6 KiB
Plaintext
202 lines
8.6 KiB
Plaintext
# ============================================================================
|
|
# ENVIRONMENT CONFIGURATION
|
|
# ============================================================================
|
|
# Set to 'production' to enable strict security validations
|
|
# Development: ENV=development (or leave unset)
|
|
# Production: ENV=production (enforces all security requirements below)
|
|
ENV=development
|
|
|
|
DOORMAN_ADMIN_EMAIL=please-change-me
|
|
DOORMAN_ADMIN_PASSWORD=please-change-me
|
|
|
|
# ============================================================================
|
|
# DATABASE & CACHE CONFIGURATION
|
|
# ============================================================================
|
|
# Unified cache/DB mode
|
|
# - MEM: In-memory only (single-node, requires MEM_ENCRYPTION_KEY in production)
|
|
# - REDIS: Use Redis for caching and MongoDB for persistence (HA-ready)
|
|
# - EXTERNAL: Use MongoDB for everything (HA-ready)
|
|
MEM_OR_EXTERNAL=MEM
|
|
# Dumps path (memory-only mode)
|
|
MEM_DUMP_PATH=generated/memory_dump.bin
|
|
|
|
# MongoDB Configuration (REQUIRED when MEM_OR_EXTERNAL=REDIS or EXTERNAL)
|
|
MONGO_DB_HOSTS=localhost:27017
|
|
MONGO_REPLICA_SET_NAME=rs0
|
|
MONGO_DB_USER=doorman_admin
|
|
MONGO_DB_PASSWORD=
|
|
|
|
# Redis Configuration (REQUIRED for production HA deployments when MEM_OR_EXTERNAL=REDIS)
|
|
REDIS_HOST=localhost
|
|
REDIS_PORT=6379
|
|
REDIS_DB=0
|
|
REDIS_PASSWORD=
|
|
|
|
# ============================================================================
|
|
# PRODUCTION SECRET MANAGEMENT
|
|
# ============================================================================
|
|
# CRITICAL: Change ALL secrets below before production deployment!
|
|
# Generate strong secrets: openssl rand -hex 32
|
|
|
|
# JWT_SECRET_KEY: Used to sign JWT tokens (REQUIRED)
|
|
# - Production: MUST be changed from default
|
|
# - Must be 32+ characters, cryptographically random
|
|
# - NEVER commit production secrets to version control
|
|
# Generate: openssl rand -base64 48
|
|
JWT_SECRET_KEY=please-change-me
|
|
|
|
# TOKEN_ENCRYPTION_KEY: Encrypts API keys at rest (RECOMMENDED for production)
|
|
# - 32+ characters required
|
|
# - If unset, API keys stored in plaintext in database
|
|
# Generate: openssl rand -hex 32
|
|
TOKEN_ENCRYPTION_KEY=
|
|
|
|
# MEM_ENCRYPTION_KEY: Encrypts memory dumps (REQUIRED in production with MEM mode)
|
|
# - 32+ characters required
|
|
# - Protects sensitive data in memory dump files
|
|
# Generate: openssl rand -hex 32
|
|
MEM_ENCRYPTION_KEY=
|
|
|
|
# Access/refresh token expiry (defaults shown)
|
|
AUTH_EXPIRE_TIME=30
|
|
AUTH_EXPIRE_TIME_FREQ=minutes
|
|
AUTH_REFRESH_EXPIRE_TIME=7
|
|
AUTH_REFRESH_EXPIRE_FREQ=days
|
|
|
|
# ============================================================================
|
|
# HTTPS SECURITY
|
|
# ============================================================================
|
|
# HTTPS_ONLY: Enforce HTTPS, CSRF validation, and set Secure cookies (REQUIRED in production)
|
|
# - true: TLS terminated at reverse proxy (Nginx, Traefik, ALB, etc.)
|
|
# - false: Allows HTTP (development only)
|
|
HTTPS_ONLY=true
|
|
|
|
# COOKIE_DOMAIN: Base domain for authentication cookies
|
|
# - If set: Cookies sent WITH domain attribute for subdomain sharing (e.g., *.example.com)
|
|
# - Also sent WITHOUT domain attribute for exact domain match (dual-cookie strategy)
|
|
# - For SSO: Set to match SSO provider's domain scope
|
|
# - For reverse proxy/load balancer: Set to base domain (e.g., "example.com" not "api.example.com")
|
|
# - For single-domain: Leave unset or set to exact domain
|
|
# - Leave blank for development/localhost (no subdomain sharing)
|
|
# Impact: Cookies are duplicated (with/without domain) which doubles cookie size; consider for large JWTs
|
|
COOKIE_DOMAIN=localhost
|
|
|
|
# COOKIE_SAMESITE: SameSite cookie attribute (Strict, Lax, or None)
|
|
# - Strict: Cookie only sent to same-site requests (recommended for production)
|
|
# - Lax: Cookie sent on top-level navigation (useful for SSO redirects)
|
|
# - None: Cookie sent on all requests (requires HTTPS_ONLY=true)
|
|
COOKIE_SAMESITE=Strict
|
|
|
|
# COOKIE_SECURE: Force the Secure attribute on/off for cookies (optional)
|
|
# - When unset: Secure is derived automatically from HTTPS_ONLY or the
|
|
# X-Forwarded-Proto=https header set by your reverse proxy.
|
|
# - Set to true to always mark cookies Secure; set to false to force non-Secure
|
|
# cookies (not recommended in production).
|
|
# - You typically do NOT need to set this if your proxy forwards X-Forwarded-Proto.
|
|
# Example: COOKIE_SECURE=true
|
|
# COOKIE_SECURE=
|
|
|
|
# Reverse proxy note:
|
|
# - If running behind a TLS-terminating proxy, ensure it forwards
|
|
# X-Forwarded-Proto=https so the server can auto-mark cookies Secure and
|
|
# enforce CSRF correctly when HTTPS_ONLY=true.
|
|
|
|
# Optional: Custom Content Security Policy (defaults to restrictive policy)
|
|
# CONTENT_SECURITY_POLICY=default-src 'self'; script-src 'self' 'unsafe-inline'
|
|
|
|
# HTTP Client Connection Pooling (httpx)
|
|
ENABLE_HTTPX_CLIENT_CACHE=true
|
|
HTTP_MAX_CONNECTIONS=100
|
|
HTTP_MAX_KEEPALIVE=50
|
|
HTTP_KEEPALIVE_EXPIRY=30.0
|
|
|
|
# Timeouts (seconds) - Prevents indefinite hangs
|
|
# CRITICAL: Adjust these based on expected upstream response times
|
|
HTTP_CONNECT_TIMEOUT=5.0 # Time to establish connection (5s recommended)
|
|
HTTP_READ_TIMEOUT=30.0 # Time to read response body (30s default, increase for slow APIs)
|
|
HTTP_WRITE_TIMEOUT=30.0 # Time to send request body (30s default)
|
|
HTTP_TIMEOUT=30.0 # Connection pool timeout (time to acquire connection)
|
|
# Note: Timeout errors return 504 Gateway Timeout to clients
|
|
|
|
# Enable HTTP/2 (default: false)
|
|
HTTP_ENABLE_HTTP2=false
|
|
|
|
# Security
|
|
# Max request body size in bytes (default: 1MB)
|
|
MAX_BODY_SIZE_BYTES=1048576
|
|
# Per-API type overrides (optional)
|
|
# MAX_BODY_SIZE_BYTES_REST=1048576
|
|
# MAX_BODY_SIZE_BYTES_SOAP=2097152
|
|
# MAX_BODY_SIZE_BYTES_GRAPHQL=524288
|
|
# MAX_BODY_SIZE_BYTES_GRPC=1048576
|
|
# Allow localhost to bypass IP filters when no X-Forwarded-For header present
|
|
LOCAL_HOST_IP_BYPASS=true
|
|
|
|
# Advanced compatibility toggles (for CI/Python 3.13 environments)
|
|
# Set to 'true' only if you experience middleware/ASGI issues during tests.
|
|
# - DISABLE_PLATFORM_CHUNKED_WRAP: skip low-level chunked-body wrapping on /platform/*
|
|
# - DISABLE_PLATFORM_CORS_ASGI: bypass ASGI CORS shim for /platform/*
|
|
# - DISABLE_BODY_SIZE_LIMIT: disable body-size limit middleware entirely
|
|
DISABLE_PLATFORM_CHUNKED_WRAP=false
|
|
DISABLE_PLATFORM_CORS_ASGI=false
|
|
DISABLE_BODY_SIZE_LIMIT=false
|
|
|
|
# Comma-separated paths to skip body size enforcement (exact match or suffix *)
|
|
# Useful for avoiding transport edge-cases on specific endpoints during CI.
|
|
# Example: BODY_LIMIT_EXCLUDE_PATHS=/platform/security/settings
|
|
BODY_LIMIT_EXCLUDE_PATHS=
|
|
|
|
# IP-based rate limiting for login endpoint
|
|
# Set very high to effectively disable by default (development-friendly)
|
|
# PRODUCTION: Reduce these values to prevent brute force attacks
|
|
# Example for stricter limits: LOGIN_IP_RATE_LIMIT=5, LOGIN_IP_RATE_WINDOW=300 (5 attempts per 5 minutes)
|
|
LOGIN_IP_RATE_LIMIT=1000000
|
|
LOGIN_IP_RATE_WINDOW=60
|
|
|
|
# Cache Configuration (Memory mode only)
|
|
# CACHE_MAX_SIZE: Maximum number of entries in memory cache (default: 10000)
|
|
# When limit is reached, least recently used (LRU) entries are evicted
|
|
# Prevents unbounded memory growth and OOM crashes
|
|
CACHE_MAX_SIZE=10000
|
|
|
|
# Response Compression
|
|
# COMPRESSION_ENABLED: Enable gzip compression for responses (default: true)
|
|
# Significantly reduces bandwidth usage (typically 60-80% for JSON/XML)
|
|
# Set to false to disable compression (useful for debugging or if using external compression)
|
|
COMPRESSION_ENABLED=true
|
|
# COMPRESSION_MINIMUM_SIZE: Only compress responses larger than this size in bytes (default: 500)
|
|
# Small responses may not benefit from compression overhead
|
|
COMPRESSION_MINIMUM_SIZE=500
|
|
# COMPRESSION_LEVEL: Compression level 1-9 (default: 1)
|
|
# 1 = fastest/best efficiency, 9 = slowest/slightly better compression
|
|
# Recommended: 1 (best efficiency - 2x faster than 6, same compression ratio)
|
|
# Alternative: 4 (balanced), 6 (conservative), 9 (overkill - not worth it)
|
|
# Benchmark shows Level 1 achieves 90.4% compression vs 90.3% at Level 9
|
|
COMPRESSION_LEVEL=1
|
|
|
|
# Logging
|
|
# Format: json or plain
|
|
LOG_FORMAT=plain
|
|
# Optional: custom logs directory (defaults to backend-services/platform-logs)
|
|
# LOGS_DIR=/path/to/logs
|
|
|
|
# App
|
|
PORT=3001 # Backend API port
|
|
WEB_PORT=3000 # Frontend web UI port
|
|
THREADS=1
|
|
DEV_RELOAD=false
|
|
PID_FILE=doorman.pid
|
|
|
|
# ============================================================================
|
|
# FRONTEND GATEWAY CONFIGURATION
|
|
# ============================================================================
|
|
# Backend Gateway URL for the web client
|
|
# - Local development (http://localhost:{port}): http://localhost:3001
|
|
# - Production with reverse proxy:
|
|
# - Same origin (via reverse proxy): leave unset
|
|
# - Separate API domain: https://api.yourdomain.com
|
|
NEXT_PUBLIC_GATEWAY_URL=http://localhost:3001
|
|
|
|
# Uses gql.Client when this flag is true and an AIOHTTPTransport is importable
|
|
DOORMAN_ENABLE_GQL_CLIENT=True
|