Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@tsmx/secure-config-tool

Package Overview
Dependencies
Maintainers
0
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tsmx/secure-config-tool - npm Package Compare versions

Comparing version 2.2.1 to 2.3.0

eslint.config.js

2

functions/create-file.js

@@ -18,3 +18,3 @@ const fs = require('fs');

try {
configKey = cryptUtils.retrieveKey();
configKey = cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY);
}

@@ -21,0 +21,0 @@ catch (error) {

@@ -8,3 +8,3 @@ const cryptUtils = require('../utils/crypt');

try {
key = cryptUtils.retrieveKey(verbose);
key = cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY, verbose);
decrypted = cryptUtils.decrypt(secret, key);

@@ -11,0 +11,0 @@ }

@@ -7,3 +7,3 @@ const cryptUtils = require('../utils/crypt');

try {
key = cryptUtils.retrieveKey(verbose);
key = cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY, verbose);
}

@@ -10,0 +10,0 @@ catch (error) {

@@ -16,3 +16,3 @@ const fs = require('fs');

try {
configKey = cryptUtils.retrieveKey();
configKey = cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY);
}

@@ -19,0 +19,0 @@ catch (error) {

@@ -14,3 +14,3 @@ const fs = require('fs');

try {
configKey = cryptUtils.retrieveKey();
configKey = cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY);
}

