npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pafrtds/nest-keycloak-connect

v1.0.2

Published

keycloak-nodejs-connect module for Nest - compatible with NestJS 11

Readme

@pafrtds/nest-keycloak-connect

A Keycloak authentication and authorization module for NestJS, powered by jose.

NPM Version GitHub License

Compatibility

| Package version | NestJS version | | --------------- | -------------- | | 1.x | 10, 11 |

This package is fully compatible with NestJS 11 and uses jose for JWT validation instead of the deprecated keycloak-nodejs-connect.

Features

  • Protect your resources using Keycloak's Authorization Services.
  • Simply add @Resource, @Scopes, @Roles, or @Groups in your controllers and you're good to go.
  • JWT validation via JWKS using jose — no deprecated dependencies.
  • Online token validation cache to avoid hitting Keycloak on every request.
  • Compatible with Fastify platform.
  • Compatible with NestJS 11.

Installation

npm install @pafrtds/nest-keycloak-connect --save

Getting Started

Module registration

import {
  KeycloakConnectModule,
  PolicyEnforcementMode,
  TokenValidation,
} from '@pafrtds/nest-keycloak-connect';

KeycloakConnectModule.register({
  authServerUrl: 'http://localhost:8080',
  realm: 'master',
  clientId: 'my-nestjs-app',
  secret: 'secret',
  policyEnforcement: PolicyEnforcementMode.PERMISSIVE, // optional
  tokenValidation: TokenValidation.ONLINE,             // optional
});

Async registration:

KeycloakConnectModule.registerAsync({
  useExisting: KeycloakConfigService,
  imports: [ConfigModule],
});

KeycloakConfigService

import { Injectable } from '@nestjs/common';
import {
  KeycloakConnectOptions,
  KeycloakConnectOptionsFactory,
  PolicyEnforcementMode,
  TokenValidation,
} from '@pafrtds/nest-keycloak-connect';

@Injectable()
export class KeycloakConfigService implements KeycloakConnectOptionsFactory {
  createKeycloakConnectOptions(): KeycloakConnectOptions {
    return {
      authServerUrl: 'http://localhost:8080',
      realm: 'master',
      clientId: 'my-nestjs-app',
      secret: 'secret',
      policyEnforcement: PolicyEnforcementMode.PERMISSIVE,
      tokenValidation: TokenValidation.ONLINE,
    };
  }
}

Guards

Register globally via APP_GUARD (recommended order):

providers: [
  { provide: APP_GUARD, useClass: AuthGuard },
  { provide: APP_GUARD, useClass: ResourceGuard },
  { provide: APP_GUARD, useClass: RoleGuard },
  { provide: APP_GUARD, useClass: GroupGuard },
];

Or scoped to a controller:

@Controller('cats')
@UseGuards(AuthGuard, ResourceGuard)
export class CatsController {}

Guards

AuthGuard

Returns 401 Unauthorized when the JWT is missing or invalid. Validates tokens against Keycloak's JWKS endpoint.

ResourceGuard

Enforces resource-level permissions via Keycloak's UMA authorization endpoint. Requires @Resource + @Scopes on the controller/method.

RoleGuard

Checks realm or client roles from the token claims. Requires @Roles on the method.

GroupGuard

Checks group membership from the groups claim in the JWT. Requires @Groups on the method.

To enable the groups claim: Keycloak → Client → Client scopes → Add mapper → Group Membership → Token Claim Name: groups

Configuring controllers

import {
  Resource, Roles, Scopes, Groups, Public,
  RoleMatchingMode, GroupMatchingMode, GroupMatch,
} from '@pafrtds/nest-keycloak-connect';

@Controller()
@Resource('product')
export class ProductController {

  @Get()
  @Public()
  async findAll() { ... }

  @Get(':id')
  @Scopes('view')
  async findOne() { ... }

  @Post()
  @Scopes('create')
  @Roles({ roles: ['manager', 'realm:admin'] })
  async create() { ... }

  @Delete(':id')
  @Scopes('delete')
  @Groups('/org/admins')
  async remove() { ... }

  @Put(':id')
  @Scopes('edit')
  @Groups('/org/admins', '/org/editors')
  @GroupMatchingMode(GroupMatch.ALL) // must belong to BOTH groups
  async update() { ... }
}

Token Validation Cache

Caches online validation results to avoid calling Keycloak on every request. The TTL is derived from the token's exp claim.

Note: revoked tokens may be accepted until the cache entry expires. Use a short maxTtl in environments requiring immediate revocation.

KeycloakConnectModule.register({
  // ...
  tokenValidation: TokenValidation.ONLINE,
  tokenCache: {
    enabled: true,
    maxTtl: 30, // max 30 seconds, regardless of token lifetime
  },
});

To manually invalidate a token (e.g. after logout):

constructor(private readonly tokenCache: KeycloakTokenCacheService) {}

async logout(accessToken: string) {
  this.tokenCache.invalidate(accessToken);
}

Decorators

| Decorator | Description | | -------------------- | ------------------------------------------------------------------------- | | @KeycloakUser | Retrieves the current Keycloak user from the request. | | @AccessToken | Retrieves the raw access token string from the request. | | @ResolvedScopes | Retrieves the resolved scopes (used with @ConditionalScopes). | | @EnforcerOptions | Keycloak enforcer options for ResourceGuard. | | @Public | Allows unauthenticated access to the route. | | @Resource | Keycloak resource name (used with ResourceGuard). | | @Scopes | Required scopes on a resource (used with ResourceGuard). | | @ConditionalScopes | Dynamic scopes resolved at request time. | | @Roles | Required realm or client roles (used with RoleGuard). | | @RoleMatchingMode | Sets RoleMatch.ANY (default) or RoleMatch.ALL for @Roles. | | @Groups | Required Keycloak group membership (used with GroupGuard). | | @GroupMatchingMode | Sets GroupMatch.ANY (default) or GroupMatch.ALL for @Groups. |

Token Validation Modes

| Mode | Description | | --------- | -------------------------------------------------------------------------------------------- | | ONLINE | Verifies JWT signature via JWKS and calls Keycloak's introspection endpoint per request. Detects revoked tokens. | | OFFLINE | Verifies JWT signature via JWKS only. Fast, no per-request Keycloak calls. Does not detect revocation. | | NONE | Skips all validation. Use only in development or internal trusted networks. |

Configuration options

| Option | Description | Default | | ----------------- | --------------------------------------------------------------------------- | ------------ | | authServerUrl | Keycloak server URL | required | | realm | Realm name | required | | clientId | Client/Application ID | required | | secret | Client secret | required | | cookieKey | Cookie key for JWT extraction | KEYCLOAK_JWT | | policyEnforcement | PERMISSIVE or ENFORCING for ResourceGuard | PERMISSIVE | | tokenValidation | ONLINE, OFFLINE, or NONE | ONLINE | | tokenCache | Cache config: { enabled, maxTtl? } | disabled | | multiTenant | Multi-tenant options | — | | roleMerge | OVERRIDE or ALL for @Roles merge strategy | OVERRIDE |

Multi-tenant configuration

KeycloakConnectModule.register({
  authServerUrl: 'http://localhost:8080',
  clientId: 'nest-api',
  secret: 'fallback-secret',
  multiTenant: {
    realmResolver: (request) => request.get('host').split('.')[0],
    realmSecretResolver: (realm) => secretsMap[realm],
    realmClientIdResolver: (realm) => clientIdMap[realm],
    realmAuthServerUrlResolver: (realm) => authServerUrlMap[realm],
  },
});

License

MIT — Copyright (c) 2020 John Joshua Ferrer, 2026 Lucas Paes