Security Model
Relevant source files
The following files were used as context for generating this wiki page:
The project implements a Perimeter Security model, where the API Gateway acts as a fortified single point of entry for all client requests. This centralized approach ensures that all security-related concerns, such as authentication, authorization, rate-limiting, and auditing, are handled at the edge of the system before any request is passed to the internal microservices.
The core of the authentication mechanism is RSA-based JSON Web Tokens (JWT), providing a secure and scalable way to manage user sessions. The Gateway is responsible for all JWT validation, while the downstream microservices trust the authenticated requests they receive from the Gateway via the NATS message broker. This design simplifies the microservices, as they do not need to implement their own security guards.
Sources: README.md:21-26, apps/gateway/REFACTORING-GUIDE.md:5-13
Architecture: Perimeter Security
The system's architecture places the API Gateway as the sole gatekeeper. It is responsible for validating all incoming traffic and enforcing security policies. Once a request is authenticated and authorized by the Gateway, it is forwarded to the appropriate microservice over NATS.
This diagram illustrates the security boundary at the API Gateway.
The Gateway's security responsibilities include:
- Authentication: Verifying user identity via JWT (
AuthGuard). - Authorization: Enforcing role-based access control (
RolesGuard). - Rate Limiting: Preventing DDoS and brute-force attacks (
RateLimitMiddleware). - Audit Logging: Recording request details for monitoring and compliance (
AuditLogMiddleware).
Sources: apps/gateway/REFACTORING-GUIDE.md:65-84, apps/gateway/src/app.module.ts:46-49
Authentication Flow
Authentication is handled using asymmetric RSA-signed JWTs. The user-app service is responsible for key generation and token signing, while the Gateway is responsible for token verification.
Key Generation and Distribution
A critical aspect of this security model is the automated distribution of the RSA public key from the user-app to the Gateway. This process ensures the Gateway can verify tokens without needing direct access to the private key.
- Key Generation: The
user-appgenerates an RSA key pair. The private key is stored securely and never leaves the service. - Publication: Upon startup, the
user-apppublishes its public key to a specific NATS subject:auth.public-key. - Subscription & Caching: The Gateway's
KeyReceiverServicesubscribes to this NATS subject. When it receives the public key, it caches it in memory. - Verification: The Gateway's
AuthGuarduses this cached public key to verify the signature of incoming JWTs.
This flow is illustrated in the sequence diagram below.
Token Verification (AuthGuard)
The AuthGuard is a NestJS guard that runs on protected routes within the API Gateway. It performs authentication locally for high performance.
- The guard extracts the Bearer token from the
Authorizationheader of an incoming request. - It uses the
JwtServiceand the cached RSA public key to verify the token's signature and expiration. - If the token is valid, the guard decodes the payload and attaches user information (e.g.,
userId,email,role) to the request object for use by subsequent handlers or guards. - If the token is missing, malformed, or invalid, the guard rejects the request with a
401 Unauthorizedstatus.
The following diagram shows the sequence for a successful authenticated request.
Authorization: Role-Based Access Control (RBAC)
Authorization is managed by the RolesGuard, which works in tandem with the AuthGuard. It ensures that an authenticated user has the necessary permissions to access a specific endpoint.
RolesGuard Logic
The RolesGuard is executed after the AuthGuard has successfully authenticated a user.
- It uses the NestJS
Reflectorto determine the required roles for the endpoint, which are specified using a@Roles()decorator. - If no roles are defined for the endpoint, the guard permits access to any authenticated user.
- It retrieves the user's role from the
request.userobject (attached byAuthGuard). - It checks if the user's role is included in the list of required roles.
- If there is a match, access is granted. If not, the guard throws a
403 Forbiddenexception with a detailed error message.
This flowchart outlines the decision-making process of the RolesGuard.
Integration tests confirm that if a CUSTOMER tries to access an ADMIN-only endpoint, they receive a 403 Forbidden response with a message like: Access denied. Required roles: ADMIN. Your role: CUSTOMER.
Sources: apps/gateway/test/auth-authorization.integration.spec.ts:129-132, apps/gateway/src/auth/roles.guard.spec.ts:79-82
Additional Security Layers
The Perimeter Security model is reinforced by additional middleware applied globally at the Gateway.
| Middleware | Description | Source File |
|---|---|---|
AuditLogMiddleware | Logs structured data for every request, including method, path, status code, IP, and user ID. | apps/gateway/REFACTORING-GUIDE.md:76-84 |
RateLimitMiddleware | Protects against brute-force and DDoS attacks by limiting the number of requests from a single IP address. | apps/gateway/REFACTORING-GUIDE.md:65-74 |
These middleware components are registered in the AppModule to apply to all incoming routes (*), forming a robust defense-in-depth strategy.
// Source: apps/gateway/src/app.module.ts:46-49
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): void {
consumer.apply(AuditLogMiddleware, RateLimitMiddleware).forRoutes('*');
}
}
Sources: apps/gateway/src/app.module.ts:46-49, apps/gateway/REFACTORING-GUIDE.md:86-90
Summary
The security model of this project is a well-defined Perimeter Security architecture centered on the API Gateway. It leverages strong, modern practices such as RSA-based JWTs for authentication and a clear RBAC system for authorization. The automated public key distribution via NATS is an intelligent design choice that enhances security and scalability. By centralizing security concerns and adding layers like rate limiting and audit logging, the system establishes a strong, maintainable, and secure foundation.