Skip to content

[Bug] Unable to support coercion & defaulting of KeyObjects #422

@sohhaofeng1989

Description

@sohhaofeng1989

Background

Thank you for this useful tool. We've been using node-convict in our production app for awhile. Recently, we tried creating a custom format via addFormat, private-key-pem that as implied by its name,

  1. Takes a private key pem string (from an environment variable PRIVATE_KEY) and coerce it into node.js's KeyObject
convict.addFormats({
  'private-key-pem': {
    validate: (val: unknown) => {
      // ... validation logic
    },
    coerce: function (val: string): KeyObject {
      return createPrivateKey(val)
    },
  },
  1. If the PRIVATE_KEY environment variable is not found, it defaults to a dummy unuseable private key as per follow
 {
        doc: 'Test Key (Secret)',
        format: 'private-key-pem',
        default: createPrivateKey(UNUSEABLE_PRIVATE_KEY),
        env: 'PRIVATE_KEY',
  }

Problem

Briefly glancing through convict package's main.js, I understand that convict uses lodash's cloneDeep to (1) return a deep clone of the config upon config.get and (2) deep clone default-able values in addDefaultValues. This is problematic for us as cloneDeep refuses to clone KeyObjects or CryptoKeys.

Image Image

Assumption

I made a simple assumption that the original intent of using cloneDeep was to prevent possible mutations on the underlying config instance. ex.

const testStringArray = config.get('some.config')
testStringArray.push('something') // don't want original value at 'some.config' to be mutated!

Proposal

I propose that we add handling of KeyObjects instances by cloning KeyObjects with an explicitexport and createPrivateKey. A simplified example for illustration would be as below (which should be sufficient for cloning private keys that aren't encrypted with a passphase)

const clonedKeyObj = createPrivateKey(originalKeyObj.export({ type : 'pkcs8', format : 'pem' }) // Simplified example

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions