Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/LMendoza70/SSA/llms.txt

Use this file to discover all available pages before exploring further.

Security is the highest-priority quality attribute in the SSA Health Platform. Before any business logic executes, every endpoint validates three things in strict order: that the requester is who they claim to be (authentication), that they are allowed to perform the requested action (authorization), and that the data they have submitted is well-formed and safe (DTO validation and sanitization). This layered defense ensures that no unsafe input ever reaches service or domain code, and that no unauthorized actor can invoke a protected operation.

Token Strategy

The platform uses a dual-token strategy to balance security with usability. Short-lived access tokens limit the blast radius of a compromised credential, while longer-lived refresh tokens allow sessions to persist without forcing users to re-enter their passwords repeatedly.

Access Token

A signed JWT with a 15-minute expiry. Contains the user’s ID and assigned roles. Signed with JWT_SECRET. Sent in the Authorization: Bearer header on every request.

Refresh Token

A longer-lived JWT with a 7-day expiry. Used exclusively to obtain a new access token when the current one expires. Never exposed to JavaScript — stored only in an HttpOnly cookie.

HttpOnly Cookie

The refresh token is delivered and stored as an HttpOnly cookie, making it invisible to browser JavaScript. This is the primary defense against XSS-based token theft.
Access tokens travel in request headers; refresh tokens travel only in HttpOnly cookies. These two channels should never be mixed.

Password Security

User passwords are hashed using Argon2, a memory-hard algorithm and winner of the Password Hashing Competition. Argon2 is designed to be computationally expensive for attackers even with specialized hardware, making brute-force and rainbow-table attacks impractical.
1

Receive password

The raw password arrives over HTTPS in the request body. It is never written to any log or persisted in plaintext.
2

Hash with Argon2

NestJS calls Argon2 to produce a salted, memory-hard hash. The salt is embedded in the hash output automatically.
3

Store hash only

Only the Argon2 hash is persisted in the users table. The original password is discarded immediately after hashing.
4

Verify on login

At login time, Argon2 re-hashes the submitted password and compares it to the stored hash in constant time, preventing timing-based attacks.
Passwords must never be stored in plaintext, echoed in API responses, or written to application logs under any circumstances.

Auth Endpoints

The Authentication Module exposes three public endpoints. All other endpoints in the platform require a valid access token.

Login

Authenticates a user with their email and password. On success, returns a signed access token in the response body and sets the refresh token as an HttpOnly cookie.
POST /auth/login
Content-Type: application/json

{
  "email": "admin@ssa.gob.mx",
  "password": "yourpassword"
}
Success response — 200 OK:
{
  "accessToken": "eyJ...",
  "user": {
    "id": "uuid",
    "email": "admin@ssa.gob.mx",
    "roles": ["admin"]
  }
}
The refresh token is automatically set as an HttpOnly cookie named refresh_token. The client does not need to handle it explicitly.

Refresh

Accepts the refresh token cookie and issues a new access token. No request body is required — the browser sends the cookie automatically.
POST /auth/refresh
Success response — 200 OK:
{
  "accessToken": "eyJ..."
}
Clients should call /auth/refresh whenever a request returns 401 Unauthorized. Use an Axios response interceptor or TanStack Query’s onError callback to handle this automatically.

Logout

Clears the refresh token cookie server-side, invalidating the session. The client should also discard the access token from memory.
POST /auth/logout
Success response — 200 OK:
{
  "message": "Logged out successfully"
}

Authorization

Authentication confirms identity; authorization confirms permission. Every request passes through this pipeline before reaching business logic:
1

Authentication Guard

Validates the JWT signature and expiry. Attaches the decoded user payload to the request context. Rejects with 401 if the token is missing, expired, or tampered.
2

Authorization Guard

Checks the user’s roles against the roles required by the route decorator. Rejects with 403 if the user lacks the required role.
3

DTO Validation Pipe

class-validator decorators on the DTO class validate shape, type, length, and format constraints. Rejects with 400 if validation fails.
4

Sanitization

String inputs are sanitized to strip script tags and other dangerous characters before being passed to the service layer.
The platform defines three roles:
RolePermissions
adminFull access — create, read, update, delete, configure
editorCreate and update content; cannot delete or configure the system
viewerRead-only access to published content
Authorization logic lives exclusively in NestJS Guards and route decorators. Controllers must never contain if (user.role === ...) checks. This keeps the authorization model consistent and auditable.

Security Rules

Never trust client-supplied data. All inputs must be validated via DTOs and sanitized before processing.
The following rules are non-negotiable and apply to every module in the platform:
  • All endpoints require authentication unless explicitly decorated as public with @Public()
  • DTOs are validated with class-validator on every mutating request
  • No secrets in source code — all sensitive values must come from environment variables
  • Tokens are never logged — neither access tokens nor refresh tokens appear in any log output
  • Soft delete for audit preservation — records are never physically removed; deletedAt is set instead, maintaining a full audit trail for compliance purposes
  • No any in TypeScript — strict typing is enforced across the entire codebase (strict: true)
  • No business logic in controllers — controllers route requests; services own the logic

Environment Variables

The following environment variables must be configured before starting the backend. All values should be stored in .env (never committed to version control).
JWT_SECRET=your-secret-key
JWT_REFRESH_SECRET=your-refresh-secret
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
Use a cryptographically secure random string of at least 64 characters for both JWT_SECRET and JWT_REFRESH_SECRET. You can generate one with openssl rand -hex 64.

Architecture Overview

How authentication fits into the broader modular monolith and Clean Architecture layers.

API Conventions

Request and response formats, HTTP status codes, and error handling across the platform.

Deployment

How environment variables, secrets, and token configuration are managed in production.

Build docs developers (and LLMs) love