# REDFLAG ENSUREADMINUSER CRITICAL BUG - COMPREHENSIVE FIX PLAN ## BACKGROUND - RedFlag was designed as SINGLE-ADMIN system (author is original developer, abhors enterprise) - Originally just JWT tokens for agents, later added single-admin web dashboard - Database schema has multi-user scaffolding but never implemented - EnsureAdminUser() exists but breaks single-admin password updates ## THE PROBLEM **EnsureAdminUser() exists in single-admin system where it doesn't belong:** ```go func (q *UserQueries) EnsureAdminUser(username, email, password string) error { existingUser, err := q.GetUserByUsername(username) if err == nil && existingUser != nil { return nil // Admin user already exists ← PREVENTS PASSWORD UPDATES! } _, err = q.CreateUser(username, email, password, "admin") return err } ``` **In single-admin system: admin exists = admin already exists, so password never updates** ## EXECUTION ORDER BUG **New version broken:** ``` Main starts → EnsureAdminUser(empty password) → isSetupComplete() → welcome mode ``` - Admin user created with empty/default password BEFORE setup - Setup runs but admin already exists → no password update - Login fails **Legacy version worked:** ``` Main starts → config check → if failed → welcome mode → return ``` - No admin user created if setup incomplete - After setup restart → EnsureAdminUser with correct password ## COMPREHENSIVE CLEANUP PLAN ### PHASE 1: ANALYSIS 1. **Document everything added in commit a92ac0ed7 (Oct 30, 2025)** - What auth system was being implemented? - Why multi-user scaffolding if never intended? - What was the original intended flow? 2. **Identify all related multi-user scaffolding:** - Database schemas with role system - Auth handlers with role checking - User management functions that exist but are unused 3. **Map the actual authentication flow:** - Agent auth (JWT tokens) - Web auth (single admin password) - How they relate/interact ### PHASE 2: CLEANUP #### REMOVE MULTI-USER SCAFFOLDING 1. **Database cleanup:** ``` users table: Keep email field (for admin) but remove role system - ALTER TABLE users DROP COLUMN role (or default to 'admin') - Remove unused indexes if any ``` 2. **Code cleanup:** - Remove role-based authentication checks - Simplify user models to remove role field - Remove unused user management endpoints #### FIX ENSUREADMINUSER **Option A: Delete entirely and replace with EnsureSingleAdmin** ```go func (q *UserQueries) EnsureSingleAdmin(username, email, password string) error { // Always update/create admin with current password existingUser, err := q.GetUserByUsername(username) if err != nil { // User doesn't exist, create it return q.CreateUser(username, email, password, "admin") } // User exists, update password return q.UpdateAdminPassword(existingUser.ID, password) } ``` **Option B: Modify existing to update instead of return early** - Keep function name but change logic to always ensure password matches #### FIX EXECUTION ORDER **In main.go:** ```go // BEFORE: EnsureAdminUser comes before setup check // AFTER: Move EnsureAdminUser AFTER setup is confirmed complete // Check if setup is complete FIRST if !isSetupComplete(cfg, signingService, db, userQueries) { startWelcomeModeServer() return } // THEN ensure admin user with correct password if err := userQueries.EnsureSingleAdmin(cfg.Admin.Username, cfg.Admin.Username+"@redflag.local", cfg.Admin.Password); err != nil { log.Fatalf("Failed to ensure admin user: %v", err) } ``` **Add password update function if not exists:** ```go func (q *UserQueries) UpdateAdminPassword(userID uuid.UUID, newPassword string) error { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost) if err != nil { return err } query := `UPDATE users SET password_hash = $1 WHERE id = $2` _, err = q.db.Exec(query, hashedPassword, userID) return err } ``` ### PHASE 3: VALIDATION 1. **Fresh install test:** - Start with clean database - Run setup with custom password - Restart - Verify login works with custom password 2. **Password change test:** - Existing installation - Update .env with new password - Restart - Verify admin password updated 3. **Agent auth compatibility:** - Ensure agent JWT auth still works - Verify no regression in agent communication ### PHASE 4: SIMPLIFICATION **Given ETHOS principles (anti-enterprise):** - Remove all complexity around multi-user - Single admin = single configuration - Remove unused user management code - Simplify to essentials only **Questions for original developer:** 1. What was the original intent when adding web auth? 2. Were there plans for multiple admins or was this just scaffolding? 3. Should we remove the entire role system or just simplify it? 4. Is keeping email field useful for single admin or should we simplify further? ## NEXT STEPS 1. Analyze commit a92ac0ed7 thoroughly 2. Get approval from original developer for cleanup approach 3. Implement fixes in development branch 4. Test thoroughly on fresh installs 5. Remove multi-user scaffolding definitively 6. Document final single-admin-only architecture ## RATIONALE RedFlag is NOT enterprise: - No multi-user requirements - Single admin for homelab/self-hosted - Simpler = better - Follow original design philosophy