Files
delphi-database/scripts/setup-secure-env.py
HotSwapp bac8cc4bd5 changes
2025-08-18 20:20:04 -05:00

283 lines
10 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Secure Environment Setup Script for Delphi Database System
This script generates secure environment variables and creates a .env file
with strong cryptographic secrets and secure configuration.
⚠️ IMPORTANT: Run this script before deploying to production!
"""
import os
import sys
import secrets
import string
import argparse
from pathlib import Path
def generate_secure_secret_key(length: int = 32) -> str:
"""Generate a cryptographically secure secret key for JWT tokens"""
return secrets.token_urlsafe(length)
def generate_secure_password(length: int = 16, include_symbols: bool = True) -> str:
"""Generate a cryptographically secure password"""
alphabet = string.ascii_letters + string.digits
if include_symbols:
alphabet += "!@#$%^&*()-_=+[]{}|;:,.<>?"
return ''.join(secrets.choice(alphabet) for _ in range(length))
def validate_cors_origins(origins: str) -> bool:
"""Validate CORS origins format"""
if not origins:
return False
origins_list = [origin.strip() for origin in origins.split(",")]
for origin in origins_list:
if not origin.startswith(('http://', 'https://')):
return False
return True
def create_secure_env_file(project_root: Path, args: argparse.Namespace) -> None:
"""Create a secure .env file with generated secrets"""
env_file = project_root / ".env"
if env_file.exists() and not args.force:
print(f"❌ .env file already exists at {env_file}")
print(" Use --force to overwrite, or manually update the file")
return
# Generate secure secrets
print("🔐 Generating secure secrets...")
secret_key = generate_secure_secret_key(32)
admin_password = generate_secure_password(16, include_symbols=True)
# Get user input for configuration
print("\n📝 Configuration Setup:")
# Admin account
admin_username = input(f"Admin username [{args.admin_username}]: ").strip() or args.admin_username
admin_email = input(f"Admin email [{args.admin_email}]: ").strip() or args.admin_email
admin_fullname = input(f"Admin full name [{args.admin_fullname}]: ").strip() or args.admin_fullname
# CORS origins
while True:
cors_origins = input("CORS origins (comma-separated, e.g., https://app.company.com,https://www.company.com): ").strip()
if validate_cors_origins(cors_origins):
break
print("❌ Invalid CORS origins. Please use full URLs starting with http:// or https://")
# Production settings
is_production = input("Is this for production? [y/N]: ").strip().lower() in ('y', 'yes')
debug = not is_production
secure_cookies = is_production
# Database URL
if is_production:
database_url = input("Database URL [sqlite:///./data/delphi_database.db]: ").strip() or "sqlite:///./data/delphi_database.db"
else:
database_url = "sqlite:///./data/delphi_database.db"
# Email settings (optional)
setup_email = input("Configure email notifications? [y/N]: ").strip().lower() in ('y', 'yes')
email_config = {}
if setup_email:
email_config = {
'SMTP_HOST': input("SMTP host (e.g., smtp.gmail.com): ").strip(),
'SMTP_PORT': input("SMTP port [587]: ").strip() or "587",
'SMTP_USERNAME': input("SMTP username: ").strip(),
'SMTP_PASSWORD': input("SMTP password: ").strip(),
'NOTIFICATION_EMAIL_FROM': input("From email address: ").strip(),
}
# Create .env content
env_content = f"""# =============================================================================
# DELPHI CONSULTING GROUP DATABASE SYSTEM - ENVIRONMENT VARIABLES
# =============================================================================
#
# 🔒 GENERATED AUTOMATICALLY BY setup-secure-env.py
# Generated on: {os.popen('date').read().strip()}
#
# ⚠️ SECURITY CRITICAL: Keep this file secure and never commit to version control
# =============================================================================
# =============================================================================
# 🔒 SECURITY SETTINGS (CRITICAL)
# =============================================================================
# 🔐 Cryptographically secure secret key for JWT tokens
SECRET_KEY={secret_key}
# 🔑 Secure admin password (save this securely!)
ADMIN_PASSWORD={admin_password}
# =============================================================================
# 🌐 CORS SETTINGS
# =============================================================================
CORS_ORIGINS={cors_origins}
# =============================================================================
# 👤 ADMIN ACCOUNT SETTINGS
# =============================================================================
ADMIN_USERNAME={admin_username}
ADMIN_EMAIL={admin_email}
ADMIN_FULLNAME={admin_fullname}
# =============================================================================
# 🗄️ DATABASE SETTINGS
# =============================================================================
DATABASE_URL={database_url}
# =============================================================================
# ⚙️ APPLICATION SETTINGS
# =============================================================================
DEBUG={str(debug).lower()}
SECURE_COOKIES={str(secure_cookies).lower()}
# JWT Token expiration (in minutes)
ACCESS_TOKEN_EXPIRE_MINUTES=240
REFRESH_TOKEN_EXPIRE_MINUTES=43200
# File paths
UPLOAD_DIR=./uploads
BACKUP_DIR=./backups
# =============================================================================
# 📝 LOGGING SETTINGS
# =============================================================================
LOG_LEVEL={'DEBUG' if debug else 'INFO'}
LOG_TO_FILE=True
LOG_ROTATION=10 MB
LOG_RETENTION=30 days
# =============================================================================
# 📧 NOTIFICATION SETTINGS
# =============================================================================
NOTIFICATIONS_ENABLED={str(setup_email).lower()}
"""
# Add email configuration if provided
if setup_email and email_config:
env_content += f"""
# Email SMTP settings
SMTP_HOST={email_config.get('SMTP_HOST', '')}
SMTP_PORT={email_config.get('SMTP_PORT', '587')}
SMTP_USERNAME={email_config.get('SMTP_USERNAME', '')}
SMTP_PASSWORD={email_config.get('SMTP_PASSWORD', '')}
SMTP_STARTTLS=True
NOTIFICATION_EMAIL_FROM={email_config.get('NOTIFICATION_EMAIL_FROM', '')}
"""
env_content += """
# =============================================================================
# 🚨 SECURITY CHECKLIST - VERIFY BEFORE PRODUCTION
# =============================================================================
#
# ✅ SECRET_KEY is 32+ character random string
# ✅ ADMIN_PASSWORD is strong and securely stored
# ✅ CORS_ORIGINS set to specific production domains
# ✅ DEBUG=False for production
# ✅ SECURE_COOKIES=True for production HTTPS
# ✅ Database backups configured and tested
# ✅ This .env file is never committed to version control
# ✅ File permissions are restrictive (600)
#
# =============================================================================
"""
# Write .env file
try:
with open(env_file, 'w') as f:
f.write(env_content)
# Set restrictive permissions (owner read/write only)
os.chmod(env_file, 0o600)
print(f"\n✅ Successfully created secure .env file at {env_file}")
print(f"✅ File permissions set to 600 (owner read/write only)")
# Display generated credentials
print(f"\n🔑 **SAVE THESE CREDENTIALS SECURELY:**")
print(f" Admin Username: {admin_username}")
print(f" Admin Password: {admin_password}")
print(f" Secret Key: {secret_key[:10]}... (truncated for security)")
print(f"\n⚠️ **IMPORTANT SECURITY NOTES:**")
print(f" • Save the admin credentials in a secure password manager")
print(f" • Never commit the .env file to version control")
print(f" • Regularly rotate the SECRET_KEY and admin password")
print(f" • Use HTTPS in production with SECURE_COOKIES=True")
if is_production:
print(f"\n🚀 **PRODUCTION DEPLOYMENT CHECKLIST:**")
print(f" • Database backups configured and tested")
print(f" • Monitoring and alerting configured")
print(f" • Security audit completed")
print(f" • HTTPS enabled with valid certificates")
print(f" • Rate limiting configured")
print(f" • Log monitoring configured")
except Exception as e:
print(f"❌ Error creating .env file: {e}")
sys.exit(1)
def main():
parser = argparse.ArgumentParser(
description="Generate secure environment configuration for Delphi Database System"
)
parser.add_argument(
"--force",
action="store_true",
help="Overwrite existing .env file"
)
parser.add_argument(
"--admin-username",
default="admin",
help="Default admin username"
)
parser.add_argument(
"--admin-email",
default="admin@yourcompany.com",
help="Default admin email"
)
parser.add_argument(
"--admin-fullname",
default="System Administrator",
help="Default admin full name"
)
args = parser.parse_args()
# Find project root
script_dir = Path(__file__).parent
project_root = script_dir.parent
print("🔐 Delphi Database System - Secure Environment Setup")
print("=" * 60)
print(f"Project root: {project_root}")
# Verify we're in the right directory
if not (project_root / "app" / "main.py").exists():
print("❌ Error: Could not find Delphi Database System files")
print(" Make sure you're running this script from the project directory")
sys.exit(1)
create_secure_env_file(project_root, args)
print(f"\n🎉 Setup complete! You can now start the application with:")
print(f" python -m uvicorn app.main:app --reload")
if __name__ == "__main__":
main()