Logo - Keyrus
  • Playbook
  • Services
    Data advisory & consulting
    Data & analytics solutions
    Artificial Intelligence (AI)
    Enterprise Performance Management (EPM)
    Digital & multi-experience
  • Insights
  • Partners
  • Careers
  • About us
    What sets us apart
    Company purpose
    Innovation & Technologies
    Committed Keyrus
    Regulatory compliance
    Investors
    Management team
    Brands
    Locations
  • Contact UsJoin us

Blog post

Secure Snowflake Authentication: Complete Guide to Qlik Talend Key Pair Integration with Azure Key Vault

Archan Chatterjee

As cloud data architectures become the backbone of modern enterprises, securing authentication mechanisms has evolved from a technical checkbox to a critical business requirement. With organisations growingly relying on cloud-based data integration platforms like Snowflake and Talend, the need for robust, scalable authentication mechanisms has never been more critical.

Gone are the days when storing authentication keys locally on servers was acceptable. Modern enterprises demand centralised key management that combines security with operational efficiency. This is where the powerful trio of Qlik, Talend, Snowflake, and Azure Key Vault creates a game-changing solution for secure data operations.

Whether you're a data engineer looking to eliminate security vulnerabilities in your ETL processes or a DevOps professional seeking to centralise credential management, this comprehensive guide will walk you through implementing enterprise-grade key pair authentication that your security team will applaud.

The overall flow of the integration and the sequence of steps would look like this :

High-level integration flow

Let’s look at each step in detail :

Configuration of Snowflake user:

Select the service user that will be used for establishing the connection. If users already exist, use them; otherwise, create a new user in Snowflake. Once the user is selected, mark the user as a service user using the query:

ALTER USER KRS_USER SET TYPE = SERVICE; // Execute with role which has access to alter users (SECURITYADMIN / ACCOUNTADMIN or roles that inherit the same grants)

After the user is marked as a service user, it is now time to assign it a Public key. To do that, let's first generate the keys using the following commands:

//generate the private key openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt 

//generate the public key openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub

Reference document



Once the above commands are executed, you can view the contents of rsa_key.pub using cat rsa_key.pub if working on a Unix-based platform or can open it in a text editor like notepad / notepad++ . Copy the value which you see in the file between the header ----BEGIN PUBLIC KEY----- and the footer — — — — — END PUBLIC KEY — — — — — and paste it in the placeholder mentioned below in the SQL and execute it in Snowflake.

// Execute with role which has access to alter users (SECURITYADMIN / ACCOUNTADMIN or roles which inherits the same grants) ALTER USER KRS_USER SET RSA_PUBLIC_KEY='MIIBIjANBgk........'; // Replace the value with the public key copied

Configuration of the Azure Key Vault

The key vault can be configured in either the Azure portal or through the command line directly. The steps to create the Azure Key Vault using the command line are given below; however same parameters can be passed to create the vault using the portal:

az keyvault create --name <your-keyvault-name> --resource-group <rg-name> --location <location>

Once the key vault is created, we need to upload the secrets to the vault. We already have the private key, which was created as part of step #1. In addition to it, we also need to create a certificate and upload it to the key vault. Please note that it is a self-signed dummy certificate, and it is required because Talend, which is built on the Java platform, is unable to create a keystore where the certificate is null. If you try to create the keystore without the certificate, the job would throw the error: Private key must be accompanied by certificate chain.

Create the certificate and encode the same :

# Generate private key and certificate (valid for 10 years) openssl req -x509 -newkey rsa:2048 -keyout private_key.pem -out cert.pem -days 3650 -nodes -subj "/CN=TalendServiceAccount" # Encode the certificate base64 -i cert.pem > cert_base64.txt

Upload the private key and certificate to the Azure Key Vault:

# Upload the certificate in vault as secret az keyvault secret set --vault-name "<VAULT_NAME>" --name talend-cert --value "$(cat cert_base64.txt)" # Upload the private key in vault as secret az keyvault secret set --vault-name "<VAULT_NAME>" --name "krs-snowflake-private-key" --file rsa_key.p8 # (Optional) Upload the public key in vault az keyvault secret set --vault-name "<VAULT_NAME>" --name "krs-snowflake-public-key" --file rsa_key.pub

Now, we need to make sure that the client (service principal) that Talend would access the vault has access to the key vault created. To do that, go to the Access control (IAM) of the KeyVault and assign the role “Key vault secrets officer” to the service principal.

Configuration of the Talend Job

The below Talend job design is to elaborate the steps and see the results of each step in the log using the tLog_Row component. These can be removed, and the logic can be condensed into a routine.

Note: One of the main constraints while working with Azure Key Vault is that the response is returned in a string and not in the body element, and hence, using out-of-the-box connectors such as tExtractJSONFields becomes limiting.

Before configuring this job, the details of the service principal, such as Client_ID, Client_Secret, and Azure_tenant_ID, will be required and passed as context parameters.

The list of context variables used in this example job is:

The tRESTClient can be configured as :

Basic Settings

Please note that in the Query parameters above, one parameter is not visible, which is scope, and the value is: https://vault.azure.net/.default.

To extract the access token, we can use the code below in a JavaRow component:

