API: Authentication & Users
Relevant source files
The following files were used as context for generating this wiki page:
The Authentication and User management system is a core part of the API Gateway, implementing a Perimeter Security model. The Gateway acts as the single entry point for all client requests, where it is solely responsible for authenticating users via JWT and authorizing access to protected resources based on user roles. This centralized approach enhances security and performance by offloading authentication logic from downstream microservices.
Once a request is authenticated and authorized, the Gateway forwards it to the appropriate microservice (e.g., user-app) via the NATS message broker. This design simplifies the internal microservices, as they can trust that any incoming request from the Gateway has already been vetted.
Sources: apps/gateway/README.md, README.md
Architecture & Security Flow
The API Gateway employs a two-step security process for protected endpoints, using NestJS Guards. First, the AuthGuard validates the JWT. If successful, the RolesGuard checks if the user's role is permitted to access the endpoint.
The following diagram illustrates the request flow for a protected endpoint.
This diagram shows the successful authentication and authorization flow for fetching user data.
Sources: apps/gateway/src/auth/auth.guard.ts, apps/gateway/src/auth/roles.guard.ts, apps/gateway/README.md
Authentication (AuthGuard)
Authentication is handled by the AuthGuard. It is responsible for validating the JSON Web Token (JWT) sent in the Authorization header of incoming requests.
Logic Flow
- Token Extraction: The guard extracts the token from the
Authorization: Bearer <token>header. - Validation: It uses the
JwtServiceto verify the token's signature and expiration. This verification is performed locally within the Gateway using an RSA public key, which is a significant performance optimization as it avoids a network call to theuser-appfor every request. - User Payload Attachment: If the token is valid, the guard decodes the payload and attaches a simplified
userobject (containinguserId,email, androle) to the Express request object for use in subsequent handlers, including theRolesGuardand controllers. - Error Handling: If the token is missing, malformed, or invalid (e.g., expired, bad signature), the guard throws an
UnauthorizedException, immediately halting the request with a401 Unauthorizedstatus.
Sources: apps/gateway/src/auth/auth.guard.ts, apps/gateway/README.md:65-73, apps/gateway/test/auth-authorization.integration.spec.ts:42-63
Error Scenarios
The AuthGuard handles several failure cases, each resulting in a 401 Unauthorized response:
| Scenario | Error Message | Source File |
|---|---|---|
No Authorization header | Missing authorization header | auth.guard.ts:24 |
Invalid header format (not Bearer) | Invalid authorization format. Format is "Bearer <token>" | auth.guard.ts:28 |
| Invalid or expired token | Invalid or expired token | auth.guard.ts:36 |
Token payload is invalid (e.g., missing sub or role) | Invalid token payload | auth.guard.ts:43 |
Sources: apps/gateway/src/auth/auth.guard.ts:23-48, apps/gateway/test/auth-authorization.integration.spec.ts:42-63
Authorization (RolesGuard)
Authorization is managed by the RolesGuard, which performs Role-Based Access Control (RBAC). It runs after the AuthGuard has successfully authenticated a user.
Logic Flow
This flowchart shows how RolesGuard determines access.
This flowchart details the decision-making process within the RolesGuard.
Sources: apps/gateway/src/auth/roles.guard.ts:14-31
Implementation Details
- Role Definition: Endpoint-specific roles are defined using the
@Roles()decorator, which attaches role metadata to the route handler. For example:@Roles(UserRole.ADMIN). - Role Checking: The
RolesGuarduses NestJS'sReflectorto retrieve the required roles for the current endpoint. It then compares these against theroleproperty of theuserobject thatAuthGuardattached to the request. - Access Denied: If the user's role is not in the list of required roles, the guard throws a
ForbiddenExceptionwith a descriptive message, resulting in a403 Forbiddenresponse. The error message specifies the required roles and the user's current role.
Sources: apps/gateway/src/users/users.controller.ts:23, apps/gateway/src/auth/roles.guard.ts:21-31, apps/gateway/test/auth-authorization.integration.spec.ts:90-101
Guard Execution Order
The order of execution for the guards is critical: AuthGuard always runs before RolesGuard. This is enforced by the order in which they are listed in the @UseGuards() decorator.
This sequence ensures that:
- Unauthorized requests (e.g., invalid or missing token) are rejected immediately with a
401status code, without ever checking for roles. - The
RolesGuardcan safely assume that if it is executed,request.userexists and contains a valid, authenticated user payload.
This behavior is verified in integration tests, which confirm that a request with an invalid token to an admin-only endpoint results in a 401 Unauthorized (from AuthGuard) rather than a 403 Forbidden (from RolesGuard).
Sources: apps/gateway/test/auth-authorization.integration.spec.ts:187-196, apps/gateway/src/users/users.controller.ts:22
API Endpoints
The following endpoints are exposed by the Gateway for authentication and user management.
Authentication Endpoints
These endpoints are handled by AuthController and are used for user registration, login, and token management.
| Method | Path | Description | Protected |
|---|---|---|---|
POST | /auth/register | Registers a new user account. | No |
POST | /auth/login | Logs in a user and returns access and refresh tokens. | No |
GET | /auth/me | Retrieves the profile of the currently authenticated user. | Yes |
POST | /auth/refresh | Issues a new set of tokens using a valid refresh token. | No |
POST | /auth/verify | Verifies the validity of a given token. | No |
Sources: apps/gateway/src/auth/auth.controller.ts, postman-collection.json
User Management Endpoints
These endpoints are handled by UsersController and are used for managing user data. Access is restricted by roles.
| Method | Path | Description | Required Role(s) |
|---|---|---|---|
GET | /users | Retrieves a paginated list of all users. | ADMIN |
GET | /users/:id | Retrieves a single user by their ID. | Authenticated |
GET | /users/email/:email | Retrieves a single user by their email address. | ADMIN |
PUT | /users/:id | Updates a user's profile information. | Authenticated |
PUT | /users/:id/deactivate | Deactivates a user's account. | Authenticated |
Sources: apps/gateway/src/users/users.controller.ts, postman-collection.json
Summary
The Authentication and Users module in the API Gateway provides a robust and secure implementation of the Perimeter Security pattern. By centralizing JWT validation and role-based authorization at the edge of the system, it simplifies the architecture of internal microservices and improves overall system performance. The use of AuthGuard and RolesGuard ensures that every request to a protected resource is properly authenticated and authorized before it is processed further.
Sources: apps/gateway/README.md, apps/gateway/REFACTORING-GUIDE.md