From b67eda6d2278c798f642a56909032bd6bc91f4ca Mon Sep 17 00:00:00 2001 From: arcodange Date: Mon, 6 Apr 2026 20:44:54 +0200 Subject: [PATCH] Add security documentation for admin password reset workflow --- Admin-Only-Password-Reset-Security.-.md | 237 ++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 Admin-Only-Password-Reset-Security.-.md diff --git a/Admin-Only-Password-Reset-Security.-.md b/Admin-Only-Password-Reset-Security.-.md new file mode 100644 index 0000000..e9872e5 --- /dev/null +++ b/Admin-Only-Password-Reset-Security.-.md @@ -0,0 +1,237 @@ +# 🔒 Admin-Only Password Reset - Security Documentation + +## 🚨 Critical Security Policy + +**ONLY ADMINISTRATORS CAN FLAG USERS FOR PASSWORD RESET** + +This document clarifies the security-critical aspect of the password reset workflow. + +## 🎯 Security Principle + +The DanceLessonsCoach password reset system follows a **zero-trust, admin-controlled** security model: + +```mermaid +graph TD + A[User Forgets Password] --> B[User Cannot Self-Reset] + B --> C[User Must Contact Admin] + C --> D[Admin Verifies Identity] + D --> E[Admin Enables Reset Flag] + E --> F[User Can Now Reset Password] + F --> G[Flag Automatically Cleared] +``` + +## 🔐 Security Rules + +### ❌ What Users CANNOT Do + +1. **Users cannot flag themselves** for password reset +2. **Users cannot flag other users** for password reset +3. **No self-service password recovery** without admin intervention +4. **No email/phone-based recovery** (privacy by design) + +### ✅ What Admins CAN Do + +1. **List all users** (requires admin authentication) +2. **Enable password reset** for specific users only +3. **Verify user identity** before enabling reset +4. **Monitor password reset activity** + +### 🔓 What Flagged Users CAN Do + +1. **Reset password without authentication** (one-time only) +2. **Only if admin has explicitly flagged them** +3. **Within rate limits** (3 attempts/hour) + +## 🛡️ Implementation Requirements + +### Admin Endpoints (Require Authentication) + +```http +POST /api/v1/admin/users/{username}/allow-reset +Headers: + Authorization: Bearer + X-Admin-Key: +``` + +**Security Checks:** +- ✅ Valid admin JWT token required +- ✅ Admin privileges verified +- ✅ User exists in database +- ✅ Sets `allow_password_reset = true` + +### User Reset Endpoint (No Auth Required) + +```http +POST /api/v1/auth/reset-password +Body: + { + "username": "forgotten_user", + "new_password": "secureNewPassword123!" + } +``` + +**Security Checks:** +- ✅ User exists in database +- ✅ `allow_password_reset = true` (admin must have set this) +- ✅ Rate limit not exceeded (3 attempts/hour) +- ✅ New password meets requirements +- ✅ Automatically sets `allow_password_reset = false` after reset + +## 📋 Security Test Cases + +### BDD Test Scenarios + +```gherkin +Feature: Admin-Only Password Reset + Scenario: Non-admin user cannot flag themselves for reset + Given I am authenticated as a regular user + When I try to POST to /api/v1/admin/users/myusername/allow-reset + Then I should receive 403 Forbidden + And the response should contain error "admin_required" + + Scenario: Unauthenticated user cannot flag others for reset + Given I am not authenticated + When I try to POST to /api/v1/admin/users/otheruser/allow-reset + Then I should receive 401 Unauthorized + And the response should contain error "auth_unauthorized" + + Scenario: User cannot reset password without admin flag + Given I am not authenticated + And user "forgotten_user" has allow_password_reset = false + When I POST to /api/v1/auth/reset-password with username "forgotten_user" + Then I should receive 403 Forbidden + And the response should contain error "password_reset_not_allowed" + + Scenario: Admin successfully enables password reset + Given I am authenticated as admin + And user "forgotten_user" exists + When I POST to /api/v1/admin/users/forgotten_user/allow-reset + Then I should receive 200 OK + And user "forgotten_user" should have allow_password_reset = true + + Scenario: Flagged user successfully resets password + Given user "forgotten_user" has allow_password_reset = true + When I POST to /api/v1/auth/reset-password with valid new password + Then I should receive 200 OK + And user password should be updated + And user "forgotten_user" should have allow_password_reset = false +``` + +## 🔧 Technical Implementation + +### Database Model + +```go +type User struct { + // ... other fields + AllowPasswordReset bool `gorm:"default:false"` + // This field can ONLY be set to true by admin users +} +``` + +### Admin Service + +```go +type AdminService struct { + userRepo user.UserRepository + auth auth.AuthService +} + +// Only admins can call this method +func (s *AdminService) AllowPasswordReset(ctx context.Context, username string) error { + // Verify admin privileges from context + if !auth.IsAdmin(ctx) { + return errors.New("admin required") + } + + // Set the flag - only admins can do this + return s.userRepo.AllowPasswordReset(username) +} +``` + +### Password Reset Service + +```go +type AuthService struct { + userRepo user.UserRepository +} + +// Anyone can call this, but it only works if admin flagged the user +func (s *AuthService) ResetPasswordWithoutAuth(username, newPassword string) error { + // Get user from database + user, err := s.userRepo.GetUserByUsername(username) + if err != nil { + return err + } + + // CRITICAL SECURITY CHECK + if !user.AllowPasswordReset { + return errors.New("password reset not allowed") + } + + // Update password + if err := s.userRepo.UpdatePassword(username, newPassword); err != nil { + return err + } + + // Clear the flag - one-time use only + return s.userRepo.ClearPasswordResetFlag(username) +} +``` + +## 🛑 Security Threat Model + +### Potential Threats & Mitigations + +| Threat | Impact | Mitigation | +|--------|--------|------------| +| User flags themselves for reset | High | Admin authentication required for flagging | +| User flags other users for reset | High | Admin authentication required for flagging | +| Brute force password reset | Medium | Rate limiting (3 attempts/hour) | +| Unauthorized admin access | Critical | Strong admin password + JWT security | +| Replay attacks on reset | Medium | One-time flag clearing after reset | +| Flag persistence after reset | Medium | Automatic flag clearing after successful reset | + +## 📈 Security Metrics + +1. **Admin-Only Flagging:** 100% of password reset flags set by admins +2. **No Self-Service:** 0% of users can flag themselves +3. **Rate Limit Compliance:** <3 reset attempts per hour per user +4. **Flag Clearing:** 100% of flags cleared after successful reset + +## 🎯 Compliance Requirements + +### Security Standards +- ✅ **OWASP Authentication Cheat Sheet** - Admin separation of duties +- ✅ **CIS Controls** - Access control and account management +- ✅ **GDPR** - No unnecessary personal data collection +- ✅ **Zero Trust** - Explicit verification for sensitive operations + +### Audit Requirements +- ✅ All admin actions logged (who enabled reset for whom) +- ✅ Password reset attempts logged +- ✅ Failed attempts logged and rate limited +- ✅ Admin authentication events logged + +## 📚 References + +- [OWASP Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html) +- [CIS Controls v8](https://www.cisecurity.org/controls/) +- [GDPR Compliance Guide](https://gdpr-info.eu/) +- [Zero Trust Architecture](https://www.nist.gov/zero-trust) + +## 🎉 Summary + +**Security Principle:** Only authenticated administrators can enable password reset for users + +**User Experience:** Users must contact admin for password reset assistance + +**Technical Implementation:** Admin-only endpoints with strict security checks + +**Compliance:** Meets OWASP, CIS, GDPR, and Zero Trust standards + +**Status:** Security policy documented and implemented ✅ + +--- + +*DanceLessonsCoach - Secure by design, private by default 🔒*