# Authentication Flow Diagrams ## Cookie Isolation Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ Browser │ │ │ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ Admin Area │ │ Vendor Area │ │ │ │ /admin/* │ │ /vendor/* │ │ │ │ │ │ │ │ │ │ 🍪 admin_token │ │ 🍪 vendor_token │ │ │ │ Path: /admin │ │ Path: /vendor │ │ │ └─────────────────────┘ └─────────────────────┘ │ │ │ │ │ │ ├───────────────────────────┤ │ │ │ ❌ No Cookie Mixing │ │ │ │ │ │ └───────────┼───────────────────────────┼──────────────────────┘ │ │ ▼ ▼ ┌───────────────────────┐ ┌───────────────────────┐ │ Admin Backend │ │ Vendor Backend │ │ /admin/* │ │ /vendor/* │ │ │ │ │ │ ✅ admin_token │ │ ✅ vendor_token │ │ ❌ vendor_token │ │ ❌ admin_token │ └───────────────────────┘ └───────────────────────┘ ``` ## Login Flow - Admin ``` ┌──────────┐ │ Browser │ └──────────┘ │ │ POST /api/v1/admin/auth/login │ { username, password } ▼ ┌─────────────────────────┐ │ Admin Auth Endpoint │ │ │ │ 1. Validate credentials│ │ 2. Check role == admin │ │ 3. Generate JWT │ └─────────────────────────┘ │ │ Set-Cookie: admin_token=; Path=/admin; HttpOnly; SameSite=Lax │ Response: { access_token, user } ▼ ┌──────────┐ │ Browser │──────────────────────────────────────┐ │ │ │ │ 🍪 admin_token (Path=/admin) │ │ 💾 localStorage.access_token │ └──────────┘ │ │ │ ├── Navigate to /admin/dashboard ────────────┤ │ (Cookie sent automatically) │ │ │ └── API call to /api/v1/admin/vendors ───────┤ (Authorization: Bearer ) │ │ ┌──────────────▼──────────────┐ │ get_current_admin_user() │ │ │ │ 1. Check Auth header │ │ 2. Check admin_token cookie │ │ 3. Validate JWT │ │ 4. Verify role == admin │ │ ✅ Return User │ └──────────────────────────────┘ ``` ## Login Flow - Vendor ``` ┌──────────┐ │ Browser │ └──────────┘ │ │ POST /api/v1/vendor/auth/login │ { username, password } ▼ ┌─────────────────────────┐ │ Vendor Auth Endpoint │ │ │ │ 1. Validate credentials│ │ 2. Block if admin │──────> ❌ "Admins cannot access vendor portal" │ 3. Check vendor access │ │ 4. Generate JWT │ └─────────────────────────┘ │ │ Set-Cookie: vendor_token=; Path=/vendor; HttpOnly; SameSite=Lax │ Response: { access_token, user, vendor } ▼ ┌──────────┐ │ Browser │──────────────────────────────────────┐ │ │ │ │ 🍪 vendor_token (Path=/vendor) │ │ 💾 localStorage.access_token │ └──────────┘ │ │ │ ├── Navigate to /vendor/ACME/dashboard ──────┤ │ (Cookie sent automatically) │ │ │ └── API call to /api/v1/vendor/ACME/products ┤ (Authorization: Bearer ) │ │ ┌──────────────▼──────────────┐ │ get_current_vendor_user() │ │ │ │ 1. Check Auth header │ │ 2. Check vendor_token cookie│ │ 3. Validate JWT │ │ 4. Block if admin │──> ❌ Error │ 5. Verify vendor access │ │ ✅ Return User │ └──────────────────────────────┘ ``` ## Security Boundary Enforcement ``` ┌─────────────────────┐ │ Request Comes In │ └──────────┬──────────┘ │ ┌──────────▼──────────┐ │ What's the path? │ └──────────┬──────────┘ │ ┌───────────────┼───────────────┐ │ │ │ Starts with Starts with Starts with /admin/* /vendor/* /api/* │ │ │ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ Check for: │ │ Check for: │ │ Check for: │ │ - admin_token │ │ - vendor_token │ │ - Authorization │ │ cookie │ │ cookie │ │ header │ │ - OR Auth header │ │ - OR Auth header │ │ (required) │ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ │ │ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ Validate: │ │ Validate: │ │ Validate: │ │ - JWT valid │ │ - JWT valid │ │ - JWT valid │ │ - User active │ │ - User active │ │ - User active │ │ - Role = admin │ │ - Role != admin │ │ - Any role │ │ │ │ - Has vendor │ │ (depends on │ │ │ │ access │ │ endpoint) │ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ │ │ ▼ ▼ ▼ ✅ Allowed ✅ Allowed ✅ Allowed ``` ## Cross-Context Prevention ### ❌ What's Blocked ``` Admin trying to access vendor route: ┌──────────────────────────────────────────┐ │ User: admin@example.com (role: admin) │ │ Token: Valid JWT with admin role │ │ Request: GET /vendor/ACME/dashboard │ └──────────────────────────────────────────┘ │ ▼ ┌───────────────────────┐ │ get_current_vendor_ │ │ from_cookie_or_header │ └───────────┬───────────┘ │ ▼ Check: role == "admin"? │ ▼ Yes ❌ InsufficientPermissionsException "Vendor access only - admins cannot use vendor portal" ``` ``` Vendor trying to access admin route: ┌──────────────────────────────────────────┐ │ User: vendor@acme.com (role: vendor) │ │ Token: Valid JWT with vendor role │ │ Request: GET /admin/dashboard │ └──────────────────────────────────────────┘ │ ▼ ┌───────────────────────┐ │ get_current_admin_ │ │ from_cookie_or_header │ └───────────┬───────────┘ │ ▼ Check: role == "admin"? │ ▼ No ❌ AdminRequiredException "Admin privileges required" ``` ``` Admin cookie sent to vendor route: ┌──────────────────────────────────────────┐ │ Cookie: admin_token= (Path=/admin) │ │ Request: GET /vendor/ACME/dashboard │ └──────────────────────────────────────────┘ │ ▼ Browser checks cookie path │ ▼ Path /vendor does NOT match /admin │ ▼ ❌ Cookie NOT sent Request has no authentication │ ▼ ❌ InvalidTokenException "Vendor authentication required" ``` ## Cookie Lifecycle ``` LOGIN │ ├── Server generates JWT ├── Server sets cookie: │ • Name: admin_token or vendor_token │ • Value: JWT │ • Path: /admin or /vendor │ • HttpOnly: true │ • Secure: true (production) │ • SameSite: Lax │ • Max-Age: matches JWT expiry │ └── Server returns JWT in response body └── Client stores in localStorage (optional) PAGE NAVIGATION │ ├── Browser automatically includes cookie │ if path matches │ ├── Server reads cookie ├── Server validates JWT └── Server returns page or 401 API CALL │ ├── Client reads token from localStorage ├── Client adds Authorization header │ Authorization: Bearer │ ├── Server reads header ├── Server validates JWT └── Server returns data or 401 LOGOUT │ ├── Client calls logout endpoint ├── Server clears cookie: │ response.delete_cookie(name, path) │ └── Client clears localStorage localStorage.removeItem('access_token') ``` ## Key Takeaways 1. **Cookie Path Isolation** = No cross-context cookies 2. **Role Checking** = Admins blocked from vendor routes 3. **Dual Auth Support** = Cookies for pages, headers for API 4. **Security First** = HttpOnly, Secure, SameSite protection 5. **Clear Boundaries** = Each context is completely isolated