5.4 KiB
5.4 KiB
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:
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
-
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?
-
Identify all related multi-user scaffolding:
- Database schemas with role system
- Auth handlers with role checking
- User management functions that exist but are unused
-
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
-
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 -
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
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:
// 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:
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
-
Fresh install test:
- Start with clean database
- Run setup with custom password
- Restart
- Verify login works with custom password
-
Password change test:
- Existing installation
- Update .env with new password
- Restart
- Verify admin password updated
-
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:
- What was the original intent when adding web auth?
- Were there plans for multiple admins or was this just scaffolding?
- Should we remove the entire role system or just simplify it?
- Is keeping email field useful for single admin or should we simplify further?
NEXT STEPS
- Analyze commit
a92ac0ed7thoroughly - Get approval from original developer for cleanup approach
- Implement fixes in development branch
- Test thoroughly on fresh installs
- Remove multi-user scaffolding definitively
- 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