nile-secrets v0.2.5
nile-secrets
Envelope encryption for nile projects using nodejs.
Envelope Encryption
Envelope encryption uses a single secret key to encrypt a collection of several secrets. This process is more convenient and more efficient than externally encrypting each secret independently.
Nile Encryption
nile has a great feature that automatically decrypts secret ciphers from AWS KMS. This package is intended to supplement this feature by making it more convenient to secure a collection of secrets.
Usage
Setup
- Add envelope key to
nile.yml
... override: project: ... environment: SECRET_KEY: %{abcdef} ... ...
1. Add scripts to `package.json`
... "scripts": { ... "decrypt": "node -e \"require('nile-secrets').decryptFiles({environment:process.argv1})\"", "encrypt": "node -e \"require('nile-secrets').encryptFiles({environment:process.argv1})\"", ... }, ...
1. Add configs to `package.json`
... "config": { ... "secrets": { "keyName": "SECRET_KEY" ... } ... }, ...
### Encrypting secrets
1. Create an environment-specific file at `secrets/${environment}.json` that contains all of your secret configuration
1. `npm run encrypt ${environment}`
_Note: When encrypting/decrypting a secrets file, the source will be deleted to avoid source truth ambiguity_
_Note: Add `secrets/*.json` to your project's `.gitignore` file to avoid accidentally checking in unencrypted secrets_
### Editing secrets
1. `npm run decrypt ${environment}`
1. Edit your `secrets/${environment}.json` file
1. `npm run encrypt ${environment}`
### Using secrets in your code
#### With Callback
var nileSecrets = require('nile-secrets');
nileSecrets( { environment:process.env.DEPLOYMENT }, (secrets) => { // use your secrets here } );
#### With Promise
var nileSecrets = require('nile-secrets');
nileSecrets({ environment:process.env.DEPLOYMENT }) .then((secrets) => { // use your secrets here });
### Options
Ways to configure options, from highest priority to lowest:
1. parameter hash object to the nileSecrets method
2. `package.json` config fields
#### Option Fields and Default Values
- key [ `undefined` ]
- keyCipher / config.secrets.keyCipher [ `undefined` ]
- nileFile / config.secrets.nileFile [ `"./nile.yml"` ]
- environment [ `undefined` ]
- keyName / config.secrets.keyName [ `"CIPHER_KEY"` ]
- envName / config.secrets.envName [ `"NODE_ENV"`]
- name [ `undefined` ]
- glob [ `undefined` ]
- dir / config.secrets.dir [ `"./secrets"` ]
- ciphertextExt / config.secrets.ciphertextExt [ `".bin"` ]
- plaintextExt / config.secrets.plaintextExt [ `".json"` ]
- algorithm / config.secrets.algorithm [ `"aes256"` ]
- json / config.secrets.json [ `plaintextExt === ".json"` ]
#### Determining the envelope key
1. If the `key` parameter is provided, it is used directly as the encryption key
1. Else if the `keyCipher` parameter is provided, it is decrypted via AWS KMS to retrieve the encryption key
1. Else if the `environment` parameter (cannot be set in `package.json` since it is shared by multiple environments in the project) is provided, the keyCipher is parsed from the environment variable named `keyName` found in the corresponding environment in the `nile.yml` file.
1. Else if the `envName` parameter is provided, the `environment` is determined from the corresponding environment variable and used with `keyName` and `nile.yml` as above.
#### Determining the source file
1. If the `name` parameter is provided, use it as the base of the filename
1. Else if the `environment` parameter is provided (or can be determined from `envName` as above), use it as the base of the filename
1. If decrypting, use `ciphertextExt` parameter as ext
1. Else if encrypting, use `plaintextExt` parameter as ext
1. return path.resolve(dir, filename + ext)
### Exposed Methods
- decrypt(params, [cbk])
decrypt the ciphertext file and return the plaintext secrets via callback or Promise
_Note: this method is aliased as the root of the package_
- decryptFiles(params, [cbk])
decrypt the ciphertext file and write to plaintext file in the secrets directory. When decrypting files, you may provide a glob to decrypt multiple files, which will override `dir` and `name` parameters.
_Note: this method will delete the corresponding ciphertext file to avoid source truth ambiguity_
- decryptSync(params)
decrypt the ciphertext file and return the plaintext secrets directly
_Note: when using the *Sync version of decrypt, the cipher key cannot be retrieved from AWS and must be provided directly either via the `key` parameter or via the environment using the `keyName` parameter_
- encrypt(plaintext, params, [cbk])
encrypt the plaintext secrets into the ciphertext file and acknowledge completion via callback or Promise
- encryptFiles(params, [cbk])
decrypt the plaintext file and write to ciphertext file in the secrets directory. When encrypting files, you may provide a glob to decrypt multiple files, which will override `dir` and `name` parameters.
_Note: this method will delete the corresponding plaintext file to avoid source truth ambiguity_
- getKey(params, [cbk])
return the envelope key as determined using the above algorithm