@@ -17,0 +17,0 @@ catch (error) {

{
"name": "@tsmx/secure-config-tool",
"version": "2.2.1",
"version": "2.3.0",
"description": "Command-line tool for @tsmx/secure-config.",

@@ -28,3 +28,3 @@ "main": "secure-config-tool.js",

"@tsmx/string-crypto": "^1.0.2",
"commander": "^11.1.0"
"commander": "^12.1.0"
},

@@ -42,2 +42,3 @@ "keywords": [

"key injection",
"key rotation",
"multi-environment",

@@ -49,5 +50,8 @@ "JSON",

"devDependencies": {
"eslint": "^8.41.0",
"@eslint/js": "^9.8.0",
"eslint": "^9.8.0",
"eslint-plugin-jest": "^28.8.0",
"globals": "^15.9.0",
"jest": "^29.2.2"
}
}

@@ -11,9 +11,10 @@ # [**@tsmx/secure-config-tool**](https://github.com/tsmx/secure-config-tool)

Features:
- create secure configurations with encrypted secrets and a HMAC out of existing JSON files
- update HMAC values of existing secure configuration files after they have changed
- test existing secure configuration JSON files (HMAC validation & decryption)
- generate keys
- encrypt single secrets for copy & paste into existing configurations
- decrypt single secrets for testing purposes
**Features:**
- [create secure configurations](#create) with encrypted secrets and a HMAC out of existing JSON files
- [key rotation](#rotate-key) of an existing secure configuration
- [update HMAC](#update-hmac) values of existing secure configuration files after they have changed
- [test](#test) existing secure configuration JSON files (HMAC validation & decryption)
- [generate keys](#genkey)
- [encrypt single secrets](#encrypt) for copy & paste into existing configurations
- [decrypt single secrets](#decrypt) for testing purposes

@@ -70,4 +71,30 @@ To get more information please also check out the [secure-config documentation](https://tsmx.net/secure-config/).

Specify a property name to store the generated HMAC value in. Defaults to `__hmac` if the option is not present. Doesn't have any effect if `-nh` is specified at the same time.
Specify a property name to store the generated HMAC value in. Defaults to `__hmac` if the option is not present. Doesn't have any effect if `-nh` is specified at the same time.
### rotate-key
Rotates the key of an existing secure configuration file produced with [create](#create). Environment variables `CONFIG_ENCRYPTION_KEY` and `CONFIG_ENCRYPTION_KEY_NEW` must be set:
- `CONFIG_ENCRYPTION_KEY`: the key for the existing secure configuration file
- `CONFIG_ENCRYPTION_KEY_NEW`: the ney key to rotate to (Hint: you can use the [genkey option](#genkey) to generate a new one)
Basic console example:
```
[tsmx@localhost ]$ export CONFIG_ENCRYPTION_KEY=...
[tsmx@localhost ]$ export CONFIG_ENCRYPTION_KEY_NEW=...
[tsmx@localhost ]$ secure-config-tool rotate-key config-production.json
```
The result is printed to stdout. Use `>` to save it in a new file or the `--overwrite` option.
If the source secure configuration file includes a HMAC in the default `__hmac` property, it will be updated automatically using the new key. If the source file has a HMAC in a custom named property, use the `-hp` option to provide the property name and it will be updated.
#### -hp, --hmac-prop
Use this option to specify the property name of an existing HMAC value to be updated in the source secure configuration file if it is deviating from the default `__hmac`.
#### -o, --overwrite
Overwrite the original configuration file after rotating the key instead of writing to stdout.
### update-hmac

@@ -149,2 +176,4 @@

### 2.3.0
- [Key rotation](#rotate-key) feature added

@@ -151,0 +180,0 @@ ## Test

@@ -6,2 +6,3 @@ #!/usr/bin/env node

const updateHmac = require('./functions/update-hmac');
const rotateKey = require('./functions/rotate-key');
const testFile = require('./functions/test-file');

@@ -36,2 +37,10 @@ const createKey = require('./functions/create-key');

program
.command('rotate-key <config-file>')
.description('Rotates the key of an existing secure-config configuration file')
.option('-o, --overwrite', 'overwrite file directly instead of writing to stdout')
.option('-hp, --hmac-prop <hmac-prop>', 'custom name of the HMAC property to be updated with the new key (if one), default is \'__hmac\'')
.action(rotateKey)
.addHelpText('after', helpTexts.rotateHelpText);
program
.command('test <config-file>')

@@ -38,0 +47,0 @@ .description('Test decryption and HMAC validation for an existing secure-config configuration file')

@@ -37,5 +37,5 @@ const cryptUtils = require('../utils/crypt');

it('tests a successful key retrieval', () => {
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY;
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY;
expect(testOutput.length).toBe(0);
const key = cryptUtils.retrieveKey(true);
const key = cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY, true);
expect(key).toBeDefined();

@@ -49,5 +49,5 @@ expect(key.length).toBe(32);

it('tests a successful key retrieval for a hexadecimal string', () => {
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY_HEX;
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY_HEX;
expect(testOutput.length).toBe(0);
const key = cryptUtils.retrieveKey(true);
const key = cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY, true);
expect(key).toBeDefined();

@@ -62,4 +62,4 @@ expect(key.length).toBe(64);

expect(() => {
cryptUtils.retrieveKey();
}).toThrow('Environment variable CONFIG_ENCRYPTION_KEY not set.');
cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY);
}).toThrow(`Environment variable ${cryptUtils.CONFIG_ENCRYPTION_KEY} not set.`);
});

@@ -69,5 +69,5 @@

expect(() => {
process.env['CONFIG_ENCRYPTION_KEY'] = TEST_KEY_BROKEN;
cryptUtils.retrieveKey();
}).toThrow('CONFIG_ENCRYPTION_KEY length must be 32 bytes.');
process.env[cryptUtils.CONFIG_ENCRYPTION_KEY] = TEST_KEY_BROKEN;
cryptUtils.retrieveKey(cryptUtils.CONFIG_ENCRYPTION_KEY);
}).toThrow(`${cryptUtils.CONFIG_ENCRYPTION_KEY} length must be 32 bytes.`);
});

@@ -74,0 +74,0 @@

@@ -73,4 +73,4 @@ const fs = require('fs');

expect(updatedJson.database.host).toStrictEqual(originalJson.database.host);
expect(updatedJson.database.user).toStrictEqual(originalJson.database.user);
expect(updatedJson.database.pass).toStrictEqual(originalJson.database.pass);
expect(updatedJson.database.username).toStrictEqual(originalJson.database.username);
expect(updatedJson.database.password).toStrictEqual(originalJson.database.password);
expect(updatedJson.database.port).toStrictEqual(originalJson.database.port);

@@ -95,4 +95,4 @@ expect(updatedJson['__hmac']).not.toStrictEqual(originalJson['__hmac']);

expect(updatedJson.database.host).toStrictEqual(originalJson.database.host);
expect(updatedJson.database.user).toStrictEqual(originalJson.database.user);
expect(updatedJson.database.pass).toStrictEqual(originalJson.database.pass);
expect(updatedJson.database.username).toStrictEqual(originalJson.database.username);
expect(updatedJson.database.password).toStrictEqual(originalJson.database.password);
expect(updatedJson.database.port).toStrictEqual(originalJson.database.port);

@@ -99,0 +99,0 @@ expect(updatedJson['__hmac']).toBeUndefined();

@@ -5,2 +5,4 @@ const crypto = require('crypto');

const prefix = 'ENCRYPTED|';
const encryptionKey = 'CONFIG_ENCRYPTION_KEY';
const encryptionKeyNew = 'CONFIG_ENCRYPTION_KEY_NEW';

@@ -12,17 +14,19 @@ const decryptErrorMessage = `Decryption failed. Please check that the right key is used and the encrypted secret is valid and has the form "ENCRYPTED|IV|DATA"

module.exports.DECRYPTION_ERROR = decryptErrorMessage;
module.exports.CONFIG_ENCRYPTION_KEY = encryptionKey;
module.exports.CONFIG_ENCRYPTION_KEY_NEW = encryptionKeyNew;
module.exports.retrieveKey = function (verbose = false) {
module.exports.retrieveKey = function (keyName, verbose = false) {
const hexReg = new RegExp('^[0-9A-F]{64}$', 'i');
let result = null;
if (!process.env.CONFIG_ENCRYPTION_KEY) {
throw new Error('Environment variable CONFIG_ENCRYPTION_KEY not set.');
if (!process.env[keyName]) {
throw new Error(`Environment variable ${keyName} not set.`);
}
else if (process.env.CONFIG_ENCRYPTION_KEY.toString().length == 32 || hexReg.test(process.env.CONFIG_ENCRYPTION_KEY.toString())) {
result = process.env.CONFIG_ENCRYPTION_KEY.toString();
else if (process.env[keyName].toString().length == 32 || hexReg.test(process.env[keyName].toString())) {
result = process.env[keyName].toString();
}
else {
throw new Error('CONFIG_ENCRYPTION_KEY length must be 32 bytes.');
throw new Error(`${keyName} length must be 32 bytes.`);
}
if (verbose) {
console.log('CONFIG_ENCRYPTION_KEY found, using key: **************************' + result.slice(result.length - 6));
console.log(`${keyName} found, using key: **************************` + result.slice(result.length - 6));
}

@@ -41,3 +45,3 @@ return result;

}
catch (error) {
catch (_error) {
throw new Error(decryptErrorMessage);

@@ -44,0 +48,0 @@ }

module.exports.createHelpText = `
If no patterns are specified with the -p option then the default patterns are used: \'user\',\'pass\',\'token\'.
If no patterns are specified with the -p option then the default patterns are used: 'user','pass','token'.
For every supplied pattern a case-insensitive regex match will be done for every key of the original JSON.

@@ -28,2 +28,12 @@ If the match succeeds, the value of the key will be encrypted.

module.exports.rotateHelpText = `
Loads an existing secure-config file and updates encryption as well as optional HMAC from old CONFIG_ENCRYPTION_KEY to CONFIG_ENCRYPTION_KEY_NEW.
Both environment variables must be set.
Examples:
$ secure-config-tool rotate-key config.json > config-production.json
$ secure-config-tool rotate-key -hp "_signature" -o config-production.json
`;
module.exports.testHelpText = `

@@ -30,0 +40,0 @@ Examples:

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc