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

@pyush/cipherlock

v1.3.2

Published

Secure local secret-management architecture for NestJS apps with Unix Sockets, Windows Named Pipes, and TPM 2.0 / Apple Secure Enclave binding.

Readme

@pyush/cipherlock

🔒 Secure Local Secret-Management Architecture for NestJS

@pyush/cipherlock is an enterprise-grade secret management library for NestJS applications. It completely eliminates sensitive plaintext .env files and process.env leaks by serving secrets on-demand over OS-authenticated local IPC channels (Unix Domain Sockets & Windows Named Pipes) with hardware-backed encryption (TPM 2.0 & Apple Secure Enclave).

License: MIT npm version


Key Features

  • 🛡️ Zero .env Usage: Eliminates .env files and static secret text on disk.
  • 🔒 Zero process.env Leaks: Secrets are never loaded into process environment variables.
  • 🔑 Hardware Key Binding: Vault keys are sealed using physical TPM 2.0 (Linux/Windows) or Apple Secure Enclave (macOS).
  • 🚀 Cross-Platform IPC: Automatic platform detection (UnixSocketTransport on Linux/macOS, WindowsNamedPipeTransport on Windows).
  • ⚡ Cloud Provider Integration: Built-in support for HashiCorp Vault, AWS Secrets Manager, and GCP Secret Manager with in-memory TTL caching.
  • 🛡️ Kernel Peer Authentication: Authenticates callers at the OS kernel level (SO_PEERCRED / /proc/<pid>/exe), ignoring untrusted JSON headers.

Installation

npm install @pyush/cipherlock

Quick Start Guide

1. Store a Secret in Local Credential Store

npx @pyush/cipherlock secrets:set -- DATABASE_PASSWORD "my-super-secret-password"

2. Start Local Secret Broker Daemon

npx @pyush/cipherlock broker:start

3. Register Module in NestJS (app.module.ts)

import { Module } from '@nestjs/common';
import { SecretsModule } from '@pyush/cipherlock';

@Module({
  imports: [SecretsModule],
})
export class AppModule {}

4. Consume Secrets in Application Entrypoint (src/main.ts)

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SecretsService } from '@pyush/cipherlock';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 1. Resolve SecretsService instance from NestJS Application Context
  const secretsService = app.get(SecretsService);

  // 2. Retrieve PORT and HOST directly over local IPC without try/catch
  const port = Number.parseInt(
    (await secretsService.get('PORT')) ?? '3000',
    10,
  );
  const host = (await secretsService.get('HOST')) ?? 'localhost';

  // 3. Start application server without process.env leaks
  await app.listen(port, host);
  console.log(`[APP] Application listening on http://${host}:${port}`);
}
void bootstrap();

CLI Management Tool

The package includes the cipherlock CLI binary executable for managing credentials and starting the broker daemon:

# 1. Set a single secret in the encrypted credential store
npx @pyush/cipherlock secrets:set PORT "3000"
# Output: [OK] Secret 'PORT' stored securely in OS credential store.

# 2. Set multiple secrets at once (set-many)
npx @pyush/cipherlock secrets:set-many PORT "3000" HOST "localhost" DB_NAME "prod_db"
# Output: [OK] Stored 3 secrets (PORT, HOST, DB_NAME) securely in OS credential store.

# 3. Retrieve a secret via CLI
npx @pyush/cipherlock secrets:get PORT
# Output: [OK] PORT = 3000

# 4. Store a complex JSON payload
npx @pyush/cipherlock secrets:set DB_CONFIG '{"host":"localhost","port":5432,"user":"admin"}'
# Output: [OK] Secret 'DB_CONFIG' stored securely in OS credential store.

# 5. Delete a single secret from the credential store
npx @pyush/cipherlock secrets:delete PORT
# Output: [OK] Secret 'PORT' deleted from OS credential store.

# 6. Delete multiple secrets at once (delete-many)
npx @pyush/cipherlock secrets:delete-many PORT HOST DB_NAME
# Output: [OK] Deleted 3 secrets (PORT, HOST, DB_NAME) from OS credential store.

# 7. Launch the Secret Broker Daemon
npx @pyush/cipherlock broker:start
# Output: [BROKER] Secret Broker listening on /tmp/cipherlock/broker.sock

# 8. Stop the Secret Broker Daemon
npx @pyush/cipherlock broker:stop
# Output: [OK] Secret broker daemon socket removed.

Concurrent Development Workflow (package.json)

To automatically launch the secret broker daemon alongside NestJS in watch mode and shut down both services cleanly when pressing Ctrl+C, install concurrently and add the --kill-others flag:

