docs(adr): convert all ADRs to MADR 2.1.2 format
Rewrites all 7 backend ADRs from a custom structure to the MADR 2.1.2 template required by the VS Code ADR Manager extension: bullet metadata (Status/Date), standardised section headings, "Chosen option: X, because Y" wording, and explicit Pros/Cons blocks per option.
This commit is contained in:
@@ -1,28 +1,53 @@
|
||||
# ADR 0006: Authentication — JWT with express-jwt
|
||||
# Use JWT for API authentication
|
||||
|
||||
**Date:** 2026-04-26
|
||||
**Status:** Accepted
|
||||
* Status: accepted
|
||||
* Date: 2026-04-26
|
||||
|
||||
## Context
|
||||
## Context and Problem Statement
|
||||
|
||||
The API must authenticate requests from the Angular frontend. Options considered:
|
||||
- **Session-based auth** — server stores session state; requires sticky sessions or shared session store in multi-instance deployments.
|
||||
- **JWT (JSON Web Tokens)** — stateless; token carries the user identity; no server-side session storage.
|
||||
The API must authenticate requests from the Angular frontend. How should user identity be verified on each request?
|
||||
|
||||
Given that the application is currently single-instance with no horizontal scaling requirement, either would work. JWT is simpler to operate and aligns with the frontend's existing token-based auth flow.
|
||||
## Decision Drivers
|
||||
|
||||
## Decision
|
||||
* Application is currently single-instance with no horizontal scaling requirement.
|
||||
* Frontend already uses token-based auth (stores JWT in `localStorage` — see frontend ADR 0005).
|
||||
* Simplicity of operation is preferred over session infrastructure.
|
||||
|
||||
Use JWT for authentication:
|
||||
- Tokens are issued by the API on successful login (`jsonwebtoken` library, `bcrypt` for password hashing).
|
||||
- Incoming requests are validated by the `express-jwt` middleware, which populates `req.auth` with the decoded token payload.
|
||||
- The `src/middlewares/auth.js` middleware wraps `express-jwt` and handles role-based access control (`Admin` role required for protected admin routes).
|
||||
## Considered Options
|
||||
|
||||
The frontend stores the token in `localStorage` and sends it as `Authorization: Token <jwt>` (see frontend ADR 0005).
|
||||
* JWT (JSON Web Tokens) with `express-jwt`
|
||||
* Session-based authentication
|
||||
|
||||
## Consequences
|
||||
## Decision Outcome
|
||||
|
||||
- **Positive:** Stateless — no session store needed. Horizontally scalable without sticky sessions.
|
||||
- **Positive:** Single middleware handles auth for all routes.
|
||||
- **Negative:** Tokens cannot be invalidated server-side before expiry. Acceptable for this use case (internal application, low revocation risk).
|
||||
- **Security:** Passwords are hashed with `bcrypt`. The JWT secret must be kept in environment configuration, never committed.
|
||||
Chosen option: "JWT", because it is stateless (no session store needed), aligns with the frontend's existing token-based auth flow, and is simpler to operate for a single-instance deployment.
|
||||
|
||||
Tokens are issued on successful login (`jsonwebtoken` library, `bcrypt` for password hashing). Incoming requests are validated by `express-jwt`, which populates `req.auth` with the decoded payload. The `src/middlewares/auth.js` middleware wraps `express-jwt` and handles role-based access control (`Admin` role required for protected admin routes). The frontend sends tokens as `Authorization: Token <jwt>`.
|
||||
|
||||
### Positive Consequences
|
||||
|
||||
* Stateless — no session store needed. Horizontally scalable without sticky sessions.
|
||||
* Single middleware handles auth for all routes.
|
||||
|
||||
### Negative Consequences
|
||||
|
||||
* Tokens cannot be invalidated server-side before expiry. Acceptable for this use case (internal application, low revocation risk).
|
||||
|
||||
## Pros and Cons of the Options
|
||||
|
||||
### JWT
|
||||
|
||||
* Good, because stateless — no session store infrastructure.
|
||||
* Good, because works seamlessly with the frontend's `localStorage`-based token flow.
|
||||
* Bad, because revocation requires token blacklisting, which adds state.
|
||||
|
||||
### Session-based authentication
|
||||
|
||||
* Good, because sessions can be invalidated immediately server-side.
|
||||
* Bad, because requires a session store (Redis or database-backed) — adds infrastructure complexity.
|
||||
* Bad, because sticky sessions or a shared store are needed in multi-instance deployments.
|
||||
|
||||
## Links
|
||||
|
||||
* Related to frontend [ADR 0005](../../adastra_app/docs/decisions/0005-jwt-authentication-localstorage.md)
|
||||
* Security note: passwords are hashed with `bcrypt`. The JWT secret must be kept in environment configuration, never committed.
|
||||
|
||||
Reference in New Issue
Block a user