Skip to content

Design: Encryption of credentials

Nick O'Leary edited this page Jul 13, 2016 · 5 revisions

Target: 0.15

Currently credentials are passed to the storage API in the clear so unless the storage mechanism does anything specific, they get stored in the clear.

With a move to add version control backing to node-red, the very real prospect emerges of credentials being stored, in the clear, in version control. That is highly undesirable.

We cannot escape the fact that we need to store credential information in a retrievable way; hashing is not an option.

What we can do is look at options to encrypt the credentials by default.


Any encryption scheme will require a key to encrypt/decrypt the content. This needs to be provided by the user to ensure uniqueness. If we were to default to a 'well-known' key by default, then we're no more secure than we are today.

There are some cases to consider:

  1. a user provides a credentialSecret property in the settings.js file - in which case use that to encrypt/decrypt credentials
  2. no such property is provided - the runtime must generate a random key and store it in the runtime settings object (see Storage.setSettings). If settings are not available, no encryption can be used.

Considerations

  1. a user runs without credentialSecret set and deploys some credentials. They get encrypted with the generated key that is stored in runtime settings. Note: the user doesn't know what that key is unless they go digging in the underlying storage mechanism for runtime settings (default: .config.json file)
  2. a user then sets credentialSecret to a non-null string value:
    • we will migrate the encryption key from the generated one to their preferred one (and delete the generated key from runtime settings)
    • if they then change credentialSecret - we can no longer decrypt credentials so they get wiped
  3. alternative, if a user sets credentialSecret to null, we disable encryption of credentials, migrating from the auto generated key.
    • if they then change credentialSecret to a non-null string value, we enable encryption

All of this behaviour occurs in the runtime - the credentials passed over the Storage API will be the encrypted set, assuming:

  • the storage plugin being used is the new one.
  • they have not set credentialSecret to null

If the storage plugin implements the v1 storage api (ie the existing one), the encryption scheme will be disabled.

Clone this wiki locally