Files
orion/docs/api/authentication-flow-diagrams.md

14 KiB

Authentication Flow Diagrams

┌─────────────────────────────────────────────────────────────┐
│                     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=<JWT>; 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 <token>)          │
                                                   │
                                    ┌──────────────▼──────────────┐
                                    │  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=<JWT>; 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 <token>)          │
                                                   │
                                    ┌──────────────▼──────────────┐
                                    │  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=<JWT> (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"
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 <JWT>
  │
  ├── 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