{"id":22281063,"url":"https://github.com/godaddy/node-config-shield","last_synced_at":"2025-07-28T19:33:08.405Z","repository":{"id":25393463,"uuid":"28822093","full_name":"godaddy/node-config-shield","owner":"godaddy","description":"Safe and easy way for storing and retrieving sensitive data","archived":false,"fork":false,"pushed_at":"2022-08-23T19:58:50.000Z","size":26,"stargazers_count":13,"open_issues_count":4,"forks_count":6,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-04-26T11:43:44.618Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/godaddy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-05T16:58:13.000Z","updated_at":"2022-11-25T05:15:14.000Z","dependencies_parsed_at":"2022-09-18T01:32:25.708Z","dependency_job_id":null,"html_url":"https://github.com/godaddy/node-config-shield","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/godaddy%2Fnode-config-shield","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/godaddy%2Fnode-config-shield/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/godaddy%2Fnode-config-shield/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/godaddy%2Fnode-config-shield/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/godaddy","download_url":"https://codeload.github.com/godaddy/node-config-shield/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227621825,"owners_count":17795021,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-03T16:13:22.817Z","updated_at":"2024-12-03T16:13:23.418Z","avatar_url":"https://github.com/godaddy.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Config Shield\r\n\r\n[![Build Status](https://travis-ci.org/godaddy/node-config-shield.png)](https://travis-ci.org/godaddy/node-config-shield) [![NPM version](https://badge.fury.io/js/config-shield.png)](http://badge.fury.io/js/config-shield) [![Dependency Status](https://gemnasium.com/godaddy/node-config-shield.png)](https://gemnasium.com/godaddy/node-config-shield) [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/godaddy/node-config-shield/trend.png)](https://bitdeli.com/free \"Bitdeli Badge\")\r\n\r\n[![NPM](https://nodei.co/npm/config-shield.png?downloads=true\u0026stars=true)](https://www.npmjs.org/package/config-shield)\r\n\r\n\r\n## About\r\n\r\nThe mission behind this project is to provide a \"safe\" process from which to store\r\nproperties sensitive in nature, in a manner that is both developer friendly as\r\nwell as optimized for production use.\r\n\r\n\r\n\r\n## Making configuration changes\r\n\r\nInstall `config-shield` in your project:\r\n```\r\n  npm install config-shield --save\r\n```\r\nStartup the command-line interface from root of application:\r\n```\r\n  npm run config-shield\r\n  : enter path of config (enter to use secure-config.json)\u003e\r\n  : enter path of private key\u003e my.app.key\r\n  set simple_property true\r\n  set my-json-prop { \"nested\": { \"values\": [ 1, 2, 3 ] } }\r\n  set null-prop null\r\n  set evaluable-prop-as-string \"null\"\r\n  set string-prop this will be stored as string if type cannot be determined\r\n  set array-pop [ 1, 2, 3 ]\r\n  set boolean-prop true\r\n  set number-prop 5\r\n  remove number-prop\r\n  get my-json-prop\r\n  : { \"nested\": { \"values\": [ 1, 2, 3 ] } }\r\n  save\r\n  : changes saved\r\n  exit\r\n```\r\nOptionally you may also install `config-shield` globally:\r\n```\r\n  npm install config-shield -g\r\n  config-shield\r\n```\r\n\r\n## Deploy your config\r\n\r\nThis step should be built into your CICD process, to clone the applicable\r\nenvironment config and copy `secure-config.json` over. Ideally these\r\nassets will be in a limited-access store to avoid unnecessary risk.\r\n\r\n***Do not under any circumstance store your production private keys within\r\nyour project.***\r\n\r\n\r\n## Loading config from your App\r\n```\r\n  var secureConfig = require('config-shield');\r\n  // one-time load\r\n  secureConfig.load({\r\n    configPath: './secure-config.json', // not required if default\r\n    privateKeyPath: '/etc/pki/tls/certs/my.app.key'\r\n  });\r\n\r\n  var myObj = secureConfig.getProp('my-json-prop');\r\n```\r\nAccess your secure config from anywhere in your app:\r\n```\r\n  var secureConfig = require('config-shield');\r\n  var myObj = secureConfig.getProp('my-json-prop');\r\n```\r\nMultiple configs? No problem:\r\n```\r\n  var secureConfig = require('config-shield');\r\n  secureConfig.load({\r\n    instance: 'my-other-config',\r\n    configPath: './my-other-secure-config.json',\r\n    privateKeyPath: '/etc/pki/tls/certs/my.app.key'\r\n  });\r\n\r\n  var myOtherSecureConfig = secureConfig.instance('my-other-config');\r\n  var myObj = myOtherSecureConfig.getProp('my-prop');\r\n```\r\n\r\n\r\n## Developer Environment\r\n\r\nOptionally you may include your development private key within your project to keep\r\nthings simple, but ***please do not do this*** for production environments as\r\nyou'll be negating the value of this module. Only a limited few should have access\r\nto production private keys.\r\n\r\n\r\n\r\n## API\r\n```\r\n  var secureConfig = require('config-shield');\r\n```\r\n* load (options[, cb]) - Load config.\r\n  * options.instance (default: 'default') - Name of the config instance.\r\n  * options.configPath (required) - Config to load, relative to the current working directory.\r\n  * options.privateKeyPath (required) - Private key to load. Or could be any secret.\r\n  * options.noCache (default: false) - Will disable caching of decrypted values if true.\r\n  * options.alg (default: 'aes-256-ctr') - Algorithm to use for encryption.\r\n  * cb (function(err, secureConfig)) - If callback is provided, will load asynchronously,\r\n    otherwise will return synchronously.\r\n* save ([configPath][, cb]) - Save config.\r\n  * configPath (required) - Config to save, relative to the current working directory.\r\n  * cb (function(err)) - If callback is provided, will save asynchronously,\r\n    otherwise will return synchronously.\r\n* convert ([options][, cb]) - Convert existing config to new private key.\r\n  * options.privateKeyPath (required) - Private key file to load. Or could be any secret file.\r\n  * options.backup (default: `false`) - Write old config values as `backup` to allow for a rotationary period where\r\n    old key will continue to work.\r\n  * options.alg (default: 'aes-256-ctr') - Algorithm to use for encryption.\r\n  * cb (function(err)) - If callback is provided, will save asynchronously,\r\n    otherwise will return synchronously.\r\n* dropBackup () - Removes all backup keys.\r\n* getProp (propName) - Return decrypted config value.\r\n* setProp (propName, propValue) - Store config value.\r\n* removeProp (propName) - Remove config value.\r\n* removeAll () - Remove all config values.\r\n* getKeys () - Return an array of available property keys.\r\n* getInstance (instanceName) - Return a config instance.\r\n* setInstance (instance) - Set a config instance.\r\n\r\n\r\n\r\n## Rotating keys\r\n\r\nIn the case you have keys that must be rotated, you can use the convert with `backup` option. The process would\r\nrequire you to:\r\n\r\n1. Load config with old private key.\r\n2. Convert with new private key, setting `backup` to `true`.\r\n3. Deploy your config change.\r\n4. Rotate your private keys.\r\n5. Load config with new private key.\r\n6. Run `dropBackup`.\r\n7. Deploy your final config change.\r\n\r\nIn CLI, would look something like:\r\n\r\n```\r\n  config-shield\r\n  enter path of config\u003e secure-config.json\r\n  enter path of private key\u003e old.key\r\n  \u003e convert\r\n  enter path of private key\u003e new.key\r\n  backup old values to enable key rotations? (enter to disable, or `true`)\u003e true\r\n  \u003e save\r\n  \u003e exit\r\n```\r\n\r\nDeploy your change, then update your config one last time:\r\n\r\n```\r\n  config-shield\r\n  enter path of config\u003e secure-config.json\r\n  enter path of private key\u003e new.key\r\n  \u003e dropBackup\r\n  \u003e save\r\n  \u003e exit\r\n```\r\n\r\nDeploy the final config. If you skip the step of dropping the backup, your config will\r\nbecome vulnerable to attacks using the old private key, negating most of the value of\r\nrotating keys.\r\n\r\n\r\n## Future\r\n\r\nPossible future enhancements:\r\n\r\n* tts - Time to stale before auto-reloading config.\r\n\r\n\r\n## License\r\n\r\n[MIT](https://github.com/godaddy/node-config-shield/blob/master/LICENSE.txt)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgodaddy%2Fnode-config-shield","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgodaddy%2Fnode-config-shield","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgodaddy%2Fnode-config-shield/lists"}