changes
This commit is contained in:
282
scripts/setup-secure-env.py
Executable file
282
scripts/setup-secure-env.py
Executable file
@@ -0,0 +1,282 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user