import java.util.regex.Pattern;

import java.util.regex.Matcher; 

String jsonString = input_row.string;

//Extract token_type using regex 

Pattern tokenPattern = Pattern.compile("\"token_type\":\\s*\"([^\"]+)\"");

Matcher tokenMatcher = tokenPattern.matcher(jsonString); 

String tokenType = tokenMatcher.find() ? tokenMatcher.group(1) : ""; 

//Extract expires_in using regex 

Pattern expiresPattern = Pattern.compile("\"expires_in\":\\s*(\\d+)"); 

Matcher expiresMatcher = expiresPattern.matcher(jsonString); 

int expiresIn = expiresMatcher.find() ? Integer.parseInt(expiresMatcher.group(1)) : 0; 

//Extract access_token using regex Pattern accessPattern = Pattern.compile("\"access_token\":\\s*\"([^\"]+)\""); 

Matcher accessMatcher = accessPattern.matcher(jsonString);

String accessToken = accessMatcher.find() ? accessMatcher.group(1) : ""; 

//Assign to output output_row.token_type = tokenType; output_row.expires_in = expiresIn; output_row.access_token = accessToken; context.AZ_TOKEN = accessToken;

To call the key vault, we can use the code below:

import java.net.http.HttpClient; 

import java.net.http.HttpRequest; 

import java.net.http.HttpResponse;

import java.net.URI; import java.time.Duration; 

// Your extracted bearer token String bearerToken = context.AZ_TOKEN; // From previous extraction

// Key Vault configuration and change the vault name below String keyVaultName = "<VAULT_NAME>";

String keyName = "krs-snowflake-private-key"; String apiVersion = "7.4"; 

// Build the URL String url = String.format("https://%s.vault.azure.net/secrets/%s?api-version=%s", keyVaultName, keyName, apiVersion); 

try { // Create HTTP client HttpClient client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(30)) .build(); 

// Create request HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .header("Authorization", "Bearer " + bearerToken) .header("Content-Type", "application/json") .GET() .build();

// Send request HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { String responseBody = response.body(); 

// Extract the key value from JSON response // The private key is typically in the 'key' object output_row.key_response = responseBody; output_row.status = "SUCCESS"; } else { output_row.status = "ERROR: " + response.statusCode(); output_row.key_response = response.body();

}

} catch (Exception e) { output_row.status = "ERROR: " + e.getMessage(); output_row.key_response = "";

}

In the next tJavaRow component, the following actions happen :

  1. Extracting the private key from the string returned by Azure Key Vault

  2. Call the Azure Key Vault and get the certificate

  3. Decode the private key and certificate

  4. Create and populate a keystore with an alias

  5. Assign the Keystore path and password to the respective context parameters

Now, since the key store is created, we need to set the key store using the tSetKeystore component, and the properties would be :

We now have to use the keystore alias to establish the Snowflake connection:

Note: Some suggestions while productionising this solution :

  • Embed the logic in multiple tJavaRow components in a routine

  • Use the context variables to pass the keystore alias

  • Use the snowflake connection from the repository

  • Set up separate keys for production and test users, and avoid using the same keys and certificates

  • The datatype of Client secret is to be set as encrypted and is not copied and visible elsewhere, while code promotion or artifact build.

  • In case you need to make a REST call using any of the REST components after setting the keystore, please ensure that the default certificates are also added to the keystore created; otherwise, the later calls to REST endpoints would fail. Add the below piece of code while creating the in-memory keystore:

And, in addition to it, in the tSetKeystore component, add the keystorePath as the trust store as well:

// Step 1: Load default truststore (cacerts) KeyStore trustStore = KeyStore.getInstance("JKS"); trustStore.load(new FileInputStream(System.getProperty("java.home") + "/lib/security/cacerts"), "changeit".toCharArray()); 

//Step 2: Create and populate the keystore KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(null, null); keyStore.setKeyEntry("snowflakeKey", privateKey, password, new Certificate[]{ certificate });

//Step 3: Add trusted certs from default truststore Enumeration<String> aliases = trustStore.aliases(); while (aliases.hasMoreElements()) { String trustAlias = aliases.nextElement(); if (trustStore.isCertificateEntry(trustAlias)) { Certificate trustedCert = trustStore.getCertificate(trustAlias); keyStore.setCertificateEntry(trustAlias, trustedCert);

 }

}

And, in addition to it, in the tSetKeystore component, add the keystorePath as the trust store as well :

About the Author: This comprehensive guide is authored by Archan Chatterjee, Principal Consultant and Technical Expert at Keyrus UK, bringing real-world expertise from enterprise-level implementations to help you master secure cloud data integration.

Why Keyrus? At Keyrus, we don't just implement solutions—we architect secure, scalable data ecosystems that drive business transformation. Our team of certified cloud specialists has successfully deployed hundreds of enterprise data integration projects, combining deep technical expertise with industry best practices. Whether you're modernising legacy systems or building cloud-native architectures from scratch, Keyrus UK delivers the strategic guidance and hands-on implementation expertise to accelerate your data journey while maintaining the highest security standards.

Logo - Keyrus
London

One Canada Square Canary Wharf London E14 5AA