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

@itmcsystemgit/secure-core

v2.0.0

Published

A security toolkit for NestJS backends - AES-256 field encryption, RS256 JWT with a global auth guard, SQL-injection-resistant Prisma access, request validation, rate limiting, and HTTP security defaults.

Readme

@itmcsystemgit/secure-core

A security toolkit for Node.js/NestJS backends, originally built at ITMC Digital. Wire up configuration once per service and every developer gets AES-256 field encryption, RS256 JWT authentication, request validation, SQL-injection protection, rate limiting, and HTTP security hardening — without needing to understand the cryptography underneath.

| | | |---|---| | Package | @itmcsystemgit/secure-core | | Registry | npm — https://www.npmjs.com/package/@itmcsystemgit/secure-core | | License | Apache-2.0 | | Runtime | Node.js, NestJS 10.x |


Table of contents

Features

| Feature | What it does | |---|---| | Field encryption | AES-256-GCM encryption for individual DB columns, with versioned keys for safe rotation | | Prisma encryption middleware | Encrypts/decrypts configured model fields automatically on create, update, and updateMany | | JWT authentication | RS256 signing/verification; a global guard requires a valid token on every route by default | | Request validation | A hardened ValidationPipe preset that blocks mass-assignment attacks | | SQL-injection guard | Disables $queryRawUnsafe/$executeRawUnsafe on a Prisma client at runtime | | Rate limiting | Pre-tuned @nestjs/throttler presets for auth, standard, and public routes | | HTTP security defaults | helmet response headers and a locked-down-by-default CORS policy | | Secrets loading | Fetches encryption/JWT keys from AWS Secrets Manager, with in-memory caching |

Requirements

This package expects the following as peer dependencies in the consuming project:

  • @nestjs/common ^10.0.0
  • @nestjs/core ^10.0.0
  • class-validator ^0.14.0
  • class-transformer ^0.5.1

Installation

Published on the public npm registry — no authentication or special configuration needed:

npm install @itmcsystemgit/secure-core

Getting started

1. Generate keys (one time)

Run once, typically by a senior developer or DevOps — not by every engineer:

import { FieldEncryption, SecureJwtService } from '@itmcsystemgit/secure-core';

console.log('Encryption key:', FieldEncryption.generateKey());
console.log('JWT key pair:', SecureJwtService.generateKeyPair());

Store the output in AWS Secrets Manager, e.g. under myapp/prod/security-keys:

{
  "encryptionKeys": { "v1": "<64 hex chars>" },
  "activeKeyVersion": "v1",
  "jwtPrivateKey": "-----BEGIN PRIVATE KEY-----...",
  "jwtPublicKey": "-----BEGIN PUBLIC KEY-----..."
}

Only the auth service needs jwtPrivateKey. Every other service in your system only needs jwtPublicKey to verify tokens — never distribute the private key beyond the auth service.

2. Wire up the module (per service)

app.module.ts:

import { SecureModule, SecretsLoader } from '@itmcsystemgit/secure-core';

@Module({
  imports: [
    SecureModule.forRootAsync(async () => {
      const secrets = await new SecretsLoader().load('myapp/prod/security-keys');
      return {
        encryptionKeys: secrets.encryptionKeys,
        activeEncryptionKeyVersion: secrets.activeKeyVersion,
        jwtPublicKey: secrets.jwtPublicKey,
        jwtPrivateKey: secrets.jwtPrivateKey, // omit in services that don't issue tokens
        jwtIssuer: 'my-auth-service',
      };
    }),
  ],
})
export class AppModule {}

Importing SecureModule protects every route by default. It registers a global JWT guard — any request without a valid Authorization: Bearer <token> header receives a 401 automatically, on every controller in the app. Routes that must stay open (login, token refresh, health checks) opt out explicitly:

import { Public } from '@itmcsystemgit/secure-core';

@Public()
@Post('login')
login(@Body() dto: LoginDto) { ... }

3. Apply HTTP security defaults

main.ts:

import { SecureValidationPipe, applySecurityDefaults } from '@itmcsystemgit/secure-core';

app.useGlobalPipes(new SecureValidationPipe());
applySecurityDefaults(app, { corsOrigins: ['https://your-frontend.example.com'] });

applySecurityDefaults adds security response headers (via helmet) and locks CORS down to the origins you list — pass nothing and cross-origin requests are rejected entirely until you explicitly allow some.

Usage guide

Read the logged-in user

JWT verification already happened in the global guard — no manual verify() call needed in a handler:

import { CurrentUser } from '@itmcsystemgit/secure-core';

@Get('me')
getProfile(@CurrentUser() user: { userId: string; role: string }) {
  return user;
}

Only reach for SECURE_JWT_SERVICE directly when verifying a token outside the normal request/response cycle (e.g. a WebSocket handshake, a background job).

Encrypt a field manually

constructor(@Inject(FIELD_ENCRYPTION) private secure: FieldEncryption) {}

const encryptedSalary = this.secure.encrypt('85000');
const salary = this.secure.decrypt(encryptedSalary);

Encrypt fields automatically via Prisma (recommended)

In your PrismaService:

import { createEncryptionMiddleware } from '@itmcsystemgit/secure-core';

this.$use(createEncryptionMiddleware(secureInstance, {
  Employee: ['salary', 'bankAccountNumber', 'panNumber'],
  Driver: ['licenseNumber', 'aadhaarNumber'],
}));

After this, prisma.employee.create(...) and .findMany(...) just work — encryption and decryption happen invisibly.

Guard a raw Prisma client against SQL injection

import { forbidUnsafeRawQueries } from '@itmcsystemgit/secure-core';

const prisma = forbidUnsafeRawQueries(new PrismaClient());
// prisma.$queryRawUnsafe(...) / $executeRawUnsafe(...) now throw immediately
// prisma.$queryRaw`...` / $executeRaw`...` (parameterized) still work fine

Rate-limit a route

import { RateLimitPresets } from '@itmcsystemgit/secure-core';

ThrottlerModule.forRoot(RateLimitPresets.auth)

Security checklist

| Don't | Do | |---|---| | Use prisma.$queryRawUnsafe / $executeRawUnsafe with string interpolation | Wrap your Prisma client with forbidUnsafeRawQueries() so this is a hard error, not just a convention | | Put encryption keys or JWT private keys in .env files or commit them | Load them from AWS Secrets Manager via SecretsLoader | | Write custom crypto.createCipher(...) calls | Use FieldEncryption | | Store JWTs in localStorage (web) or SharedPreferences (Flutter) | Use httpOnly cookies (web) or flutter_secure_storage (Flutter) | | — | Mark every new sensitive DB column in the Prisma encryption middleware config | | — | Use DTOs with class-validator decorators on every endpoint |

Key rotation

When it's time to rotate the AES encryption key:

  1. Generate a new key: FieldEncryption.generateKey()
  2. Add it to Secrets Manager as a new version, e.g. v2, keeping v1
  3. Set activeKeyVersion: 'v2' — new writes use v2; old data still decrypts fine via v1 (each stored value records which key version encrypted it)
  4. Optionally run a background job to re-encrypt old rows with v2, then remove v1 once done