npm install --save-dev concurrently

Update your package.json:

"scripts": {
  "start:dev": "concurrently --kill-others \"npx @pyush/cipherlock broker:start\" \"nest start --watch\""
}

Now running npm run start:dev starts both the Secret Broker Daemon and NestJS. When you terminate with Ctrl+C, concurrently terminates both child processes and unlinks the Unix socket.


Automated Background Service Setup (systemd)

Instead of starting the broker manually in a terminal, you can run it as an automatic background service under your Linux OS user.

Create ~/.config/systemd/user/cipherlock-broker.service:

[Unit]
Description=CipherLock Secret Broker Daemon
After=network.target

[Service]
ExecStart=/usr/bin/npx @pyush/cipherlock broker:start
Restart=always
RestartSec=3
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=default.target

Enable and start the background service:

systemctl --user daemon-reload
systemctl --user enable cipherlock-broker --now

Check service status anytime:

systemctl --user status cipherlock-broker

NestJS ConfigService Integration Patterns

@pyush/cipherlock fully supports NestJS @nestjs/config across 3 flexible patterns:

Pattern 1: Asynchronous Config Loader (createCipherlockConfig)

import { ConfigModule } from '@nestjs/config';
import { createCipherlockConfig } from '@pyush/cipherlock';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [createCipherlockConfig(['PORT', 'HOST', 'DATABASE_PASSWORD'])],
    }),
  ],
})
export class AppModule {}

Pattern 2: Custom CipherlockConfigService Injection

import { CipherlockConfigService, SecretsModule } from '@pyush/cipherlock';

@Injectable()
export class DatabaseService {
  constructor(private readonly configService: CipherlockConfigService) {}

  async connect() {
    const dbPassword = await this.configService.get('DATABASE_PASSWORD');
  }
}

Pattern 3: 1-Line CipherlockConfigModule Dynamic Module

import { CipherlockConfigModule } from '@pyush/cipherlock';

@Module({
  imports: [CipherlockConfigModule.forRoot({ isGlobal: true })],
})
export class AppModule {}

Dynamic PolicyEngine & Custom Security ACLs

@pyush/cipherlock includes a built-in PolicyEngine that controls process-level access permissions to secrets based on OS kernel peer authentication (SO_PEERCRED).

1. Registering Custom Roles and Permissions Dynamically

import { PolicyEngine, ClientIdentity } from '@pyush/cipherlock';

// Instantiate PolicyEngine (set allowAllForOwner to false to enforce strict role rules)
const policyEngine = new PolicyEngine({}, false);

// 1. Register role-based whitelists
policyEngine.registerPolicy('payment-service', ['STRIPE_KEY', 'DATABASE_URL']);
policyEngine.registerPolicy('user-service', ['PORT', 'HOST', 'JWT_SECRET']);

// 2. Register wildcard '*' administrative policy
policyEngine.registerPolicy('super-admin', ['*']);

// 3. Evaluate identity permissions
const caller: ClientIdentity = { uid: 1001, gid: 1001, role: 'payment-service' };

console.log(policyEngine.isAllowed(caller, 'STRIPE_KEY'));   // true
console.log(policyEngine.isAllowed(caller, 'JWT_SECRET'));   // false

2. Passing Custom PolicyEngine to SecretBrokerServer

If you are running a custom Secret Broker Daemon inside your application or infrastructure:

import { SecretBrokerServer, PolicyEngine } from '@pyush/cipherlock';

const customPolicy = new PolicyEngine();
customPolicy.registerPolicy('analytics-app', ['CLICKHOUSE_URL', 'REDIS_HOST']);

// Pass custom PolicyEngine to SecretBrokerServer
const server = new SecretBrokerServer('/tmp/custom-broker.sock', customPolicy);
await server.start();

3. Extending PolicyEngine for Custom Application Logic

You can extend PolicyEngine to pull permission rules from a database, remote RBAC server, or custom logic:

import { PolicyEngine, ClientIdentity } from '@pyush/cipherlock';

export class DatabaseBackedPolicyEngine extends PolicyEngine {
  private allowedSecrets = new Set(['PORT', 'HOST', 'CUSTOM_APP_SECRET']);

  public override isAllowed(identity: ClientIdentity, secretName: string): boolean {
    // Custom check: Root user UID 0 has full access
    if (identity.uid === 0) {
      return true;
    }
    // Whitelist check
    return this.allowedSecrets.has(secretName);
  }
}

License

MIT License © 2026 CipherLock Contributors