Authenticating connections

To authenticate to Snowflake, you can use one of the following options:

Additionally, the Snowflake Node.js driver supports the ability to cache SSO and MFA tokens. For more information, see Authentication token caching.

Use single sign-on (SSO) through a web browser

If you have configured Snowflake to use single sign-on (SSO), you can configure your client application to use browser-based SSO for authentication.

In your application code:

  1. Set the authenticator option to EXTERNALBROWSER.

  2. To establish a connection, call the connectAsync method, rather than the connect method.

For example:

// Use a browser to authenticate via SSO.
var connection = snowflake.createConnection({
  ...,
  authenticator: "EXTERNALBROWSER"
});
// Establish a connection. Use connectAsync, rather than connect.
connection.connectAsync(
  function (err, conn)
  {
    ... // Handle any errors.
  }
).then(() =>
{
  // Execute SQL statements.
  var statement = connection.execute({...});
});
Copy

For more information about using browser-based SSO for authentication, see Browser-based SSO.

Use native SSO through Okta

If you have configured Snowflake to use single sign-on (SSO) through Okta, you can configure your client application to use native SSO authentication through Okta.

In your application code:

  1. Set the following options:

    • Set the authenticator option to the Okta URL endpoint for your Okta account (e.g. https://<okta_account_name>.okta.com).

    • Set the username and password options to the user name and password for your Identity Provider (IdP).

  2. To establish a connection, call the connectAsync method, rather than the connect method.

For example:

// Use native SSO authentication through Okta.
var connection = snowflake.createConnection({
  ...,
  username: '<user_name_for_okta>',
  password: '<password_for_okta>',
  authenticator: "https://myaccount.okta.com"
});

// Establish a connection.
connection.connectAsync(
  function (err, conn)
  {
    ... // Handle any errors.
  }
);

// Execute SQL statements.
var statement = connection.execute({...});
Copy

For more information about using native SSO authentication through Okta, see Native SSO — Okta only.

Use key-pair authentication and key-pair rotation

The driver supports key pair authentication and key rotation. To use key-pair authentication and key rotation, follow the steps below:

  1. Configure key pair authentication, as explained in Key-pair authentication and key-pair rotation.

  2. In your application code:

    1. Set the authenticator option to SNOWFLAKE_JWT.

    2. Use the private key to authenticate in one of the following ways:

      • Set the privateKey option to the private key.

      • Set the privateKeyPath option to the path to the private key file.

        If the file is encrypted, you must also set the privateKeyPass option to the passphrase to decrypt the private key.

The following example loads the private key from a file and sets the privateKey option to the private key:

// Read the private key file from the filesystem.
var crypto = require('crypto');
var fs = require('fs');
var privateKeyFile = fs.readFileSync('<path_to_private_key_file>/rsa_key.p8');

// Get the private key from the file as an object.
const privateKeyObject = crypto.createPrivateKey({
  key: privateKeyFile,
  format: 'pem',
  passphrase: 'passphrase'
});

// Extract the private key from the object as a PEM-encoded string.
var privateKey = privateKeyObject.export({
  format: 'pem',
  type: 'pkcs8'
});

// Use the private key for authentication.
var connection = snowflake.createConnection({
  ...
  authenticator: "SNOWFLAKE_JWT",
  privateKey: privateKey
});

// Establish a connection.
connection.connect(
  function (err, conn)
  {
    ... // Handle any errors.
  }
);

// Execute SQL statements.
var statement = connection.execute({...});
Copy

The following example sets the privateKeyPath option to an encrypted private key file and sets the privateKeyPass option to the passphrase used to decrypt the private key:

// Use an encrypted private key file for authentication.
// Specify the passphrase for decrypting the key.
var connection = snowflake.createConnection({
  ...
  authenticator: "SNOWFLAKE_JWT",
  privateKeyPath: "<path-to-privatekey>/privatekey.p8",
  privateKeyPass: '<passphrase_to_decrypt_the_private_key>'
});

// Establish a connection.
connection.connect(
  function (err, conn)
  {
    ... // Handle any errors.
  }
);

// Execute SQL statements.
var statement = connection.execute({...});
Copy

Use OAuth

To connect using OAuth, set the authenticator option to OAUTH and the token option to the OAuth access token. For example:

// Use OAuth for authentication.
var connection = snowflake.createConnection({
  ...
  authenticator: "OAUTH",
  token: "<your_oauth_token>"
});

// Establish a connection.
connection.connect(
  function (err, conn)
  {
    ... // Handle any errors.
  }
);

// Execute SQL statements.
var statement = connection.execute({...});
Copy

For more information, see Clients, drivers, and connectors.

Use an MFA passcode

Note

This feature requires Snowflake Node.js driver version 1.13.1 or higher.

You can connect to Snowflake by passing a multi-factor authentication (MFA) passcode instead of waiting for an external confirmation, such as a push notification from Duo. The driver provides the following ways to specify an MFA passcode:

  • Set the passcodeInPassword option to true and include the passcode as part of the password string, similar to the following:

    const connection = snowflake.createConnection({
        account: process.env.SNOWFLAKE_TEST_ACCOUNT,
        username: process.env.SNOWFLAKE_TEST_USER,
        ...
        authenticator: 'USERNAME_PASSWORD_MFA',
        password: "abc123987654", // passcode 987654 is part of the password
        passcodeInPassword: true  // because passcodeInPassword is true
    });
    
    Copy
  • Set the passcode option to the value of the passcode to specify the password and the passcode separately, similar to the following:

    const connection = snowflake.createConnection({
        account: process.env.SNOWFLAKE_TEST_ACCOUNT,
        username: process.env.SNOWFLAKE_TEST_USER,
        ...
        authenticator: 'USERNAME_PASSWORD_MFA',
        password: "abc123", // password and MFA passcode are input separately
        passcode: "987654"
    });
    
    Copy

    To use this approach, ensure that the passcodeInPassword option is false (the default value).

Note

If you enable the passcodeInPassword option and set the passcode option, the passcodeInPassword option takes precedence.

For more information about these options, see passcode.

Authentication token caching

The Snowflake Node.js driver provides the ability to cache SSO and MFA tokens.

Important

Token caching is disabled by default. Caching tokens locally increases security risks. Because tokens do not expire for four hours, someone who accesses a token on a local system can impersonate the token owner until the token naturally expires. Consequently, before choosing to cache tokens, consider the following:

  • Be aware and mindful of the potential risks.

  • Consult with your internal security and compliance personnel to check whether your organization’s policies permit token caching.

  • With the default settings, the file that stores the cached tokens is written in your $HOME directory, or in a path you cohfigure. You are responsible for the security of the data in the designated directory.

  • You are responsible to ensure that the file has proper permissions to be accessed only by the file owner.

Cache SSO (ID) tokens

An SSO (ID) token is generated from the request when you connect to Snowflake with external browser authentication. Caching SSO (ID) tokens on the client driver’s side only works if the server allows them to be cached. Caching SSO tokens can be enabled on the server-side with executing the following SQL statement, as described in Using SSO with client applications that connect to Snowflake:

ALTER ACCOUNT SET ALLOW_ID_TOKEN = TRUE;
Copy

To use an SSO token cache in the Node.js driver, set the following options in the snowflake.createConnection() call:

  • Set authenticator to EXTERNALBROWSER. For details, see Authentication options.

  • Set clientStoreTemporaryCredential to true.

const connection = snowflake.createConnection({
  account: process.env.SNOWFLAKE_TEST_ACCOUNT,
  username: process.env.SNOWFLAKE_TEST_USER,
  database: process.env.SNOWFLAKE_TEST_DATABASE,
  schema: process.env.SNOWFLAKE_TEST_SCHEMA,
  warehouse: process.env.SNOWFLAKE_TEST_WAREHOUSE,
  authenticator: 'EXTERNALBROWSER',
  clientStoreTemporaryCredential: true,
});
Copy

When enabled, driver uses the cached token for subsequent connections until the token expires. If the driver opens a browser to authenticate the connection again, either the driver cannot find the token information in the local credential storage or the token has expired.

Cache MFA tokens

An MFA token is generated from the request when you connect to Snowflake with USERNAME_PASSWORD_MFA authentication. Caching MFA tokens on the client driver’s side only works if the server allows them to be cached. Caching MFA tokens can be enabled on the server-side with executing the following SQL statement, as described in Using MFA token caching to minimize the number of prompts during authentication — optional:

ALTER ACCOUNT SET ALLOW_CLIENT_MFA_CACHING = TRUE;
Copy

To use an MFA token cache in the Node.js driver, set the following options in the snowflake.createConnection() call:

  • Set authenticator to USERNAME_PASSWORD_MFA. For details, see Authentication options.

  • Set clientRequestMFAToken to true.

const connection = snowflake.createConnection({
  account: process.env.SNOWFLAKE_TEST_ACCOUNT,
  username: process.env.SNOWFLAKE_TEST_USER,
  database: process.env.SNOWFLAKE_TEST_DATABASE,
  schema: process.env.SNOWFLAKE_TEST_SCHEMA,
  warehouse: process.env.SNOWFLAKE_TEST_WAREHOUSE,
  authenticator: 'USERNAME_PASSWORD_MFA',
  clientRequestMFAToken: true,
});
Copy

When enabled, driver uses the cached token for subsequent connections until the token expires. If the driver reaches out to the MFA provider again, either the driver cannot find the token information in the local credential storage or the token has expired.

Use the default credential manager

The Snowflake Node.js driver provides a credential manager and credential storage. By default, the driver stores cached tokens in your $HOME directory. Currently, the driver only supports token caching with the connectAsync() function.

If you want to store the cached tokens in an alternate location, you can specify the desired location in the credentialCacheDir parameter of the snowflake.createConnection() function. You can specify either a relative or absolute path, as shown below:

  • Relative path

    const connection = snowflake.createConnection({
              credentialCacheDir: "../../<folder name>",
    });
    
    Copy
  • Absolute path

    const connection = snowflake.createConnection({
              credentialCacheDir: "C:\\<folder name>\\<subfolder name>",
    });
    
    Copy

If you do not configure credentialCacheDir, the Snowflake Node.js driver uses $HOME/temporary_credential.json to store the credentials.

Use a custom credential manager

The Snowflake node.js driver provides a default credential manager, which uses a local JSON file to store the credentials. When no credential manager is explicitly configured, the driver will use this default credential manager.

If you prefer not to use the default credential manager, you can create a custom credential manager. A custom credential manager must meet the following requirements:

  • It must minimally contain read, write, and remove functions. You can include other functions as well.

  • It must be an object data type.

The following example shows a template for minimal custom credential manager.

const sampleCustomManager = {
  read: function (key) {
  //(do something with the key)
    return token;
  },
  write: function (key, token) {
  //(do something with the key and token)
  },
  remove: function (key) {
    //(do something with the key)
  }
};
Copy

After completing your custom credential manager, you can configure it for the driver in the snowflake.configure() method, as shown. This example reflects MFA tokens, though you can also create custom credential managers for SSO tokens.

const myCredentialManager = require('<your custom credential manager module>')
const snowflake = require('snowflake-sdk');

snowflake.configure({
  customCredentialManager: myCredentialManager
})

const connection = snowflake.createConnection({
  account: process.env.SNOWFLAKE_TEST_ACCOUNT,
  database: process.env.SNOWFLAKE_TEST_DATABASE,
  schema: process.env.SNOWFLAKE_TEST_SCHEMA,
  warehouse: process.env.SNOWFLAKE_TEST_WAREHOUSE,
  authenticator: 'USERNAME_PASSWORD_MFA',
  clientRequestMFAToken: true,
});
Copy

Although the Snowflake Node.js driver provides a plugin-like interface to implement and use custom credential managers, Snowflake is not responsible for creating, implementing, or supporting custom credential managers for the customers.