# πŸ” API Security & Access Levels This document details the security layers, authentication methods, and role-based access control (RBAC) for the GoHorse Jobs API. Use this guide to verify and test route protection. ## πŸ›‘οΈ Authentication Methods 1. **Bearer Token (JWT)** * Header: `Authorization: Bearer ` * Used by: Mobile apps, external integrations, simple API tests. 2. **HttpOnly Cookie** * Cookie Name: `jwt` * Used by: Web Frontend (Next.js), Backoffice. * Properties: `HttpOnly`, `Secure` (in prod), `SameSite=Lax`. ## 🚦 Access Levels | Level | Description | Middleware | | :--- | :--- | :--- | | **Public** | Open to everyone (Guests). No check performed. | None | | **Authenticated** | Requires a valid JWT (Header or Cookie). | `HeaderAuthGuard` | | **Role-Restricted** | Requires valid JWT + Specific Role claim. | `HeaderAuthGuard` + `RequireRoles(...)` | ## πŸ—ΊοΈ Route Permission Matrix ### 🟒 Public Routes | Method | Route | Description | Notes | | :--- | :--- | :--- | :--- | | `POST` | `/api/v1/auth/login` | User Login | Returns JWT + Cookie | | `POST` | `/api/v1/auth/register` | Candidate Register | Creates `jobSeeker` user | | `POST` | `/api/v1/companies` | Company Register | Creates company + `companyAdmin` | | `GET` | `/api/v1/jobs` | List Jobs | Public search/list | | `GET` | `/api/v1/jobs/{id}` | Get Job | Public details | | `GET` | `/docs/*` | Swagger UI | API Documentation | ### 🟑 Authenticated Routes (Any Logged User) **Requirement**: Valid JWT. | Method | Route | Description | | :--- | :--- | :--- | | `GET` | `/api/v1/users/me` | Get Own Profile | | `PATCH` | `/api/v1/users/{id}` | Update Own Profile (Self-check in handler) | | `GET` | `/api/v1/notifications` | Get Own Notifications | | `POST` | `/api/v1/applications` | Apply for Job (Candidate) | | `POST` | `/api/v1/storage/upload-url` | Get S3 Upload URL | | `POST` | `/api/v1/storage/download-url` | Get S3 Download URL | | `DELETE` | `/api/v1/storage/files` | Delete S3 File | ### 🟠 Recruiter / CompanyAdmin Routes **Requirement**: Role `companyAdmin` OR `recruiter`. | Method | Route | Description | | :--- | :--- | :--- | | `POST` | `/api/v1/jobs` | Create Job | | `PUT` | `/api/v1/jobs/{id}` | Update Job | | `DELETE` | `/api/v1/jobs/{id}` | Delete Job | | `GET` | `/api/v1/applications` | List Applications (for own jobs) | | `PUT` | `/api/v1/applications/{id}/status` | Update Application Status | ### πŸ”΄ Admin / SuperAdmin Routes (Backoffice) **Requirement**: Role `superadmin` OR `admin`. | Method | Route | Description | Middleware Check | | :--- | :--- | :--- | :--- | | `GET` | `/api/v1/users` | List All Users | `adminOnly` | | `POST` | `/api/v1/users` | Create User (Staff) | `adminOnly` | | `DELETE` | `/api/v1/users/{id}` | Delete User | `adminOnly` | | `GET` | `/api/v1/users/roles` | List System Roles | `adminOnly` | | `GET` | `/api/v1/companies` | List Companies (Full) | `adminOnly` | | `PATCH` | `/api/v1/companies/{id}/status` | Activate/Ban Company | `adminOnly` | | `GET` | `/api/v1/jobs/moderation` | Moderate Jobs | `adminOnly` | | `PATCH` | `/api/v1/jobs/{id}/status` | Approve/Reject Job | `adminOnly` | | `POST` | `/api/v1/jobs/{id}/duplicate` | Admin Duplicate Job | `adminOnly` | | `GET` | `/api/v1/tags` | List Tags | `adminOnly` | | `POST` | `/api/v1/tags` | Create Tag | `adminOnly` | | `PATCH` | `/api/v1/tags/{id}` | Update Tag | `adminOnly` | | `GET` | `/api/v1/candidates` | List All Candidates | `adminOnly` | | `GET` | `/api/v1/audit/logins` | View Audit Logs | `adminOnly` | ## πŸ§ͺ Testing Security **1. Test Public Access (Should Succeed)** ```bash curl http://localhost:8521/api/v1/jobs ``` **2. Test Protected Route without Token (Should Fail 401)** ```bash curl http://localhost:8521/api/v1/users/me # Expected: 401 Unauthorized ``` **3. Test Admin Route as Candidate (Should Fail 403)** 1. Login as Candidate -> Get Token A 2. Call Admin Route: ```bash curl -H "Authorization: Bearer " http://localhost:8521/api/v1/audit/logins # Expected: 403 Forbidden ``` **4. Test Admin Route as Admin (Should Succeed)** 1. Login as SuperAdmin -> Get Token B 2. Call Admin Route: ```bash curl -H "Authorization: Bearer " http://localhost:8521/api/v1/audit/logins # Expected: 200 OK ```