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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions