From c6b19d01f29aba1d10612f9d08c4af88f6ace65b Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Wed, 29 Apr 2026 14:12:24 +0100 Subject: [PATCH] security: remove default admin password fallback (C-04) seed_default_admin now skips creation and logs a warning when DEFAULT_ADMIN_PASSWORD is unset instead of falling back to the hardcoded ChangeMe123! value. Existing-admin promotion path is unaffected. Added DEFAULT_ADMIN_PASSWORD to .env.prod.example. Co-Authored-By: Claude Sonnet 4.6 --- .env.prod.example | 9 +++++++-- backend/app/core/seed.py | 8 +++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.env.prod.example b/.env.prod.example index 176dddb..e16f608 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -10,6 +10,8 @@ REDIS_URL=redis://redis:6379/0 # JWT Authentication JWT_SECRET_KEY=your-production-jwt-secret-key-min-32-chars JWT_REFRESH_SECRET_KEY=your-production-refresh-secret-key-min-32-chars +# Required: admin account created on first boot. Unset = admin not seeded. +DEFAULT_ADMIN_PASSWORD=your-secure-admin-password # AI Services GEMINI_API_KEY=your-gemini-api-key @@ -19,8 +21,11 @@ ELEVENLABS_API_KEY=your-elevenlabs-api-key GCS_BUCKET_NAME=your-production-bucket-name GOOGLE_CLOUD_PROJECT=your-gcp-project-id -# Email Service -SENDGRID_API_KEY=your-sendgrid-api-key +# Email Service (Mailgun) +SENDGRID_API_KEY= +MAILGUN_API_KEY=your-mailgun-api-key +MAILGUN_DOMAIN=mg.oliver.solutions +MAILGUN_FROM=noreply@mg.oliver.solutions # Monitoring SENTRY_DSN=your-sentry-dsn-url diff --git a/backend/app/core/seed.py b/backend/app/core/seed.py index 294daf7..a5f6741 100644 --- a/backend/app/core/seed.py +++ b/backend/app/core/seed.py @@ -34,7 +34,13 @@ async def seed_default_admin(db) -> None: print(f"✅ Default admin {DEFAULT_ADMIN_EMAIL} already exists") return - password = os.environ.get("DEFAULT_ADMIN_PASSWORD", "ChangeMe123!") + password = os.environ.get("DEFAULT_ADMIN_PASSWORD") + if not password: + print( + "⚠️ DEFAULT_ADMIN_PASSWORD not set — skipping default admin creation. " + "Set this env var and restart to create the admin account." + ) + return user_doc = { "_id": str(ObjectId()), "email": DEFAULT_ADMIN_EMAIL,