NestJS Guards, Auth & Authorization
Best practices for securing NestJS applications with guards, Passport-based JWT authentication, and role-based authorization. Verified against the current NestJS v10/v11 documentation (guards, authentication, authorization, and the Passport recipe).
The core mental model: authentication (authn) answers "who are you?" and
runs as a guard that validates a credential and attaches a typed user to the
request. Authorization (authz) answers "are you allowed?" and runs as a
separate guard that reads route metadata via Reflector and compares it against
that user. Keep these two concerns in distinct guards, declare a strong JWT
config from the environment, and never leak whether a credential was valid.
When to Apply
Reference these rules when:
- Implementing login / token issuance or protecting routes in NestJS
- Writing or reviewing a
CanActivateguard,AuthGuard, orJwtStrategy - Setting up Passport (
@nestjs/passport+passport-jwt) - Adding role-based access control (
@Roles,RolesGuard) - Registering a global auth guard with per-route opt-out (
@Public) - Reviewing how
req.useris typed, how secrets are configured, or how auth failures are surfaced to clients
Rules
| Rule | Impact | Summary |
|---|---|---|
| separate-authn-from-authz | HIGH | Keep identity verification and permission checks in distinct guards |
| passport-jwt-strategy | HIGH | Use @nestjs/passport + a passport-jwt strategy class for JWT auth |
| global-auth-guard-with-public | HIGH | Register a global auth guard and opt out via @Public() metadata |
| roles-guard-rbac | HIGH | Drive RBAC with @Roles() metadata read by a RolesGuard via Reflector |
| hash-passwords | CRITICAL | Never store plaintext; hash with bcrypt/argon2 + salt |
| type-the-request-user | MEDIUM | Strongly type req.user; never trust an unvalidated payload |
| dont-leak-auth-details | HIGH | Return generic 401/403; don't reveal whether a user exists |
| validate-jwt-config | CRITICAL | Load a strong secret from config/env with sane expiry; verify signature and expiration |
How to Use
Read individual rule files for the rationale and incorrect/correct code:
rules/passport-jwt-strategy.md
rules/roles-guard-rbac.md
Each rule file contains a short explanation of why it matters, followed by an Incorrect and a Correct TypeScript example. Apply CRITICAL and HIGH impact rules first when reviewing existing auth code.