Skip to content

duabalabs/dps-secure-keys

Repository files navigation

@duabalabs/secure-keys

Production-grade cryptographic secret generation, rotation, and policy enforcement for fintech, KYC, Parse Server, CI/CD, and automation systems.

npm version License: MIT

Features

  • 🔐 Cryptographically Secure - Uses Node.js crypto.randomBytes() for all secret generation
  • 🎯 Opinionated Presets - Ready-to-use generators for Parse Server, JWT, webhooks, and more
  • 🔄 Zero-Downtime Rotation - Dual-key rotation support for seamless secret updates
  • Policy Enforcement - Blocks weak secrets, UUIDs-as-secrets, and insufficient entropy
  • 📝 Environment Writers - Writes .env files with timestamps and metadata
  • ☁️ Cloud Exporters - Export to AWS Secrets Manager, HashiCorp Vault, Doppler, Kubernetes
  • 🖥️ CLI Tool - Full-featured command-line interface
  • 🤖 n8n Integration - Custom node for automation workflows
  • 🚀 CI/CD Ready - GitHub Actions workflow included

Installation

npm install @duabalabs/secure-keys

Or install globally for CLI access:

npm install -g @duabalabs/secure-keys

Quick Start

Generate Parse Server Keys

import { generateParseKeys, writeParseEnv } from '@duabalabs/secure-keys';

const keys = generateParseKeys({
  includeEncryptionKey: true,
  environment: 'production',
});

// Write to .env file
writeParseEnv(keys, '.env.parse');

console.log('App ID:', keys.appId);
// Master key and other secrets are NOT logged for security

Generate JWT Secrets

import { generateJwtSecrets } from '@duabalabs/secure-keys';

const secrets = generateJwtSecrets({
  includeIdTokenSecret: true,
});

console.log('Access Token Secret:', secrets.accessTokenSecret);
console.log('Refresh Token Secret:', secrets.refreshTokenSecret);

Generate Webhook Secret

import { generateWebhookSecret } from '@duabalabs/secure-keys';

const webhook = generateWebhookSecret();

console.log('Webhook Secret:', webhook.fullSecret);
// Output: whsec_a1b2c3d4e5f6...

CLI Usage

Generate Parse Keys

# Generate and write to .env.parse
secure-keys parse

# Output as JSON
secure-keys parse --json

# With additional options
secure-keys parse --read-only-master --encryption-key -o .env.production

Generate JWT Secrets

secure-keys jwt --id-token --output .env.jwt

Generate Webhook Secret

secure-keys webhook --prefix "myapp_"

Rotate a Secret

secure-keys rotate "old-secret-here" --grace-period 7 --json

Lint Environment Files

# Lint and fail on weak secrets
secure-keys lint .env.production

# Output GitHub Actions annotations
secure-keys lint .env.production --github

# Strict mode (fail on warnings)
secure-keys lint .env.production --strict

Bootstrap Parse Server

secure-keys parse-bootstrap \
  --server-url https://api.example.com/parse \
  --database-uri mongodb://localhost:27017/parse \
  --docker

Export to Cloud Providers

# Export to AWS Secrets Manager format
secure-keys export -i .env.parse -t aws -n "myapp/production"

# Export to HashiCorp Vault format
secure-keys export -i .env.parse -t vault -n "secret/data/myapp"

# Export to Doppler format
secure-keys export -i .env.parse -t doppler -n "myproject"

Secret Rotation

Zero-downtime rotation is achieved by maintaining both primary (new) and secondary (old) secrets:

import { rotateSecret, verifyWithRotation, signWithRotation } from '@duabalabs/secure-keys';

// Rotate an existing secret
const rotated = rotateSecret('current-secret', {
  gracePeriodMs: 7 * 24 * 60 * 60 * 1000, // 7 days
  reason: 'scheduled',
});

// Sign with the new primary secret
const signature = signWithRotation(payload, rotated);

// Verify accepts both old and new secrets
const result = verifyWithRotation(payload, signature, rotated);

if (result.valid) {
  console.log(`Verified with ${result.matchedKey} key`);
}

Rotate Parse Keys

import { rotateParseKeys } from '@duabalabs/secure-keys';

const rotatedKeys = rotateParseKeys(currentKeys, {
  gracePeriodMs: 14 * 24 * 60 * 60 * 1000, // 14 days
  reason: 'compliance',
});

Policy Enforcement

Prevent weak secrets from reaching production:

import { enforcePolicy, validateSecret, SecretPolicyError } from '@duabalabs/secure-keys';

// Validate a secret
const result = validateSecret(mySecret, { secretType: 'parse-master-key' });

if (!result.valid) {
  console.error('Violations:', result.violations);
}

// Enforce policy (throws on failure)
try {
  enforcePolicy(process.env.MASTER_KEY, { secretType: 'parse-master-key' });
} catch (error) {
  if (error instanceof SecretPolicyError) {
    console.error('Security policy violation:', error.violations);
    process.exit(1);
  }
}

