Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ricardomb-tech/auth-service/llms.txt

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

Auth Service implements a classic email-and-password credential flow in four stages: a user registers an account, confirms their email address via a single-use token, logs in with their verified credentials, and then uses the issued JWT access token to access protected resources. Every step is designed with a security-first posture — enumeration of existing accounts is deliberately prevented at the registration and verification-resend endpoints, and a single, indistinguishable error is returned for all credential failures at login.

Full authentication flow

1

Register an account

Submit the user’s email and password. Auth Service creates the account in PENDING_VERIFICATION state and sends a verification email. The response is always 202 Accepted with the same generic body, regardless of whether the email already exists — this is an intentional anti-enumeration control.
curl -X POST https://your-auth-service/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "s3cur3P@ssword"
  }'
Response — 202 Accepted
{
  "message": "Si el email es válido, recibirás un correo de verificación."
}
The password is validated in the domain layer against the RawPassword value object. The only hard limit enforced at the HTTP layer (before the domain even runs) is a maximum of 72 characters — bcrypt silently truncates input beyond that boundary, so the limit is a defense-in-depth guard. Format rules (minimum length, complexity) are owned by the domain.
2

Verify the email address

The verification email contains a link that carries a single-use token. Your frontend extracts that token and posts it to /auth/verify. A successful response means the account is now ACTIVE. Unlike registration, this endpoint does return a distinguishable 400 on failure — the caller already possesses the token, so there is no enumeration risk.
curl -X POST https://your-auth-service/auth/verify \
  -H "Content-Type: application/json" \
  -d '{
    "token": "<verification-token-from-email>"
  }'
Response — 200 OK
{
  "message": "Tu cuenta ha sido verificada. Ya puedes iniciar sesión."
}
If the verification token is invalid, expired, or already consumed, the service returns 400 Bad Request with a application/problem+json body.Resend a verification emailIf the user needs a new verification link, call /auth/resend-verification. Like /auth/register, this endpoint always returns 202 Accepted with a generic body — the same response is returned whether the account exists, is already verified, or never existed.
curl -X POST https://your-auth-service/auth/resend-verification \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com"
  }'
Response — 202 Accepted
{
  "message": "Si el email es válido y está pendiente de verificación, recibirás un correo con un nuevo enlace."
}
3

Log in with credentials

Once the account is ACTIVE, the user can exchange their email and password for an access token and a refresh token.
curl -X POST https://your-auth-service/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "s3cur3P@ssword"
  }'
Response — 200 OK
{
  "accessToken": "eyJhbGciOiJIUzI1NiJ9...",
  "refreshToken": "d3f4a2b1c9e8...",
  "tokenType": "Bearer",
  "expiresInSeconds": 900
}
FieldDescription
accessTokenHS256-signed JWT. Valid for 15 minutes (expiresInSeconds: 900). Stateless — not persisted.
refreshTokenOpaque random value. Valid for 7 days. Stored as a SHA-256 hash in the database.
tokenTypeAlways "Bearer".
expiresInSecondsAccess token TTL in seconds (900 = 15 min).
Login returns a single 401 Unauthorized error — "Email o contraseña incorrectos." — for all failure scenarios: non-existent email, wrong password, unverified account, locked account, and disabled account. This is intentional and matches the anti-enumeration posture of the service. Do not attempt to distinguish failure reasons on the client side; the service will not reveal them.
4

Use the access token

Pass the accessToken as a Bearer token in the Authorization header of every request to protected endpoints.
curl https://your-auth-service/api/v1/users/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..."
The access token expires after 15 minutes. Use the refreshToken to obtain a new pair — see the Token Management guide.

Account statuses

Auth Service models account lifecycle with four statuses. Only ACTIVE accounts can log in or use a refresh token to rotate credentials.

PENDING_VERIFICATION

The account was just registered. Login and token refresh are blocked until the email address is verified.

ACTIVE

The email has been verified. The account can log in and use all authenticated endpoints.

LOCKED

The account has been locked — for example, after a brute-force detection event (Story 3.2, backlog). Login and refresh are blocked.

DISABLED

The account has been administratively disabled (Epic 4, backlog). Login and refresh are blocked.

Roles

Auth Service assigns every account one or more roles, which appear as a roles array in the JWT payload.
RoleDescription
USERDefault role assigned at registration. Grants access to standard user endpoints such as GET /api/v1/users/me.
ADMINElevated role. Required for administrative operations introduced in Epic 4. Assigned manually or via the initial admin provisioning env vars.
Roles are embedded directly in the issued JWT and are propagated to downstream services via the token. See Protecting Endpoints for how to enforce them in your services.

Build docs developers (and LLMs) love