Production-grade cryptographic secret generation, rotation, and policy enforcement for fintech, KYC, Parse Server, CI/CD, and automation systems.
- 🔐 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
.envfiles 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
npm install @duabalabs/secure-keysOr install globally for CLI access:
npm install -g @duabalabs/secure-keysimport { 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 securityimport { generateJwtSecrets } from '@duabalabs/secure-keys';
const secrets = generateJwtSecrets({
includeIdTokenSecret: true,
});
console.log('Access Token Secret:', secrets.accessTokenSecret);
console.log('Refresh Token Secret:', secrets.refreshTokenSecret);import { generateWebhookSecret } from '@duabalabs/secure-keys';
const webhook = generateWebhookSecret();
console.log('Webhook Secret:', webhook.fullSecret);
// Output: whsec_a1b2c3d4e5f6...# 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.productionsecure-keys jwt --id-token --output .env.jwtsecure-keys webhook --prefix "myapp_"secure-keys rotate "old-secret-here" --grace-period 7 --json# 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 --strictsecure-keys parse-bootstrap \
--server-url https://api.example.com/parse \
--database-uri mongodb://localhost:27017/parse \
--docker# 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"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`);
}import { rotateParseKeys } from '@duabalabs/secure-keys';
const rotatedKeys = rotateParseKeys(currentKeys, {
gracePeriodMs: 14 * 24 * 60 * 60 * 1000, // 14 days
reason: 'compliance',
});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);
}
}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' },
]);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 kubectlThe 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);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
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 |
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
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
MIT © Duaba Labs