From harness-claude
Implements NestJS guards for route protection using @UseGuards, CanActivate, JWT, and role-based access control.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:nestjs-guards-patternThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Protect routes with @UseGuards, CanActivate, JWT guards, and role-based access control
Protect routes with @UseGuards, CanActivate, JWT guards, and role-based access control
CanActivate and return true (allow) or false/throw (deny):@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private jwtService: JwtService) {}
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest<Request>();
const token = this.extractToken(request);
if (!token) throw new UnauthorizedException();
try {
request['user'] = this.jwtService.verify(token, { secret: process.env.JWT_SECRET });
return true;
} catch {
throw new UnauthorizedException();
}
}
private extractToken(req: Request): string | undefined {
const [type, token] = req.headers.authorization?.split(' ') ?? [];
return type === 'Bearer' ? token : undefined;
}
}
@UseGuards(GuardClass) at the controller or handler level. Handler-level overrides controller-level.main.ts for app-wide auth: app.useGlobalGuards(new JwtAuthGuard(jwtService)). For DI in global guards, use APP_GUARD provider instead:providers: [{ provide: APP_GUARD, useClass: JwtAuthGuard }];
Reflector and custom decorators to build a roles guard:export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const required = this.reflector.getAllAndOverride<string[]>('roles', [
context.getHandler(),
context.getClass(),
]);
if (!required) return true; // no roles required
const { user } = context.switchToHttp().getRequest();
return required.some((role) => user?.roles?.includes(role));
}
}
@Public() with a SetMetadata('isPublic', true) decorator to bypass global auth guards on specific routes.ExecutionContext is transport-agnostic — use context.switchToWs() for WebSockets and context.switchToRpc() for microservices.Guards run after middleware but before interceptors and pipes in the NestJS request lifecycle. They are the correct place for authorization decisions because they have access to ExecutionContext, which provides the handler and class metadata.
Guard vs Middleware: Middleware runs before routing and has no knowledge of which handler will process the request. Guards run after routing with full handler context, making them the right tool for authorization logic that depends on route metadata (roles, permissions).
Throwing vs returning false: Throwing UnauthorizedException (or any HttpException) is preferred over returning false. Returning false causes NestJS to throw a generic ForbiddenException (403), which may not communicate the correct HTTP status.
Multiple guards: @UseGuards(AuthGuard, RolesGuard) applies guards in order. If AuthGuard throws, RolesGuard never runs. Compose authentication and authorization as separate guards for clean separation of concerns.
Passport integration: @nestjs/passport provides AuthGuard('jwt'), AuthGuard('local'), etc. that wrap Passport strategies. Use it when you need OAuth2, SAML, or complex multi-strategy auth flows.
https://docs.nestjs.com/guards
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeImplements NestJS guards and interceptors for authentication, authorization, logging, and request/response transformation. Covers CanActivate, ExecutionContext, and JWT patterns for cross-cutting concerns.
NestJS decorator usage: built-in route/param/class decorators, custom decorators via `createParamDecorator` and `SetMetadata`, metadata reflection via `Reflector`. Apply when designing controllers, guards, interceptors, or custom decorators. Use this skill to: - Pick the right built-in decorator for routes, params, and DI. - Compose decorators (`@UseGuards(A, B) @UseInterceptors(C)`). - Build custom param decorators (e.g., `@CurrentUser()`). - Use metadata for role-based logic (Reflector + SetMetadata). - Avoid common decorator mistakes. Do NOT use this skill for: - General module/DI patterns (see nest-conventions). - GraphQL-specific decorators (see nest-advanced). - ORM entity decorators (see nest-data-layer).
Guides NestJS architecture with modular design, dependency injection, guards, interceptors, pipes, DTOs, and MongoDB/Mongoose patterns for building and debugging APIs.