@@ -22,6 +22,7 @@ import {
2222} from '@cubejs-backend/base-driver' ;
2323import { formatToTimeZone } from 'date-fns-timezone' ;
2424import fs from 'fs/promises' ;
25+ import crypto from 'crypto' ;
2526import { HydrationMap , HydrationStream } from './HydrationStream' ;
2627
2728const SUPPORTED_BUCKET_TYPES = [ 's3' , 'gcs' , 'azure' ] ;
@@ -245,8 +246,30 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
245246 assertDataSource ( 'default' ) ;
246247
247248 let privateKey = getEnv ( 'snowflakePrivateKey' , { dataSource } ) ;
248- if ( privateKey && ! privateKey . endsWith ( '\n' ) ) {
249- privateKey += '\n' ;
249+
250+ if ( privateKey ) {
251+ // If the private key is encrypted - we need to decrypt it before passing to
252+ // snowflake sdk.
253+ if ( privateKey . includes ( 'BEGIN ENCRYPTED PRIVATE KEY' ) ) {
254+ const keyPasswd = getEnv ( 'snowflakePrivateKeyPass' , { dataSource } ) ;
255+
256+ if ( ! keyPasswd ) {
257+ throw new Error (
258+ 'Snowflake encrypted private key provided, but no passphrase was given.'
259+ ) ;
260+ }
261+
262+ const privateKeyObject = crypto . createPrivateKey ( {
263+ key : privateKey ,
264+ format : 'pem' ,
265+ passphrase : keyPasswd
266+ } ) ;
267+
268+ privateKey = privateKeyObject . export ( {
269+ format : 'pem' ,
270+ type : 'pkcs8'
271+ } ) ;
272+ }
250273 }
251274
252275 snowflake . configure ( { logLevel : 'OFF' } ) ;
@@ -267,6 +290,7 @@ export class SnowflakeDriver extends BaseDriver implements DriverInterface {
267290 privateKeyPath : getEnv ( 'snowflakePrivateKeyPath' , { dataSource } ) ,
268291 privateKeyPass : getEnv ( 'snowflakePrivateKeyPass' , { dataSource } ) ,
269292 privateKey,
293+ ...( privateKey ? { privateKey } : { } ) ,
270294 exportBucket : this . getExportBucket ( dataSource ) ,
271295 resultPrefetch : 1 ,
272296 executionTimeout : getEnv ( 'dbQueryTimeout' , { dataSource } ) ,
0 commit comments