Spaces:
Sleeping
Sleeping
Commit ·
d6ffecb
1
Parent(s): e5e8519
Config: Update production configuration with environment variables
Browse filesChanges:
- Updated config.py to use environment variables
- Set DEBUG=False as default (production-safe)
- CORS_ORIGINS now configurable via environment
- Added .env.production.example template
Security improvements:
- DEBUG disabled by default (prevents info leaks)
- CORS restricted by default
- All sensitive config via environment variables
Production deployment:
1. Copy .env.production.example to .env
2. Update CORS_ORIGINS with your domain
3. Deploy with DEBUG=False
Closes #44
- .env.production.example +25 -0
- backend/core/config.py +38 -24
- backend/main.py +6 -6
.env.production.example
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# VeriFile-X Production Configuration
|
| 2 |
+
# Copy this file to .env in production and update values
|
| 3 |
+
|
| 4 |
+
# CRITICAL: Set these for production!
|
| 5 |
+
DEBUG=False
|
| 6 |
+
CORS_ORIGINS=https://verifile-x.com,https://www.verifile-x.com
|
| 7 |
+
|
| 8 |
+
# Rate limiting
|
| 9 |
+
RATE_LIMIT_PER_MINUTE=10
|
| 10 |
+
|
| 11 |
+
# File limits
|
| 12 |
+
MAX_FILE_SIZE_MB=50
|
| 13 |
+
MAX_ANALYSIS_SIZE_MB=10
|
| 14 |
+
|
| 15 |
+
# Cache
|
| 16 |
+
CACHE_TTL_MINUTES=60
|
| 17 |
+
MAX_CACHE_SIZE=500
|
| 18 |
+
|
| 19 |
+
# Logging (use INFO or WARNING in production)
|
| 20 |
+
LOG_LEVEL=INFO
|
| 21 |
+
|
| 22 |
+
# Server (for Gunicorn/Uvicorn)
|
| 23 |
+
HOST=0.0.0.0
|
| 24 |
+
PORT=8000
|
| 25 |
+
WORKERS=4
|
backend/core/config.py
CHANGED
|
@@ -1,40 +1,54 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Application configuration management.
|
| 3 |
-
Uses environment variables for security-sensitive settings.
|
| 4 |
-
"""
|
| 5 |
from pydantic_settings import BaseSettings
|
| 6 |
-
from typing import
|
| 7 |
-
|
| 8 |
|
| 9 |
class Settings(BaseSettings):
|
| 10 |
"""
|
| 11 |
-
Application settings
|
| 12 |
|
| 13 |
-
|
|
|
|
| 14 |
"""
|
| 15 |
-
# API Settings
|
| 16 |
-
API_TITLE: str = "VeriFile-X API"
|
| 17 |
-
API_VERSION: str = "0.1.0"
|
| 18 |
-
API_DESCRIPTION: str = "Privacy-preserving digital forensics platform"
|
| 19 |
|
| 20 |
-
#
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
-
#
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
ALLOWED_VIDEO_TYPES: list = ["video/mp4", "video/mpeg"]
|
| 29 |
-
ALLOWED_DOC_TYPES: list = ["application/pdf"]
|
| 30 |
|
| 31 |
-
#
|
| 32 |
-
|
| 33 |
|
| 34 |
class Config:
|
| 35 |
env_file = ".env"
|
| 36 |
case_sensitive = True
|
| 37 |
|
| 38 |
|
| 39 |
-
# Singleton pattern - one instance across app
|
| 40 |
settings = Settings()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from pydantic_settings import BaseSettings
|
| 2 |
+
from typing import List
|
| 3 |
+
import os
|
| 4 |
|
| 5 |
class Settings(BaseSettings):
|
| 6 |
"""
|
| 7 |
+
Application settings with environment variable overrides.
|
| 8 |
|
| 9 |
+
Environment variables take precedence over defaults.
|
| 10 |
+
For production, create a .env file based on .env.example
|
| 11 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
+
# CORS Configuration
|
| 14 |
+
# Development default: localhost only
|
| 15 |
+
# Production: Set via CORS_ORIGINS environment variable
|
| 16 |
+
CORS_ORIGINS: str = os.getenv(
|
| 17 |
+
"CORS_ORIGINS",
|
| 18 |
+
"http://localhost:3000" # Development default
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
@property
|
| 22 |
+
def cors_origins_list(self) -> List[str]:
|
| 23 |
+
"""Parse CORS_ORIGINS into a list."""
|
| 24 |
+
return [origin.strip() for origin in self.CORS_ORIGINS.split(",")]
|
| 25 |
+
|
| 26 |
+
# Debug Mode
|
| 27 |
+
# IMPORTANT: Set DEBUG=False in production!
|
| 28 |
+
DEBUG: bool = os.getenv("DEBUG", "False").lower() == "true"
|
| 29 |
+
|
| 30 |
+
# API Configuration
|
| 31 |
+
API_V1_PREFIX: str = "/api/v1"
|
| 32 |
+
PROJECT_NAME: str = "VeriFile-X"
|
| 33 |
+
VERSION: str = "6.0.0"
|
| 34 |
+
|
| 35 |
+
# Rate Limiting
|
| 36 |
+
RATE_LIMIT_PER_MINUTE: int = int(os.getenv("RATE_LIMIT_PER_MINUTE", "10"))
|
| 37 |
+
|
| 38 |
+
# File Upload Limits
|
| 39 |
+
MAX_FILE_SIZE_MB: int = int(os.getenv("MAX_FILE_SIZE_MB", "50"))
|
| 40 |
+
MAX_ANALYSIS_SIZE_MB: int = int(os.getenv("MAX_ANALYSIS_SIZE_MB", "10"))
|
| 41 |
|
| 42 |
+
# Cache Settings
|
| 43 |
+
CACHE_TTL_MINUTES: int = int(os.getenv("CACHE_TTL_MINUTES", "60"))
|
| 44 |
+
MAX_CACHE_SIZE: int = int(os.getenv("MAX_CACHE_SIZE", "500"))
|
|
|
|
|
|
|
| 45 |
|
| 46 |
+
# Logging
|
| 47 |
+
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
|
| 48 |
|
| 49 |
class Config:
|
| 50 |
env_file = ".env"
|
| 51 |
case_sensitive = True
|
| 52 |
|
| 53 |
|
|
|
|
| 54 |
settings = Settings()
|
backend/main.py
CHANGED
|
@@ -33,25 +33,25 @@ async def lifespan(app: FastAPI):
|
|
| 33 |
|
| 34 |
|
| 35 |
app = FastAPI(
|
| 36 |
-
title=settings.
|
| 37 |
-
version=settings.
|
| 38 |
-
|
| 39 |
-
lifespan=lifespan,
|
| 40 |
)
|
| 41 |
|
| 42 |
app.state.limiter = limiter
|
| 43 |
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
| 44 |
app.add_middleware(SlowAPIMiddleware)
|
| 45 |
|
| 46 |
-
# CORS
|
| 47 |
app.add_middleware(
|
| 48 |
CORSMiddleware,
|
| 49 |
-
allow_origins=settings.
|
| 50 |
allow_credentials=True,
|
| 51 |
allow_methods=["*"],
|
| 52 |
allow_headers=["*"],
|
| 53 |
)
|
| 54 |
|
|
|
|
| 55 |
# Register API routers
|
| 56 |
app.include_router(upload.router)
|
| 57 |
app.include_router(analyze.router)
|
|
|
|
| 33 |
|
| 34 |
|
| 35 |
app = FastAPI(
|
| 36 |
+
title=settings.PROJECT_NAME,
|
| 37 |
+
version=settings.VERSION,
|
| 38 |
+
debug=settings.DEBUG
|
|
|
|
| 39 |
)
|
| 40 |
|
| 41 |
app.state.limiter = limiter
|
| 42 |
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
| 43 |
app.add_middleware(SlowAPIMiddleware)
|
| 44 |
|
| 45 |
+
# CORS Configuration
|
| 46 |
app.add_middleware(
|
| 47 |
CORSMiddleware,
|
| 48 |
+
allow_origins=settings.cors_origins_list,
|
| 49 |
allow_credentials=True,
|
| 50 |
allow_methods=["*"],
|
| 51 |
allow_headers=["*"],
|
| 52 |
)
|
| 53 |
|
| 54 |
+
|
| 55 |
# Register API routers
|
| 56 |
app.include_router(upload.router)
|
| 57 |
app.include_router(analyze.router)
|