Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNOW-1475982: Client does not handle encrypted private keys via privateKey #855

Closed
jverce opened this issue Jun 12, 2024 · 2 comments
Closed
Assignees
Labels
question Issue is a usage/other question rather than a bug status-triage_done Initial triage done, will be further handled by the driver team

Comments

@jverce
Copy link

jverce commented Jun 12, 2024

Please answer these questions before submitting your issue.
In order to accurately debug the issue this information is required. Thanks!

  1. What version of NodeJS driver are you using?
    1.11.0

  2. What operating system and processor architecture are you using?

    1. Linux on x86
    2. Mac (Darwin on arm64)
  3. What version of NodeJS are you using?

    1. Node: v18.17.0
    2. NPM: 9.6.7
  4. What are the component versions in the environment (npm list)?

scrapbook@ /Users/jay/dev/scrapbook
├── @pipedream/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
  1. Server version:
    8.21.3

  2. What did you do?
    Trying to connect to Snowflake using an encrypted private key that's passed to the client constructor via the privateKey option:

    const privateKey = `-----BEGIN ENCRYPTED PRIVATE KEY-----
    MIIF...
    -----END ENCRYPTED PRIVATE KEY-----
    `;
    snowflake.createConnection({
      ...baseOptions,
      privateKey,
      privateKeyPass,
    });
  3. What did you expect to see?
    A successful connection, but instead I got this:

    Error [InvalidParameterError]: Invalid private key. The specified value must be a string in pem format of type pkcs8
    

I think the error lies in how the library tries to detect a private key in lib/util.js.

  1. Can you set logging to DEBUG and collect the logs?
{
  "code": "InvalidParameterError",
  "message": "Invalid private key. The specified value must be a string in pem format of type pkcs8",
  "stack": "    at null.createError (/tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/node_modules/.pnpm/[email protected][email protected]/node_modules/snowflake-sdk/lib/errors.js:529:17)\n    at Object.exports.checkArgumentValid (/tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/node_modules/.pnpm/[email protected][email protected]/node_modules/snowflake-sdk/lib/errors.js:263:11)\n    at null.ConnectionConfig (/tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/node_modules/.pnpm/[email protected][email protected]/node_modules/snowflake-sdk/lib/connection/connection_config.js:279:12)\n    at null.createConnection (/tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/node_modules/.pnpm/[email protected][email protected]/node_modules/snowflake-sdk/lib/core.js:68:7)\n    at Object.createConnection (/tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/node_modules/.pnpm/[email protected][email protected]/node_modules/snowflake-sdk/lib/core.js:91:16)\n    at Object._getConnection (file:///tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/code/snowflake.app.mjs:97:35)\n    at Object.getRows (file:///tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/code/snowflake.app.mjs:173:37)\n    at Object.collectRows (file:///tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/code/snowflake.app.mjs:178:36)\n    at Object.run (file:///tmp/__pdg__/dist/code/c76c7f1ea195e5839af9579e287dbf204794aef4c61dd1cea3c0d71b7402be88/code/actions/execute-sql-query/execute-sql-query.mjs:21:27)\n    at null.executeComponent (/var/task/launch_worker.js:288:53)\n",
}
  1. What is your Snowflake account identifier, if any? (Optional)
@jverce jverce added the bug Something isn't working label Jun 12, 2024
@github-actions github-actions bot changed the title Client does not handle encrypted private keys via privateKey SNOW-1475982: Client does not handle encrypted private keys via privateKey Jun 12, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka self-assigned this Jun 12, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka added the status-triage Issue is under initial triage label Jun 12, 2024
@sfc-gh-dszmolka
Copy link
Collaborator

hi and thanks for raising this issue, also appreciate for sharing the details and code snippet ! can you please try the method documented here : https://docs.snowflake.com/en/developer-guide/node-js/nodejs-driver-authenticate#using-key-pair-authentication-and-key-pair-rotation for defining privateKey contents, and see if it works for you ?

@sfc-gh-dszmolka sfc-gh-dszmolka added question Issue is a usage/other question rather than a bug status-triage_done Initial triage done, will be further handled by the driver team and removed bug Something isn't working status-triage Issue is under initial triage labels Jun 12, 2024
@jverce
Copy link
Author

jverce commented Jun 12, 2024

Nice! I thought the library did those steps internally since I kinda skipped that section of the docs.

For posterity, I'm basically doing this now before initializing the client:

import { createPrivateKey } from "crypto";
import snowflake from "snowflake-sdk";

const extractPrivateKey = (key, passphrase) => {
  if (!key.startsWith("-----BEGIN ENCRYPTED PRIVATE KEY-----")) {
    // Key is not encrypted, no need to extract anything
    return key;
  }

  const privateKeyObject = createPrivateKey({
    key,
    format: "pem",
    passphrase,
  });
  return privateKeyObject.export({
    format: "pem",
    type: "pkcs8",
  });
};

const getClientConfiguration = (authInfo) => {
  const {
    privateKey: originalPrivateKey,
    privateKeyPass,
    ...auth
  } = authInfo;
  const privateKey = extractPrivateKey(originalPrivateKey, privateKeyPass);
  const authenticator = privateKey
    ? "SNOWFLAKE_JWT"
    : "SNOWFLAKE";
  return {
    ...auth,
    authenticator,
    privateKey,
    privateKeyPass,
  };
};

snowflake.createConnection(getClientConfiguration());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issue is a usage/other question rather than a bug status-triage_done Initial triage done, will be further handled by the driver team
Projects
None yet
Development

No branches or pull requests

2 participants