# ============================================================================ # Application Configuration # ============================================================================ # Environment: development, production # - development: Local development with debug logging and test API keys (test_sk_*) # - production: Live production environment with live API keys (live_sk_*) APP_ENVIRONMENT=development APP_VERSION=0.1.0 # JWT Secret: Used for signing JWT tokens for user authentication # SECURITY CRITICAL: This MUST be changed in production! # - Minimum length: 32 characters (256 bits) # - Recommended length: 64 characters (512 bits) # - Must be cryptographically random # - Never commit production secrets to version control # # Generate a secure secret: # openssl rand -base64 64 # # WARNING: The application will refuse to start in production with: # - Default/placeholder values (containing "change", "sample", etc.) # - Common weak secrets ("secret", "password", "12345", etc.) # - Secrets shorter than 32 characters # # For development ONLY (this value will trigger a warning): APP_JWT_SECRET=change-me-in-production-use-a-long-random-string # HTTP Server Configuration SERVER_HOST=0.0.0.0 SERVER_PORT=8000 # ============================================================================ # Security Configuration # ============================================================================ # CORS Allowed Origins: Comma-separated list of allowed frontend origins # IMPORTANT: Configure this in production to allow your frontend domain(s) # # Example for production: # SECURITY_CORS_ALLOWED_ORIGINS=https://getmaplepress.com,https://www.getmaplepress.com # # For development: # - Localhost origins (http://localhost:5173, etc.) are automatically allowed # - Leave empty or add additional development origins if needed # # Security notes: # - Use HTTPS in production (https://, not http://) # - Include both www and non-www versions if needed # - Do NOT use wildcards (*) - specify exact origins # SECURITY_CORS_ALLOWED_ORIGINS= # ============================================================================ # Cassandra Database Configuration # ============================================================================ # Default: Docker development (task dev) # For running OUTSIDE Docker (go run main.go daemon): # Change to: DATABASE_HOSTS=localhost DATABASE_HOSTS=cassandra-1,cassandra-2,cassandra-3 DATABASE_KEYSPACE=maplepress DATABASE_CONSISTENCY=QUORUM DATABASE_REPLICATION=3 DATABASE_MIGRATIONS_PATH=file://migrations # ============================================================================ # Redis Cache Configuration # ============================================================================ # Default: Docker development (task dev) # For running OUTSIDE Docker (go run main.go daemon): # Change to: CACHE_HOST=localhost CACHE_HOST=redis CACHE_PORT=6379 CACHE_PASSWORD= CACHE_DB=0 # ============================================================================ # AWS S3 Configuration (Optional - for object storage) # ============================================================================ # Default: Docker development (task dev) with SeaweedFS # For running OUTSIDE Docker with SeaweedFS: # Change to: AWS_ENDPOINT=http://localhost:8333 # For AWS S3: # AWS_ENDPOINT can be left empty or set to https://s3.amazonaws.com # For S3-compatible services (DigitalOcean Spaces, MinIO, etc.): # AWS_ENDPOINT should be the service endpoint # # SeaweedFS development settings (accepts any credentials): AWS_ACCESS_KEY=any AWS_SECRET_KEY=any AWS_ENDPOINT=http://seaweedfs:8333 AWS_REGION=us-east-1 AWS_BUCKET_NAME=maplepress # ============================================================================ # Logger Configuration # ============================================================================ # Levels: debug, info, warn, error # Formats: json, console LOGGER_LEVEL=debug LOGGER_FORMAT=console # ============================================================================ # Meilisearch Configuration # ============================================================================ # Default: Docker development (task dev) # For running OUTSIDE Docker: # Change to: MEILISEARCH_HOST=http://localhost:7700 MEILISEARCH_HOST=http://meilisearch:7700 MEILISEARCH_API_KEY=mapleopentech-dev-master-key-change-in-production MEILISEARCH_INDEX_PREFIX=site_ # ============================================================================ # Rate Limiting Configuration # ============================================================================ # Four-tier rate limiting architecture for comprehensive protection # Uses Redis for distributed tracking across multiple instances # All rate limiters implement fail-open design (allow on Redis failure) # ============================================================================ # 1. Registration Rate Limiter (CWE-307: Account Creation Protection) # ============================================================================ # Protects against automated account creation, bot signups, and account farming # Strategy: IP-based limiting # Recommended: Very strict (prevents abuse while allowing legitimate signups) RATELIMIT_REGISTRATION_ENABLED=true # Maximum number of registration attempts per IP address RATELIMIT_REGISTRATION_MAX_REQUESTS=10 # Time window for rate limiting (Go duration format) # Examples: "1h" (default), "30m", "24h" RATELIMIT_REGISTRATION_WINDOW=1h # ============================================================================ # 2. Login Rate Limiter (CWE-307: Brute Force Protection) # ============================================================================ # Dual protection: IP-based rate limiting + account lockout mechanism # Protects against credential stuffing, brute force, and password guessing attacks # Strategy: Dual (IP-based for distributed attacks + account-based for targeted attacks) # Recommended: Moderate (balance security with user experience) RATELIMIT_LOGIN_ENABLED=true # Maximum login attempts per IP address RATELIMIT_LOGIN_MAX_ATTEMPTS_PER_IP=10 # Time window for IP-based rate limiting # Examples: "15m" (default), "10m", "30m" RATELIMIT_LOGIN_IP_WINDOW=15m # Maximum failed attempts before account lockout RATELIMIT_LOGIN_MAX_FAILED_ATTEMPTS_PER_ACCOUNT=10 # Account lockout duration after too many failed attempts # Examples: "30m" (default), "1h", "15m" RATELIMIT_LOGIN_ACCOUNT_LOCKOUT_DURATION=30m # ============================================================================ # 3. Generic CRUD Endpoints Rate Limiter (CWE-770: Resource Exhaustion Protection) # ============================================================================ # Protects authenticated CRUD operations: tenant/user/site management, admin endpoints # Strategy: User-based (authenticated user ID from JWT) # Recommended: Lenient (allow normal operations, prevent resource exhaustion) # Applies to: /api/v1/tenants, /api/v1/users, /api/v1/sites, /api/v1/admin/*, /api/v1/me, /api/v1/hello RATELIMIT_GENERIC_ENABLED=true # Maximum requests per authenticated user per window # Default: 100 requests per hour (1.67 req/min) # Lenient for normal admin panel usage, mobile apps, and automation scripts RATELIMIT_GENERIC_MAX_REQUESTS=100 # Time window for rate limiting # Examples: "1h" (default), "30m", "2h" RATELIMIT_GENERIC_WINDOW=1h # ============================================================================ # 4. Plugin API Rate Limiter (CWE-770: DoS Prevention for Core Business) # ============================================================================ # Protects WordPress plugin API endpoints - CORE BUSINESS ENDPOINTS # Strategy: Site-based (API key → site_id) # Recommended: Very lenient (supports high-volume legitimate traffic) # Applies to: /api/v1/plugin/* (status, sync, search, delete, pages) # # IMPORTANT: These are revenue-generating endpoints. Limits should be high enough # to support legitimate WordPress sites with: # - Large page counts (1000+ pages) # - Frequent content updates # - Search-heavy workloads # - Bulk operations RATELIMIT_PLUGIN_API_ENABLED=true # Maximum requests per site (API key) per window # Default: 10000 requests per hour (166.67 req/min, ~2.78 req/sec) # Usage-based billing: Very generous limits for anti-abuse only # This supports high-volume WordPress sites (240K/day, 7.2M/month) # Limits only hit during abuse scenarios or plugin bugs (infinite loops) RATELIMIT_PLUGIN_API_MAX_REQUESTS=10000 # Time window for rate limiting # Examples: "1h" (default), "30m", "2h" RATELIMIT_PLUGIN_API_WINDOW=1h # ============================================================================ # Scheduler Configuration # ============================================================================ # Automated quota reset scheduler (cron-based) # Enable/disable monthly quota resets SCHEDULER_QUOTA_RESET_ENABLED=true # Cron schedule for quota resets (default: 1st of month at midnight) # Format: minute hour day month weekday # Examples: # "0 0 1 * *" = 1st of month at midnight (default) # "0 2 * * *" = Every day at 2 AM (testing) # "*/5 * * * *" = Every 5 minutes (development) SCHEDULER_QUOTA_RESET_SCHEDULE="0 0 1 * *" # ============================================================================ # Leader Election Configuration # ============================================================================ # Distributed leader election for multi-instance deployments # Uses Redis for coordination - ensures only one instance runs scheduled tasks # Auto-configures instance identity (hostname + random suffix) # # Enable/disable leader election LEADER_ELECTION_ENABLED=true # Lock TTL: How long the leader lock lasts before expiring (Go duration) # The leader must renew before this expires. Default: 10s # Recommended: 10-30s LEADER_ELECTION_LOCK_TTL=10s # Heartbeat interval: How often the leader renews its lock (Go duration) # Should be significantly less than LockTTL (e.g., LockTTL / 3). Default: 3s # Recommended: LockTTL / 3 LEADER_ELECTION_HEARTBEAT_INTERVAL=3s # Retry interval: How often followers check for leadership opportunity (Go duration) # Default: 2s. Recommended: 1-5s LEADER_ELECTION_RETRY_INTERVAL=2s