Lint Environment at Startup

import { requireSecrets } from '@duabalabs/secure-keys';

// Fail fast if secrets are missing or weak
requireSecrets(process.env, [
  'PARSE_MASTER_KEY',
  'JWT_ACCESS_TOKEN_SECRET',
  { key: 'WEBHOOK_SECRET', type: 'webhook-secret' },
]);

Cloud Exporters

Export secrets to cloud providers without making API calls:

import { exportToAwsSecretsManager, exportToVault, exportToKubernetes } from '@duabalabs/secure-keys';

// AWS Secrets Manager
const awsExport = exportToAwsSecretsManager(secrets, {
  name: 'myapp/production',
  description: 'Production secrets',
  environment: 'production',
});
// Use with: aws secretsmanager create-secret --cli-input-json '...'

// HashiCorp Vault
const vaultExport = exportToVault(secrets, {
  name: 'secret/data/myapp',
});
// Use with: vault kv put myapp @data.json

// Kubernetes Secret
const k8sExport = exportToKubernetes(secrets, {
  name: 'myapp-secrets',
  namespace: 'production',
});
// Convert to YAML and apply with kubectl

n8n Integration

The package includes an n8n custom node for automation workflows:

import { executeSecureKeysNode } from '@duabalabs/secure-keys/n8n';

const result = executeSecureKeysNode({
  operation: 'generateParse',
  includeEncryptionKey: true,
  environment: 'production',
});

console.log(result.secrets);

GitHub Actions

See .github/workflows/secrets-management.yml for a complete CI/CD workflow that:

  • Validates secrets in PRs
  • Generates new secrets on demand
  • Rotates secrets on schedule
  • Exports to AWS/Vault/Doppler

Security Requirements

All secrets must meet these minimum requirements:

Secret Type Minimum Entropy Minimum Bytes
Master Key 256 bits 32 bytes
API Keys 256 bits 32 bytes
JWT Secrets 256 bits 32 bytes
Webhook Secrets 256 bits 32 bytes
Identifiers (App ID) 128 bits 16 bytes

Policy Violations

The following will cause policy failures:

  • ❌ UUIDs used as secrets
  • ❌ Secrets shorter than minimum entropy
  • ❌ Weak patterns (sequential, repeated characters)
  • ❌ Common weak values (password, secret, test)
  • ❌ Empty or undefined secrets

API Reference

Generators

Function Description
generateSecret(bytes?) Generates hex secret
generateBase64Secret(bytes?) Generates Base64 secret
generateBase64UrlSecret(bytes?) Generates URL-safe Base64 secret
generateUUID() Generates UUID v4 (identifiers only!)
generateIdentifier(bytes?) Generates identifier (128+ bits)
generatePrefixedSecret(prefix, bytes?) Generates prefixed secret

Presets

Function Description
generateParseKeys(options?) Complete Parse Server keys
generateJwtSecrets(options?) JWT signing secrets
generateWebhookSecret(options?) Webhook signing secret
generateApiKeyPair(environment?) API key pair (pk/sk)
generateEncryptionKey() AES-256 encryption key
generateSessionSecrets() Session secrets with rotation
generateOAuthCredentials() OAuth client credentials
generateDatabaseKeys() Database encryption keys
generateHmacKey(algorithm?) HMAC signing key

Rotation

Function Description
rotateSecret(oldSecret, options?) Rotate to new primary
verifyWithRotation(payload, sig, rotated) Verify with either key
signWithRotation(payload, rotated) Sign with primary
isSecondaryExpired(rotated) Check if secondary expired
rotateParseKeys(currentKeys, options?) Rotate all Parse keys
rotateJwtSecrets(currentSecrets, options?) Rotate all JWT secrets

Policy

Function Description
validateSecret(secret, options?) Validate against policy
validateSecrets(secrets, mapping?) Validate multiple secrets
enforcePolicy(secret, options?) Throw on policy violation
enforcePolicies(secrets, mapping?) Enforce on multiple
isUUID(value) Check if value is UUID
isWeakSecret(value) Check if secret is weak

Linter

Function Description
lintEnvFile(path, options?) Lint .env file
lintEnvObject(envVars, options?) Lint env object
requireSecrets(env, required) Require valid secrets
formatLintResult(result) Format for console
createGitHubAnnotations(result) GitHub Actions format

Exporters

Function Description
exportToAwsSecretsManager(secrets, options) AWS format
exportToVault(secrets, options) Vault KV v2 format
exportToDoppler(secrets, options) Doppler format
exportToGitHubActions(secrets, options) GitHub Actions format
exportToKubernetes(secrets, options) K8s Secret manifest
exportToDockerCompose(secrets) Docker Compose env

License

MIT © Duaba Labs

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors