Blog Post

Microsoft Developer Community Blog
16 MIN READ

Enhancing Data Security and Digital Trust in the Cloud using Azure Services.

sasina's avatar
sasina
Brass Contributor
Sep 05, 2024

 

Introduction

Think of Client-Side Encryption (CSE) as a strategy that has proven to be most effective in augmenting data security and modern precursor to traditional approaches. In addition to providing a stronger security posture, this strategy is also in compliance with major data regulations like GDPR, FERPA and PCI-DSS. In this article, we’ll explore how CSE can provide superior protection for your data, particularly if an authentication and authorization account is compromised. We’ll also address common questions about Microsoft's stance on CSE and explain why CSE might not be as widely discussed as Client-Side Key Encryption (CSKE). By understanding these concepts, you can better meet security and regulatory requirements and ensure that your data remains protected.

 

Use Case

As shown below in the Figure 1: An example of Use Case Architecture. Protecting and managing financial and health sensitive data for clients is subject to stringent regulatory requirements such as GDPR and PCI-DSS and also the followings:

  • E-commerce: Protecting customer data such as credit card information, personal details, and purchase history is crucial to maintaining trust and complying with regulations like GDPR and PCI-DSS.
  • Technology and Software Development: Intellectual property, source code, and proprietary algorithms are valuable assets that need protection from unauthorized access and industrial espionage.  
  • Education: Institutions handle a significant amount of sensitive data, including student records, research data, and personal information of faculty and staff. Compliance with regulations like FERPA (Family Educational Rights and Privacy Act) is essential to protect the privacy of student information.

Practical Use Case scenario for CSE

  • Organizations handling highly sensitive information (e.g., sensitive personal information) can use CSE to ensure that data remains protected at all times, even if the cloud infrastructure is compromised.
  • Where and when clients need to comply with regulations that requiring strict control over the encryption keys and data access, CSE allows them to manage keys externally, ensuring no unauthorized access by cloud providers.
  • Organizations concerned about data governance, sovereignty and privacy can use CSE to ensure that their data is protected in line with local laws and privacy regulations.

Figure 1: An example of Use Case Architecture

Understanding the concept

As it shown in the Figure 2: The Concept, the processes involved in client-side encryption (CSE) are the followings:

  • The client device or application utilizes the authentications and authorization components, authenticates with Azure Key Vault to securely retrieve the encryption key.
  • The client application uses the retrieved encryption key to encrypt the data, ensuring it is securely transformed into an encrypted format.
  • The client uploads the encrypted data to Azure Storage, where it is stored securely in its encrypted form.
  • When needed, the client retrieves the encrypted data from Azure Storage.
  • The client retrieves the encryption key again from Azure Key Vault.
  • It then decrypts the data, making it usable.

 

Figure 2: The Concept

 

In a nutshell:

  • The company uses strong encryption algorithms AES-256 to encrypt data on the client side before uploading it to Azure Blob Storage.
  • Encryption keys are stored securely using a hardware security module (HSM), ensuring that keys are never exposed to the cloud service provider.
  • Encrypted data is uploaded to Azure, and only authorized client-side applications can decrypt and access the data using the securely managed keys.
  • NOTE: This does not jeopardize service-side encryption features for ease of use in protecting your data and if you are using client-side encryption, migrate your applications to version 2 for improved security.

 

Understanding Client-Side Encryption (CSE) and Client-Side Key Encryption (CSKE).

Client-Side Encryption (CSE) provides a significant security advantage by allowing organizations to maintain complete control over their data and encryption keys. This method not only enhances data security but also supports compliance with regulatory requirements, offering peace of mind in the ever-evolving landscape of cloud computing. CSE encrypts data before it is sent to any service like Azure and this means that the data is encrypted on the client’s side, and Azure never sees the encryption keys. Even if someone gains access to your Azure account, they cannot read your data without the keys. In contrast, Client-Side Key Encryption (CSKE) focuses on securing the encryption keys themselves. The client manages and controls these keys, ensuring they are not accessible to the cloud service. This adds an extra layer of protection by keeping the keys out of the service provider’s reach. Both approaches enhance security but address different aspects of data protection.

 

Why We Need Client-Side Encryption (CSE)

Enhanced Security

  • With CSE, data is encrypted before it leaves the client’s environment. This means that even if the cloud service is compromised, the attacker only has access to encrypted data, which is useless without the decryption keys.
  • There is no risk of them being exposed through cloud service vulnerabilities.

Regulatory Compliance

  • Under regulations like GDPR, data breaches involving encrypted data where the keys are not compromised may not require reporting. CSE ensures that the data is encrypted in a way that meets these regulatory requirements.
  • For industries with strict data protection requirements (e.g., healthcare, finance), CSE provides a way to handle sensitive data securely and meet compliance standards.

Data Ownership and Control

  • The client maintains full control over the encryption keys. This autonomy helps organizations enforce their own security policies and procedures.
  • Clients can ensure that their data sovereignty requirements are met since they control where and how the encryption keys are stored and managed.

 

Why Not Client-Side Key Encryption (CSKE) Alone

Reliance on Cloud Service

  • Even though CSKE allows clients to manage the encryption keys, the cloud service still handles the encryption and decryption operations. If the cloud service is compromised, there’s a risk that the data could be decrypted by the attacker using the stolen keys.
  • CSKE requires trusting that the cloud service’s encryption processes are secure and that there are no vulnerabilities that could be exploited to access the data.

 

Key Exposure Risks

  • With CSKE, there’s a shared responsibility between the client and the cloud service for data protection. Any lapses on the cloud service side could lead to key exposure.
  • While clients manage the keys, they must still rely on the cloud service to handle the actual encryption and decryption processes securely.

 

Azure's Position on CSE

Most of Azure’s documentation and services tend to emphasize Server-Side Encryption (SSE) due to its simplicity and ease of use for most scenarios. SSE allows Azure to provide a straightforward security model that works out-of-the-box for users, without requiring significant changes to their applications or processes.

However, Azure does support CSE through various SDKs and client libraries. For instance, Azure Storage SDKs for different programming languages provide support for encrypting data on the client side before uploading it to Azure Blob Storage.

 

Step-by-Step Solution for Implementing Client-Side Encryption (CSE) for Python, .NET Core Blazor App using C#, and Java Apps.

 

Requirements (Refers to Figure 1: An example of Use Case Architecture) 

Cloud provider (Microsoft Azure)

  • Choose the Right Azure Storage
  • Select the Encryption Mode
  • Ensure Right Dependencies
  • Azure Key Vault Integration
  • Azure Blob Storage (In this context)

 

Your organization responsibility to implement CSE

  • Determine the level of security needed for your data.
  • Identify any regulations (like GDPR) that mandate specific encryption practices.
  • Choose a strong encryption algorithm (AES-256) latest version and a reliable encryption library in your programming language of choice. For example, Python’s cryptography library, Java’s javax.crypto  or C# security.cryptography.algorithms package.
  • Azure subscription, storage account, and .NET SDK.

 

To implement Client-Side Encryption (CSE) in your application using Azure Key Vault and Azure Blob Storage.

 

Azure Key Vault

You will set up Azure Key Vault to store and manage encryption keys securely.

 

  1. You will need to create a Key Vault as this will help to create RSA, EC, or AES keys in Managed HSM, then use them for encryption-at-rest in Azure Storage, Azure SQL, and more. So, in the Azure portal, create a new Key Vault resource as shown below.
 

Figure 3: Creating Azure Key Vault

 You will Navigate to Administrators by click on it, then Click Add principal, then select your apps as seen on the screen below:

Figure 4: Add Administrator for Azure Key Vault Managed HSM

 

 

This will Set the permissions for the Key Vault, ensuring that your application can access the keys. So, review to create and Click on Create button as shown below:

Figure 5: Review and create Azure Key Vault

 

It might take a couple of minutes for your Azure Key Vault creation to deploy successfully.

 

Figure 6: Azure Key Vault deployment is complete

 

 

 

  1. Create or Import Encryption Keys:

Next is to create a new key or import an existing key in the Key Vault. This key will be used for encrypting and decrypting data. But prior to this you must have updated your network settings. So, let’s use Azure CLI:

  • To Create a New Key using bash in Azure CLI

 

 

az keyvault key create --vault-name <YourKeyVaultName> --name <YourKeyName> --protection software

 

 

  • To Import an Existing Key (If you have a key in a PEM or PFX file, you can import it) using bash in Azure CLI.

 

 

az keyvault key import --vault-name <YourKeyVaultName> --name <YourKeyName> --pem-file <YourPemFilePath>

 

 

 

Replace <YourKeyVaultName>, <YourKeyName>, and <YourPemFilePath> with your Key Vault name, the key name, and the path to your key file.

 

 

  1. Assign Access Policies to allow your app to perform operations like `wrapKey` and `unwrapKey` with the key using bash in Azure CLI:

 

 

az keyvault set-policy --name <YourKeyVaultName> --spn <YourAppServicePrincipalId> --key-permissions get list wrapKey unwrapKey

 

 

Replace <YourKeyVaultName> with your Key Vault name and <YourAppServicePrincipalId> with the service principal ID of your Blazor app.

 

Azure Blob Storage

You will configure Azure Blob Storage to store the encrypted data. You will be using Azure Storage client libraries for Blob Storage or Queue Storage if that’s your choice with the same steps.

 

  1. In the Azure portal, create a new Blob Storage account (Quickstart blobs)  or using Azure CLI as shown below:

 

 

az storage account create --name <YourStorageAccountName> --resource-group <YourResourceGroup> --location <YourLocation> --sku Standard_LRS --kind StorageV2

 

 

Replace <YourStorageAccountName>, <YourResourceGroup>, and <YourLocation> with your desired storage account name, resource group, and Azure region.

 

  1. Configure access control for your Blob Storage account, ensuring your app can read and write data using a service principal, for example you can assign a role like Storage Blob Data Contributor:

 

 

az role assignment create --assignee <YourAppServicePrincipalId> --role "Storage Blob Data Contributor" --scope /subscriptions/<YourSubscriptionId>/resourceGroups/<YourResourceGroup>/providers/Microsoft.Storage/storageAccounts/<YourStorageAccountName>

 

 

Replace <YourAppServicePrincipalId>, <YourSubscriptionId>, <YourResourceGroup>, and <YourStorageAccountName> with your service principal ID, subscription ID, resource group, and storage account name.

 

  1. Use SAS tokens or managed identities to secure access to the Blob Storage account. To generate a SAS token for the storage account using Azure CLI:

 

 

az storage account generate-sas --account-name <YourStorageAccountName> --permissions rwl --expiry <YYYY-MM-DD> --resource-types sco --services b --https-only

 

 

If your app is using a managed identity, the role assignment from previous step, it will automatically secure the storage account access, and no additional steps are required.

Replace <YourStorageAccountName> and <YYYY-MM-DD> with your storage account name and desired expiry date.

 

Implementing Client-Side Encryption for Python App

 

Encryption and Uploading in Python:

 

  1. Install the required libraries in bash command

  

 

 

 pip install cryptography azure-storage-blob

 

 

 

  1. Encryption and Uploading in Python, for example:

  

 

 


   from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

   from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

   from cryptography.hazmat.backends import default_backend

   from cryptography.hazmat.primitives import hashes

   from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient

   import os

   from base64 import urlsafe_b64encode



   # Configuration

   account_url = "https://<your_storage_account>.blob.core.windows.net"

   container_name = "my-container"

   blob_name = "my-encrypted-blob"

   key = b'secret_key'  # Replace with your secret key



   # Function to encrypt data

   def encrypt_data(data, key):

       backend = default_backend()

       salt = os.urandom(16)

       kdf = PBKDF2HMAC(

           algorithm=hashes.SHA256(),

           length=32,

           salt=salt,

           iterations=100000,

           backend=backend

       )

       key = kdf.derive(key)

       iv = os.urandom(16)

       cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=backend)

       encryptor = cipher.encryptor()

       encrypted_data = encryptor.update(data) + encryptor.finalize()

       return salt + iv + encrypted_data



   # Sample data to encrypt

   data = b"Sensitive data that needs encryption"



   # Encrypt the data

   encrypted_data = encrypt_data(data, key)



   # Upload encrypted data to Azure Blob Storage

   blob_service_client = BlobServiceClient(account_url=account_url)

   blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)

   blob_client.upload_blob(encrypted_data, overwrite=True)



   print("Data encrypted and uploaded successfully.")

 

 

 

Downloading and Decrypting in Python:

 

Decrypt and Download Data:

  

 

 


   from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

   from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

   from cryptography.hazmat.backends import default_backend

   from cryptography.hazmat.primitives import hashes

   from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient

   import os



   # Configuration

   account_url = "https://<your_storage_account>.blob.core.windows.net"

   container_name = "my-container"

   blob_name = "my-encrypted-blob"

   key = b'secret_key'  # Replace with your secret key



   # Function to decrypt data

   def decrypt_data(encrypted_data, key):

       backend = default_backend()

       salt = encrypted_data[:16]

       iv = encrypted_data[16:32]

       ciphertext = encrypted_data[32:]

       kdf = PBKDF2HMAC(

           algorithm=hashes.SHA256(),

           length=32,

           salt=salt,

           iterations=100000,

           backend=backend

       )

       key = kdf.derive(key)

       cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=backend)

       decryptor = cipher.decryptor()

       decrypted_data = decryptor.update(ciphertext) + decryptor.finalize()

       return decrypted_data

   # Download encrypted data from Azure Blob Storage

   blob_service_client = BlobServiceClient(account_url=account_url)

   blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)

   encrypted_data = blob_client.download_blob().readall()


   # Decrypt the data

   decrypted_data = decrypt_data(encrypted_data, key)

   print(f"Decrypted data: {decrypted_data.decode('utf-8')}")

  

 

 

 

Implementing Client-Side Encryption for .NET Core Blazor App using C#

 

Encryption and uploading in C#:

 

 

  1. Irrespective of IDE you are using, Install the required NuGet packages:

  

 

 

dotnet add package Azure.Storage.Blobs
dotnet add package System.Security.Cryptography.Algorithms

 

 

 

  1. Encryption and Uploading code example:

 

 

 

   using System;
   using System.IO;
   using System.Security.Cryptography;
   using Azure.Storage.Blobs;
   using Azure.Storage.Blobs.Models;


   // Configuration
   string accountUrl = "https://<your_storage_account>.blob.core.windows.net";
   string containerName = "my-container";
   string blobName = "my-encrypted-blob";
   byte[] key = Convert.FromBase64String("your_base64_secret_key"); // Replace with your Base64 encoded secret key


   // Function to encrypt data
   byte[] EncryptData(byte[] data, byte[] key)
   {
       using var aes = Aes.Create();
       aes.Key = key;
       aes.GenerateIV();
       using var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
       using var ms = new MemoryStream();
       ms.Write(aes.IV, 0, aes.IV.Length);
       using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
       {
           cs.Write(data, 0, data.Length);
       }
       return ms.ToArray();

   }

   // Sample data to encrypt
   byte[] data = System.Text.Encoding.UTF8.GetBytes("Sensitive data that needs encryption");


   // Encrypt the data
   byte[] encryptedData = EncryptData(data, key);

   // Upload encrypted data to Azure Blob Storage
   BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(accountUrl));
   BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
   BlobClient blobClient = containerClient.GetBlobClient(blobName);
   using (var ms = new MemoryStream(encryptedData))
   {
       blobClient.Upload(ms, new BlobHttpHeaders { ContentType = "application/octet-stream" }, true);

   }

   Console.WriteLine("Data encrypted and uploaded successfully.");



 

 

Downloading and Decrypting Example in C#:

 

Decrypt and Download Data:

 

 

   using System;
   using System.IO;
   using System.Security.Cryptography;
   using Azure.Storage.Blobs;

   // Configuration
   string accountUrl = "https://<your_storage_account>.blob.core.windows.net";
   string containerName = "my-container";
   string blobName = "my-encrypted-blob";
   byte[] key = Convert.FromBase64String("your_base64_secret_key"); // Replace with your Base64 encoded secret key


   // Function to decrypt data
   byte[] DecryptData(byte[] encryptedData, byte[] key)
   {
       using var aes = Aes.Create();
       using var ms = new MemoryStream(encryptedData);
       byte[] iv = new byte[aes.BlockSize / 8];
       ms.Read(iv, 0, iv.Length);
       using var decryptor = aes.CreateDecryptor(key, iv);
       using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
       using var result = new MemoryStream();
       cs.CopyTo(result);
       return result.ToArray();
   }


   // Download encrypted data from Azure Blob Storage
   BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(accountUrl));
   BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
   BlobClient blobClient = containerClient.GetBlobClient(blobName);


   using var ms = new MemoryStream();
   blobClient.DownloadTo(ms);
   byte[] encryptedData = ms.ToArray();

   // Decrypt the data
   byte[] decryptedData = DecryptData(encryptedData, key);
   Console.WriteLine($"Decrypted data: {System.Text.Encoding.UTF8.GetString(decryptedData)}");

 

 

 

Replace <your_storage_account> and your_base64_secret_key with your actual storage account URL and Base64 encoded secret key, respectively.

 

Implementing Client-Side Encryption for Java application

 

Encryption and Uploading in Java:

 

  1. You will first need to add the required dependencies to your pom.xml:

 

 

   <dependency>
       <groupId>com.azure</groupId>
       <artifactId>azure-storage-blob</artifactId>
       <version>12.16.0</version>
   </dependency>
   <dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcprov-jdk15on</artifactId>
       <version>1.70</version>
   </dependency>

 

 

  

 

  1. Encryption and uploading similar code sample:

 

 

   import com.azure.storage.blob.BlobClient;
   import com.azure.storage.blob.BlobContainerClient;
   import com.azure.storage.blob.BlobServiceClient;
   import com.azure.storage.blob.BlobServiceClientBuilder;
   import org.bouncycastle.jce.provider.BouncyCastleProvider;
   import javax.crypto.Cipher;
   import javax.crypto.KeyGenerator;
   import javax.crypto.SecretKey;
   import javax.crypto.spec.IvParameterSpec;
   import java.nio.file.Files;
   import java.nio.file.Path;
   import java.nio.file.Paths;
   import java.security.Security;
   import java.util.Base64;

   public class EncryptAndUpload {
       static {
           Security.addProvider(new BouncyCastleProvider());
       }

       private static final String ACCOUNT_URL = "https://<your_storage_account>.blob.core.windows.net";
       private static final String CONTAINER_NAME = "my-container";
       private static final String BLOB_NAME = "my-encrypted-blob";
       private static final String SECRET_KEY = "your_base64_secret_key"; // Replace with your Base64 encoded secret key

       public static void main(String[] args) throws Exception {
    
       // Sample data to encrypt
           byte[] data = "Sensitive data that needs encryption".getBytes();

           // Encrypt the data
           byte[] encryptedData = encryptData(data);

           // Upload encrypted data to Azure Blob Storage
           BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(ACCOUNT_URL).buildClient();
           BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(CONTAINER_NAME);
           BlobClient blobClient = containerClient.getBlobClient(BLOB_NAME);

           Path tempFile = Files.createTempFile("encrypted", ".dat");
           Files.write(tempFile, encryptedData);
           blobClient.uploadFromFile(tempFile.toString(), true);
           System.out.println("Data encrypted and uploaded successfully.");
       }

       private static byte[] encryptData(byte[] data) throws Exception {
           SecretKey key = getKeyFromBase64(SECRET_KEY);
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
           byte[] iv = new byte[cipher.getBlockSize()];
           new java.security.SecureRandom().nextBytes(iv);
           cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
           byte[] encryptedData = cipher.doFinal(data);
           byte[] ivAndEncryptedData = new byte[iv.length + encryptedData.length];
           System.arraycopy(iv, 0, ivAndEncryptedData, 0, iv.length);
           System.arraycopy(encryptedData, 0, ivAndEncryptedData, iv.length, encryptedData.length);
           return ivAndEncryptedData;
       }

       private static SecretKey getKeyFromBase64(String base64Key) {
           byte[] decodedKey = Base64.getDecoder().decode(base64Key);
           return new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
       }
   }

 

 

  

Downloading and Decrypting in Java

 

Decrypt and Download Data:

  

 

 

   import com.azure.storage.blob.BlobClient;
   import com.azure.storage.blob.BlobContainerClient;
   import com.azure.storage.blob.BlobServiceClient;
   import com.azure.storage.blob.BlobServiceClientBuilder;
   import org.bouncycastle.jce.provider.BouncyCastleProvider;
   import javax.crypto.Cipher;
   import javax.crypto.SecretKey;
   import javax.crypto.spec.IvParameterSpec;
   import java.nio.file.Files;
   import java.nio.file.Path;
   import java.nio.file.Paths;
   import java.security.Security;
   import java.util.Base64;

   public class DownloadAndDecrypt {
       static {
           Security.addProvider(new BouncyCastleProvider());
       }

       private static final String ACCOUNT_URL = "https://<your_storage_account>.blob.core.windows.net";
       private static final String CONTAINER_NAME = "my-container";
       private static final String BLOB_NAME = "my-encrypted-blob";
       private static final String SECRET_KEY = "your_base64_secret_key"; // Replace with your Base64 encoded secret key

       public static void main(String[] args) throws Exception {
    
       // Download encrypted data from Azure Blob Storage
           BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(ACCOUNT_URL).buildClient();
           BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(CONTAINER_NAME);
           BlobClient blobClient = containerClient.getBlobClient(BLOB_NAME);


           Path tempFile = Files.createTempFile("encrypted", ".dat");
           blobClient.downloadToFile(tempFile.toString());
           byte[] encryptedData = Files.readAllBytes(tempFile);


           // Decrypt the data
           byte[] decryptedData = decryptData(encryptedData);

           System.out.println("Decrypted data: " + new String(decryptedData));
       }


       private static byte[] decryptData(byte[] encryptedData) throws Exception {
           SecretKey key = getKeyFromBase64(SECRET_KEY);
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
           byte[] iv = new byte[cipher.getBlockSize()];
           System.arraycopy(encryptedData, 0, iv, 0, iv.length);
           byte[] encryptedContent = new byte[encryptedData.length - iv.length];
           System.arraycopy(encryptedData, iv.length, encryptedContent, 0, encryptedContent.length);
           cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
           return cipher.doFinal(encryptedContent);
       }

       private static SecretKey getKeyFromBase64(String base64Key) {
           byte[] decodedKey = Base64.getDecoder().decode(base64Key);
           return new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
      }
   }

 

 

 

Likewise, you will replace <your_storage_account> and your_base64_secret_key with your actual storage account URL and Base64 encoded secret key, respectively and ensure you are using the latest Azure SDK.

 

Managing Encryption Keys

  • Store encryption keys securely, preferably in a hardware security module (HSM) or a key management service (KMS) and make sure you regularly rotate encryption keys to enhance security.

 

Verifying and Testing

  • Ensure that encryption and decryption processes are secure and cannot be bypassed.
  • Verify that your implementation meets all regulatory requirements.

 

Outcome

  • Even if the cloud storage is compromised, the encrypted data remains secure as the keys are not accessible to the attacker.
  • The company meets regulatory requirements by ensuring data is encrypted in a way that aligns with GDPR, PCI-DSS, and FERPA digital trust standards.
  • Full control over encryption keys and data access policies enhances the company’s ability to protect its clients' sensitive financial information.

 

Conclusion

We have seen so far, how Client-Side Encryption (CSE) provides an enhanced level of security by ensuring that data is encrypted before it leaves the client’s environment, and how we can implement this with three different programing languages for Azure App using Azure Key Vault, Azure Blob and create Azure Storage Account. This method aligns well with regulatory requirements such as GDPR, PCI-DSS, and FERPA, offering greater control over sensitive information and protecting it from breaches and unauthorized access. By implementing CSE, can better meet security and regulatory requirements, ensuring the highest level of data protection. It helps provides enhanced protection against data breaches. While it involves more complexity than Client-Side Key Encryption (CSKE), it offers significant security benefits that are crucial for handling sensitive data. CSE enhances security by allowing you to manage encryption keys independently. It's a valuable practice for safeguarding sensitive information in cloud solutions!

 

 

CAUTION:

  1. The code might need to upgrade depend on the time you are performing these tasks.
  2. If you are using Azure file share as a Persistent Volume Claim (PVC) in Azure Kubernetes Service (AKS) with POD workload identity to retrieve secret you will use the Secrets Store CSI Driver to natively retrieve secret contents from Azure Key Vault. This driver securely provides secrets to the requesting pods: https://learn.microsoft.com/en-us/azure/aks/developer-best-practices-pod-security

 

References

For more information on Azure's support for Client-Side Encryption and to access further resources on Azure's official documentation and security best practices.

 

 

Updated Sep 08, 2024
Version 2.0
No CommentsBe the first to comment
"}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/Pager/PagerLoadMore\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeDescription\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505307000"}]},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":null,"possibleValues":["en-US","es-ES"]},"repliesSortOrder":{"__typename":"InheritableStringSettingWithPossibleValues","key":"config.user_replies_sort_order","value":"DEFAULT","localValue":"DEFAULT","possibleValues":["DEFAULT","LIKES","PUBLISH_TIME","REVERSE_PUBLISH_TIME"]}},"deleted":false},"CachedAsset:pages-1747123677058":{"__typename":"CachedAsset","id":"pages-1747123677058","value":[{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1747123677058,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}","userBanned":"We're sorry, but you have been banned from using this site.","userBannedReason":"You have been banned for the following reason: {reason}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"Rank:rank:36":{"__typename":"Rank","id":"rank:36","position":17,"name":"Brass Contributor","color":"333333","icon":null,"rankStyle":"TEXT"},"User:user:506258":{"__typename":"User","id":"user:506258","uid":506258,"login":"sasina","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS01MDYyNTgtMjM1NzE3aTdBNTk2QTgyRDkyN0I0NTQ"},"rank":{"__ref":"Rank:rank:36"},"email":"","messagesCount":24,"biography":null,"topicsCount":4,"kudosReceivedCount":10,"kudosGivenCount":27,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2020-01-04T09:13:43.936-08:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":0},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","entityType":"CATEGORY","displayId":"Azure","nodeType":"category","depth":3,"title":"Azure","shortTitle":"Azure","parent":{"__ref":"Category:category:products-services"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","entityType":"CATEGORY","displayId":"top","nodeType":"category","depth":0,"title":"Top","shortTitle":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","entityType":"CATEGORY","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities","shortTitle":"Communities"},"Category:category:products-services":{"__typename":"Category","id":"category:products-services","entityType":"CATEGORY","displayId":"products-services","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Products","shortTitle":"Products"},"Blog:board:AzureDevCommunityBlog":{"__typename":"Blog","id":"board:AzureDevCommunityBlog","entityType":"BLOG","displayId":"AzureDevCommunityBlog","nodeType":"board","depth":4,"conversationStyle":"BLOG","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"REVERSE_PUBLISH_TIME","repliesFormat":"threaded"},"tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":false,"tagType":"PRESET_ONLY","description":"","title":"Microsoft Developer Community Blog","shortTitle":"Microsoft Developer Community Blog","parent":{"__ref":"Category:category:Azure"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:products-services"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:Azure"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"theme":{"__ref":"Theme:customTheme1"},"boardPolicies":{"__typename":"BoardPolicies","canViewSpamDashBoard":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.access_spam_quarantine.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.access_spam_quarantine.allowed.accessDenied","args":[]}},"canArchiveMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.content_archivals.enable_content_archival_settings.accessDenied","key":"error.lithium.policies.content_archivals.enable_content_archival_settings.accessDenied","args":[]}},"canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}}},"BlogTopicMessage:message:4234937":{"__typename":"BlogTopicMessage","uid":4234937,"subject":"Enhancing Data Security and Digital Trust in the Cloud using Azure Services.","id":"message:4234937","revisionNum":5,"repliesCount":0,"author":{"__ref":"User:user:506258"},"depth":0,"hasGivenKudo":false,"board":{"__ref":"Blog:board:AzureDevCommunityBlog"},"conversation":{"__ref":"Conversation:conversation:4234937"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:4234937"},"teaser":"

Enhancing Data Security and Digital Trust in the Cloud by Implementing Client-Side Encryption (CSE) using Azure Apps, Azure Storage and Azure Key Vault. Think of Client-Side Encryption (CSE) as a strategy that has proven to be most effective in augmenting data security and modern precursor to traditional approaches. CSE can provide superior protection for your data, particularly if an authentication and authorization account is compromised.

","body":"

\n

 

\n

Introduction

\n

Think of Client-Side Encryption (CSE) as a strategy that has proven to be most effective in augmenting data security and modern precursor to traditional approaches. In addition to providing a stronger security posture, this strategy is also in compliance with major data regulations like GDPR, FERPA and PCI-DSS. In this article, we’ll explore how CSE can provide superior protection for your data, particularly if an authentication and authorization account is compromised. We’ll also address common questions about Microsoft's stance on CSE and explain why CSE might not be as widely discussed as Client-Side Key Encryption (CSKE). By understanding these concepts, you can better meet security and regulatory requirements and ensure that your data remains protected.

\n

 

\n

Use Case

\n

As shown below in the Figure 1: An example of Use Case Architecture. Protecting and managing financial and health sensitive data for clients is subject to stringent regulatory requirements such as GDPR and PCI-DSS and also the followings:

\n\n

Practical Use Case scenario for CSE

\n\n

Figure 1: An example of Use Case Architecture

\n

Understanding the concept

\n

As it shown in the Figure 2: The Concept, the processes involved in client-side encryption (CSE) are the followings:

\n\n

 

\n

Figure 2: The Concept

\n

 

\n

In a nutshell:

\n\n

 

\n

Understanding Client-Side Encryption (CSE) and Client-Side Key Encryption (CSKE).

\n

Client-Side Encryption (CSE) provides a significant security advantage by allowing organizations to maintain complete control over their data and encryption keys. This method not only enhances data security but also supports compliance with regulatory requirements, offering peace of mind in the ever-evolving landscape of cloud computing. CSE encrypts data before it is sent to any service like Azure and this means that the data is encrypted on the client’s side, and Azure never sees the encryption keys. Even if someone gains access to your Azure account, they cannot read your data without the keys. In contrast, Client-Side Key Encryption (CSKE) focuses on securing the encryption keys themselves. The client manages and controls these keys, ensuring they are not accessible to the cloud service. This adds an extra layer of protection by keeping the keys out of the service provider’s reach. Both approaches enhance security but address different aspects of data protection.

\n

 

\n

Why We Need Client-Side Encryption (CSE)

\n

Enhanced Security

\n\n

Regulatory Compliance

\n\n

Data Ownership and Control

\n\n

 

\n

Why Not Client-Side Key Encryption (CSKE) Alone

\n

Reliance on Cloud Service

\n\n

 

\n

Key Exposure Risks

\n\n

 

\n

Azure's Position on CSE

\n

Most of Azure’s documentation and services tend to emphasize Server-Side Encryption (SSE) due to its simplicity and ease of use for most scenarios. SSE allows Azure to provide a straightforward security model that works out-of-the-box for users, without requiring significant changes to their applications or processes.

\n

However, Azure does support CSE through various SDKs and client libraries. For instance, Azure Storage SDKs for different programming languages provide support for encrypting data on the client side before uploading it to Azure Blob Storage.

\n

 

\n

Step-by-Step Solution for Implementing Client-Side Encryption (CSE) for Python, .NET Core Blazor App using C#, and Java Apps.

\n

 

\n

Requirements (Refers to Figure 1: An example of Use Case Architecture) 

\n

Cloud provider (Microsoft Azure)

\n\n

 

\n

Your organization responsibility to implement CSE

\n\n

 

\n

To implement Client-Side Encryption (CSE) in your application using Azure Key Vault and Azure Blob Storage.

\n

 

\n

Azure Key Vault

\n

You will set up Azure Key Vault to store and manage encryption keys securely.

\n

 

\n
    \n
  1. You will need to create a Key Vault as this will help to create RSA, EC, or AES keys in Managed HSM, then use them for encryption-at-rest in Azure Storage, Azure SQL, and more. So, in the Azure portal, create a new Key Vault resource as shown below.
  2. \n
\n
 
\n

Figure 3: Creating Azure Key Vault

\n

 You will Navigate to Administrators by click on it, then Click Add principal, then select your apps as seen on the screen below:

\n

Figure 4: Add Administrator for Azure Key Vault Managed HSM

\n

 

\n

 

\n

This will Set the permissions for the Key Vault, ensuring that your application can access the keys. So, review to create and Click on Create button as shown below:

\n

Figure 5: Review and create Azure Key Vault

\n

 

\n

It might take a couple of minutes for your Azure Key Vault creation to deploy successfully.

\n

 

\n

Figure 6: Azure Key Vault deployment is complete

\n

 

\n

 

\n

 

\n
    \n
  1. Create or Import Encryption Keys:
  2. \n
\n

Next is to create a new key or import an existing key in the Key Vault. This key will be used for encrypting and decrypting data. But prior to this you must have updated your network settings. So, let’s use Azure CLI:

\n\n

 

\n

 

\n
az keyvault key create --vault-name <YourKeyVaultName> --name <YourKeyName> --protection software
\n

 

\n

 

\n\n

 

\n

 

\n
az keyvault key import --vault-name <YourKeyVaultName> --name <YourKeyName> --pem-file <YourPemFilePath>
\n

 

\n

 

\n

 

\n

Replace <YourKeyVaultName>, <YourKeyName>, and <YourPemFilePath> with your Key Vault name, the key name, and the path to your key file.

\n

 

\n

 

\n
    \n
  1. Assign Access Policies to allow your app to perform operations like `wrapKey` and `unwrapKey` with the key using bash in Azure CLI:
  2. \n
\n

 

\n

 

\n
az keyvault set-policy --name <YourKeyVaultName> --spn <YourAppServicePrincipalId> --key-permissions get list wrapKey unwrapKey
\n

 

\n

 

\n

Replace <YourKeyVaultName> with your Key Vault name and <YourAppServicePrincipalId> with the service principal ID of your Blazor app.

\n

 

\n

Azure Blob Storage

\n

You will configure Azure Blob Storage to store the encrypted data. You will be using Azure Storage client libraries for Blob Storage or Queue Storage if that’s your choice with the same steps.

\n

 

\n
    \n
  1. In the Azure portal, create a new Blob Storage account (Quickstart blobs)  or using Azure CLI as shown below:
  2. \n
\n

 

\n

 

\n
az storage account create --name <YourStorageAccountName> --resource-group <YourResourceGroup> --location <YourLocation> --sku Standard_LRS --kind StorageV2
\n

 

\n

 

\n

Replace <YourStorageAccountName>, <YourResourceGroup>, and <YourLocation> with your desired storage account name, resource group, and Azure region.

\n

 

\n
    \n
  1. Configure access control for your Blob Storage account, ensuring your app can read and write data using a service principal, for example you can assign a role like Storage Blob Data Contributor:
  2. \n
\n

 

\n

 

\n
az role assignment create --assignee <YourAppServicePrincipalId> --role \"Storage Blob Data Contributor\" --scope /subscriptions/<YourSubscriptionId>/resourceGroups/<YourResourceGroup>/providers/Microsoft.Storage/storageAccounts/<YourStorageAccountName>
\n

 

\n

 

\n

Replace <YourAppServicePrincipalId>, <YourSubscriptionId>, <YourResourceGroup>, and <YourStorageAccountName> with your service principal ID, subscription ID, resource group, and storage account name.

\n

 

\n
    \n
  1. Use SAS tokens or managed identities to secure access to the Blob Storage account. To generate a SAS token for the storage account using Azure CLI:
  2. \n
\n

 

\n

 

\n
az storage account generate-sas --account-name <YourStorageAccountName> --permissions rwl --expiry <YYYY-MM-DD> --resource-types sco --services b --https-only
\n

 

\n

 

\n

If your app is using a managed identity, the role assignment from previous step, it will automatically secure the storage account access, and no additional steps are required.

\n

Replace <YourStorageAccountName> and <YYYY-MM-DD> with your storage account name and desired expiry date.

\n

 

\n

Implementing Client-Side Encryption for Python App

\n

 

\n

Encryption and Uploading in Python:

\n

 

\n
    \n
  1. Install the required libraries in bash command
  2. \n
\n

  

\n

 

\n

 

\n
 pip install cryptography azure-storage-blob
\n

 

\n

 

\n

 

\n
    \n
  1. Encryption and Uploading in Python, for example:
  2. \n
\n

  

\n

 

\n

 

\n
\n   from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes\n\n   from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC\n\n   from cryptography.hazmat.backends import default_backend\n\n   from cryptography.hazmat.primitives import hashes\n\n   from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient\n\n   import os\n\n   from base64 import urlsafe_b64encode\n\n\n\n   # Configuration\n\n   account_url = \"https://<your_storage_account>.blob.core.windows.net\"\n\n   container_name = \"my-container\"\n\n   blob_name = \"my-encrypted-blob\"\n\n   key = b'secret_key'  # Replace with your secret key\n\n\n\n   # Function to encrypt data\n\n   def encrypt_data(data, key):\n\n       backend = default_backend()\n\n       salt = os.urandom(16)\n\n       kdf = PBKDF2HMAC(\n\n           algorithm=hashes.SHA256(),\n\n           length=32,\n\n           salt=salt,\n\n           iterations=100000,\n\n           backend=backend\n\n       )\n\n       key = kdf.derive(key)\n\n       iv = os.urandom(16)\n\n       cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=backend)\n\n       encryptor = cipher.encryptor()\n\n       encrypted_data = encryptor.update(data) + encryptor.finalize()\n\n       return salt + iv + encrypted_data\n\n\n\n   # Sample data to encrypt\n\n   data = b\"Sensitive data that needs encryption\"\n\n\n\n   # Encrypt the data\n\n   encrypted_data = encrypt_data(data, key)\n\n\n\n   # Upload encrypted data to Azure Blob Storage\n\n   blob_service_client = BlobServiceClient(account_url=account_url)\n\n   blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)\n\n   blob_client.upload_blob(encrypted_data, overwrite=True)\n\n\n\n   print(\"Data encrypted and uploaded successfully.\")\n\n \n\n
\n

 

\n

 

\n

Downloading and Decrypting in Python:

\n

 

\n

Decrypt and Download Data:

\n

  

\n

 

\n

 

\n
\n   from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes\n\n   from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC\n\n   from cryptography.hazmat.backends import default_backend\n\n   from cryptography.hazmat.primitives import hashes\n\n   from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient\n\n   import os\n\n\n\n   # Configuration\n\n   account_url = \"https://<your_storage_account>.blob.core.windows.net\"\n\n   container_name = \"my-container\"\n\n   blob_name = \"my-encrypted-blob\"\n\n   key = b'secret_key'  # Replace with your secret key\n\n\n\n   # Function to decrypt data\n\n   def decrypt_data(encrypted_data, key):\n\n       backend = default_backend()\n\n       salt = encrypted_data[:16]\n\n       iv = encrypted_data[16:32]\n\n       ciphertext = encrypted_data[32:]\n\n       kdf = PBKDF2HMAC(\n\n           algorithm=hashes.SHA256(),\n\n           length=32,\n\n           salt=salt,\n\n           iterations=100000,\n\n           backend=backend\n\n       )\n\n       key = kdf.derive(key)\n\n       cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=backend)\n\n       decryptor = cipher.decryptor()\n\n       decrypted_data = decryptor.update(ciphertext) + decryptor.finalize()\n\n       return decrypted_data\n\n   # Download encrypted data from Azure Blob Storage\n\n   blob_service_client = BlobServiceClient(account_url=account_url)\n\n   blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)\n\n   encrypted_data = blob_client.download_blob().readall()\n\n\n   # Decrypt the data\n\n   decrypted_data = decrypt_data(encrypted_data, key)\n\n   print(f\"Decrypted data: {decrypted_data.decode('utf-8')}\")\n\n  
\n

 

\n

 

\n

 

\n

Implementing Client-Side Encryption for .NET Core Blazor App using C#

\n

 

\n

Encryption and uploading in C#:

\n

 

\n

 

\n
    \n
  1. Irrespective of IDE you are using, Install the required NuGet packages:
  2. \n
\n

  

\n

 

\n

 

\n
dotnet add package Azure.Storage.Blobs\ndotnet add package System.Security.Cryptography.Algorithms
\n

 

\n

 

\n

 

\n
    \n
  1. Encryption and Uploading code example:
  2. \n
\n

 

\n

 

\n

 

\n
   using System;\n   using System.IO;\n   using System.Security.Cryptography;\n   using Azure.Storage.Blobs;\n   using Azure.Storage.Blobs.Models;\n\n\n   // Configuration\n   string accountUrl = \"https://<your_storage_account>.blob.core.windows.net\";\n   string containerName = \"my-container\";\n   string blobName = \"my-encrypted-blob\";\n   byte[] key = Convert.FromBase64String(\"your_base64_secret_key\"); // Replace with your Base64 encoded secret key\n\n\n   // Function to encrypt data\n   byte[] EncryptData(byte[] data, byte[] key)\n   {\n       using var aes = Aes.Create();\n       aes.Key = key;\n       aes.GenerateIV();\n       using var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);\n       using var ms = new MemoryStream();\n       ms.Write(aes.IV, 0, aes.IV.Length);\n       using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))\n       {\n           cs.Write(data, 0, data.Length);\n       }\n       return ms.ToArray();\n\n   }\n\n   // Sample data to encrypt\n   byte[] data = System.Text.Encoding.UTF8.GetBytes(\"Sensitive data that needs encryption\");\n\n\n   // Encrypt the data\n   byte[] encryptedData = EncryptData(data, key);\n\n   // Upload encrypted data to Azure Blob Storage\n   BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(accountUrl));\n   BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);\n   BlobClient blobClient = containerClient.GetBlobClient(blobName);\n   using (var ms = new MemoryStream(encryptedData))\n   {\n       blobClient.Upload(ms, new BlobHttpHeaders { ContentType = \"application/octet-stream\" }, true);\n\n   }\n\n   Console.WriteLine(\"Data encrypted and uploaded successfully.\");\n\n\n\n
\n

 

\n

 

\n

Downloading and Decrypting Example in C#:

\n

 

\n

Decrypt and Download Data:

\n

 

\n

 

\n
   using System;\n   using System.IO;\n   using System.Security.Cryptography;\n   using Azure.Storage.Blobs;\n\n   // Configuration\n   string accountUrl = \"https://<your_storage_account>.blob.core.windows.net\";\n   string containerName = \"my-container\";\n   string blobName = \"my-encrypted-blob\";\n   byte[] key = Convert.FromBase64String(\"your_base64_secret_key\"); // Replace with your Base64 encoded secret key\n\n\n   // Function to decrypt data\n   byte[] DecryptData(byte[] encryptedData, byte[] key)\n   {\n       using var aes = Aes.Create();\n       using var ms = new MemoryStream(encryptedData);\n       byte[] iv = new byte[aes.BlockSize / 8];\n       ms.Read(iv, 0, iv.Length);\n       using var decryptor = aes.CreateDecryptor(key, iv);\n       using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);\n       using var result = new MemoryStream();\n       cs.CopyTo(result);\n       return result.ToArray();\n   }\n\n\n   // Download encrypted data from Azure Blob Storage\n   BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(accountUrl));\n   BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);\n   BlobClient blobClient = containerClient.GetBlobClient(blobName);\n\n\n   using var ms = new MemoryStream();\n   blobClient.DownloadTo(ms);\n   byte[] encryptedData = ms.ToArray();\n\n   // Decrypt the data\n   byte[] decryptedData = DecryptData(encryptedData, key);\n   Console.WriteLine($\"Decrypted data: {System.Text.Encoding.UTF8.GetString(decryptedData)}\");
\n

 

\n

 

\n

 

\n

Replace <your_storage_account> and your_base64_secret_key with your actual storage account URL and Base64 encoded secret key, respectively.

\n

 

\n

Implementing Client-Side Encryption for Java application

\n

 

\n

Encryption and Uploading in Java:

\n

 

\n
    \n
  1. You will first need to add the required dependencies to your pom.xml:
  2. \n
\n

 

\n

 

\n
   <dependency>\n       <groupId>com.azure</groupId>\n       <artifactId>azure-storage-blob</artifactId>\n       <version>12.16.0</version>\n   </dependency>\n   <dependency>\n       <groupId>org.bouncycastle</groupId>\n       <artifactId>bcprov-jdk15on</artifactId>\n       <version>1.70</version>\n   </dependency>\n
\n

 

\n

 

\n

  

\n

 

\n
    \n
  1. Encryption and uploading similar code sample:
  2. \n
\n

 

\n

 

\n
   import com.azure.storage.blob.BlobClient;\n   import com.azure.storage.blob.BlobContainerClient;\n   import com.azure.storage.blob.BlobServiceClient;\n   import com.azure.storage.blob.BlobServiceClientBuilder;\n   import org.bouncycastle.jce.provider.BouncyCastleProvider;\n   import javax.crypto.Cipher;\n   import javax.crypto.KeyGenerator;\n   import javax.crypto.SecretKey;\n   import javax.crypto.spec.IvParameterSpec;\n   import java.nio.file.Files;\n   import java.nio.file.Path;\n   import java.nio.file.Paths;\n   import java.security.Security;\n   import java.util.Base64;\n\n   public class EncryptAndUpload {\n       static {\n           Security.addProvider(new BouncyCastleProvider());\n       }\n\n       private static final String ACCOUNT_URL = \"https://<your_storage_account>.blob.core.windows.net\";\n       private static final String CONTAINER_NAME = \"my-container\";\n       private static final String BLOB_NAME = \"my-encrypted-blob\";\n       private static final String SECRET_KEY = \"your_base64_secret_key\"; // Replace with your Base64 encoded secret key\n\n       public static void main(String[] args) throws Exception {\n    \n       // Sample data to encrypt\n           byte[] data = \"Sensitive data that needs encryption\".getBytes();\n\n           // Encrypt the data\n           byte[] encryptedData = encryptData(data);\n\n           // Upload encrypted data to Azure Blob Storage\n           BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(ACCOUNT_URL).buildClient();\n           BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(CONTAINER_NAME);\n           BlobClient blobClient = containerClient.getBlobClient(BLOB_NAME);\n\n           Path tempFile = Files.createTempFile(\"encrypted\", \".dat\");\n           Files.write(tempFile, encryptedData);\n           blobClient.uploadFromFile(tempFile.toString(), true);\n           System.out.println(\"Data encrypted and uploaded successfully.\");\n       }\n\n       private static byte[] encryptData(byte[] data) throws Exception {\n           SecretKey key = getKeyFromBase64(SECRET_KEY);\n           Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\", \"BC\");\n           byte[] iv = new byte[cipher.getBlockSize()];\n           new java.security.SecureRandom().nextBytes(iv);\n           cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));\n           byte[] encryptedData = cipher.doFinal(data);\n           byte[] ivAndEncryptedData = new byte[iv.length + encryptedData.length];\n           System.arraycopy(iv, 0, ivAndEncryptedData, 0, iv.length);\n           System.arraycopy(encryptedData, 0, ivAndEncryptedData, iv.length, encryptedData.length);\n           return ivAndEncryptedData;\n       }\n\n       private static SecretKey getKeyFromBase64(String base64Key) {\n           byte[] decodedKey = Base64.getDecoder().decode(base64Key);\n           return new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, \"AES\");\n       }\n   }
\n

 

\n

 

\n

  

\n

Downloading and Decrypting in Java

\n

 

\n

Decrypt and Download Data:

\n

  

\n

 

\n

 

\n
   import com.azure.storage.blob.BlobClient;\n   import com.azure.storage.blob.BlobContainerClient;\n   import com.azure.storage.blob.BlobServiceClient;\n   import com.azure.storage.blob.BlobServiceClientBuilder;\n   import org.bouncycastle.jce.provider.BouncyCastleProvider;\n   import javax.crypto.Cipher;\n   import javax.crypto.SecretKey;\n   import javax.crypto.spec.IvParameterSpec;\n   import java.nio.file.Files;\n   import java.nio.file.Path;\n   import java.nio.file.Paths;\n   import java.security.Security;\n   import java.util.Base64;\n\n   public class DownloadAndDecrypt {\n       static {\n           Security.addProvider(new BouncyCastleProvider());\n       }\n\n       private static final String ACCOUNT_URL = \"https://<your_storage_account>.blob.core.windows.net\";\n       private static final String CONTAINER_NAME = \"my-container\";\n       private static final String BLOB_NAME = \"my-encrypted-blob\";\n       private static final String SECRET_KEY = \"your_base64_secret_key\"; // Replace with your Base64 encoded secret key\n\n       public static void main(String[] args) throws Exception {\n    \n       // Download encrypted data from Azure Blob Storage\n           BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(ACCOUNT_URL).buildClient();\n           BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(CONTAINER_NAME);\n           BlobClient blobClient = containerClient.getBlobClient(BLOB_NAME);\n\n\n           Path tempFile = Files.createTempFile(\"encrypted\", \".dat\");\n           blobClient.downloadToFile(tempFile.toString());\n           byte[] encryptedData = Files.readAllBytes(tempFile);\n\n\n           // Decrypt the data\n           byte[] decryptedData = decryptData(encryptedData);\n\n           System.out.println(\"Decrypted data: \" + new String(decryptedData));\n       }\n\n\n       private static byte[] decryptData(byte[] encryptedData) throws Exception {\n           SecretKey key = getKeyFromBase64(SECRET_KEY);\n           Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\", \"BC\");\n           byte[] iv = new byte[cipher.getBlockSize()];\n           System.arraycopy(encryptedData, 0, iv, 0, iv.length);\n           byte[] encryptedContent = new byte[encryptedData.length - iv.length];\n           System.arraycopy(encryptedData, iv.length, encryptedContent, 0, encryptedContent.length);\n           cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));\n           return cipher.doFinal(encryptedContent);\n       }\n\n       private static SecretKey getKeyFromBase64(String base64Key) {\n           byte[] decodedKey = Base64.getDecoder().decode(base64Key);\n           return new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, \"AES\");\n      }\n   }
\n

 

\n

 

\n

 

\n

Likewise, you will replace <your_storage_account> and your_base64_secret_key with your actual storage account URL and Base64 encoded secret key, respectively and ensure you are using the latest Azure SDK.

\n

 

\n

Managing Encryption Keys

\n\n

 

\n

Verifying and Testing

\n\n

 

\n

Outcome

\n\n

 

\n

Conclusion

\n

We have seen so far, how Client-Side Encryption (CSE) provides an enhanced level of security by ensuring that data is encrypted before it leaves the client’s environment, and how we can implement this with three different programing languages for Azure App using Azure Key Vault, Azure Blob and create Azure Storage Account. This method aligns well with regulatory requirements such as GDPR, PCI-DSS, and FERPA, offering greater control over sensitive information and protecting it from breaches and unauthorized access. By implementing CSE, can better meet security and regulatory requirements, ensuring the highest level of data protection. It helps provides enhanced protection against data breaches. While it involves more complexity than Client-Side Key Encryption (CSKE), it offers significant security benefits that are crucial for handling sensitive data. CSE enhances security by allowing you to manage encryption keys independently. It's a valuable practice for safeguarding sensitive information in cloud solutions!

\n

 

\n

 

\n

CAUTION:

\n
    \n
  1. The code might need to upgrade depend on the time you are performing these tasks.
  2. \n
  3. If you are using Azure file share as a Persistent Volume Claim (PVC) in Azure Kubernetes Service (AKS) with POD workload identity to retrieve secret you will use the Secrets Store CSI Driver to natively retrieve secret contents from Azure Key Vault. This driver securely provides secrets to the requesting pods: https://learn.microsoft.com/en-us/azure/aks/developer-best-practices-pod-security
  4. \n
\n

 

\n

References

\n

For more information on Azure's support for Client-Side Encryption and to access further resources on Azure's official documentation and security best practices.

\n\n

 

\n

 

","body@stringLength":"43274","rawBody":"

\n

 

\n

Introduction

\n

Think of Client-Side Encryption (CSE) as a strategy that has proven to be most effective in augmenting data security and modern precursor to traditional approaches. In addition to providing a stronger security posture, this strategy is also in compliance with major data regulations like GDPR, FERPA and PCI-DSS. In this article, we’ll explore how CSE can provide superior protection for your data, particularly if an authentication and authorization account is compromised. We’ll also address common questions about Microsoft's stance on CSE and explain why CSE might not be as widely discussed as Client-Side Key Encryption (CSKE). By understanding these concepts, you can better meet security and regulatory requirements and ensure that your data remains protected.

\n

 

\n

Use Case

\n

As shown below in the Figure 1: An example of Use Case Architecture. Protecting and managing financial and health sensitive data for clients is subject to stringent regulatory requirements such as GDPR and PCI-DSS and also the followings:

\n\n

Practical Use Case scenario for CSE

\n\n

Figure 1: An example of Use Case Architecture

\n

Understanding the concept

\n

As it shown in the Figure 2: The Concept, the processes involved in client-side encryption (CSE) are the followings:

\n\n

 

\n

Figure 2: The Concept

\n

 

\n

In a nutshell:

\n\n

 

\n

Understanding Client-Side Encryption (CSE) and Client-Side Key Encryption (CSKE).

\n

Client-Side Encryption (CSE) provides a significant security advantage by allowing organizations to maintain complete control over their data and encryption keys. This method not only enhances data security but also supports compliance with regulatory requirements, offering peace of mind in the ever-evolving landscape of cloud computing. CSE encrypts data before it is sent to any service like Azure and this means that the data is encrypted on the client’s side, and Azure never sees the encryption keys. Even if someone gains access to your Azure account, they cannot read your data without the keys. In contrast, Client-Side Key Encryption (CSKE) focuses on securing the encryption keys themselves. The client manages and controls these keys, ensuring they are not accessible to the cloud service. This adds an extra layer of protection by keeping the keys out of the service provider’s reach. Both approaches enhance security but address different aspects of data protection.

\n

 

\n

Why We Need Client-Side Encryption (CSE)

\n

Enhanced Security

\n\n

Regulatory Compliance

\n\n

Data Ownership and Control

\n\n

 

\n

Why Not Client-Side Key Encryption (CSKE) Alone

\n

Reliance on Cloud Service

\n\n

 

\n

Key Exposure Risks

\n\n

 

\n

Azure's Position on CSE

\n

Most of Azure’s documentation and services tend to emphasize Server-Side Encryption (SSE) due to its simplicity and ease of use for most scenarios. SSE allows Azure to provide a straightforward security model that works out-of-the-box for users, without requiring significant changes to their applications or processes.

\n

However, Azure does support CSE through various SDKs and client libraries. For instance, Azure Storage SDKs for different programming languages provide support for encrypting data on the client side before uploading it to Azure Blob Storage.

\n

 

\n

Step-by-Step Solution for Implementing Client-Side Encryption (CSE) for Python, .NET Core Blazor App using C#, and Java Apps.

\n

 

\n

Requirements (Refers to Figure 1: An example of Use Case Architecture) 

\n

Cloud provider (Microsoft Azure)

\n\n

 

\n

Your organization responsibility to implement CSE

\n\n

 

\n

To implement Client-Side Encryption (CSE) in your application using Azure Key Vault and Azure Blob Storage.

\n

 

\n

Azure Key Vault

\n

You will set up Azure Key Vault to store and manage encryption keys securely.

\n

 

\n
    \n
  1. You will need to create a Key Vault as this will help to create RSA, EC, or AES keys in Managed HSM, then use them for encryption-at-rest in Azure Storage, Azure SQL, and more. So, in the Azure portal, create a new Key Vault resource as shown below.
  2. \n
\n
 
\n

Figure 3: Creating Azure Key Vault

\n

 You will Navigate to Administrators by click on it, then Click Add principal, then select your apps as seen on the screen below:

\n

Figure 4: Add Administrator for Azure Key Vault Managed HSM

\n

 

\n

 

\n

This will Set the permissions for the Key Vault, ensuring that your application can access the keys. So, review to create and Click on Create button as shown below:

\n

Figure 5: Review and create Azure Key Vault

\n

 

\n

It might take a couple of minutes for your Azure Key Vault creation to deploy successfully.

\n

 

\n

Figure 6: Azure Key Vault deployment is complete

\n

 

\n

 

\n

 

\n
    \n
  1. Create or Import Encryption Keys:
  2. \n
\n

Next is to create a new key or import an existing key in the Key Vault. This key will be used for encrypting and decrypting data. But prior to this you must have updated your network settings. So, let’s use Azure CLI:

\n\n

 

\n

 

\naz keyvault key create --vault-name <YourKeyVaultName> --name <YourKeyName> --protection software\n

 

\n

 

\n\n

 

\n

 

\naz keyvault key import --vault-name <YourKeyVaultName> --name <YourKeyName> --pem-file <YourPemFilePath>\n

 

\n

 

\n

 

\n

Replace <YourKeyVaultName>, <YourKeyName>, and <YourPemFilePath> with your Key Vault name, the key name, and the path to your key file.

\n

 

\n

 

\n
    \n
  1. Assign Access Policies to allow your app to perform operations like `wrapKey` and `unwrapKey` with the key using bash in Azure CLI:
  2. \n
\n

 

\n

 

\naz keyvault set-policy --name <YourKeyVaultName> --spn <YourAppServicePrincipalId> --key-permissions get list wrapKey unwrapKey\n

 

\n

 

\n

Replace <YourKeyVaultName> with your Key Vault name and <YourAppServicePrincipalId> with the service principal ID of your Blazor app.

\n

 

\n

Azure Blob Storage

\n

You will configure Azure Blob Storage to store the encrypted data. You will be using Azure Storage client libraries for Blob Storage or Queue Storage if that’s your choice with the same steps.

\n

 

\n
    \n
  1. In the Azure portal, create a new Blob Storage account (Quickstart blobs)  or using Azure CLI as shown below:
  2. \n
\n

 

\n

 

\naz storage account create --name <YourStorageAccountName> --resource-group <YourResourceGroup> --location <YourLocation> --sku Standard_LRS --kind StorageV2\n

 

\n

 

\n

Replace <YourStorageAccountName>, <YourResourceGroup>, and <YourLocation> with your desired storage account name, resource group, and Azure region.

\n

 

\n
    \n
  1. Configure access control for your Blob Storage account, ensuring your app can read and write data using a service principal, for example you can assign a role like Storage Blob Data Contributor:
  2. \n
\n

 

\n

 

\naz role assignment create --assignee <YourAppServicePrincipalId> --role \"Storage Blob Data Contributor\" --scope /subscriptions/<YourSubscriptionId>/resourceGroups/<YourResourceGroup>/providers/Microsoft.Storage/storageAccounts/<YourStorageAccountName>\n

 

\n

 

\n

Replace <YourAppServicePrincipalId>, <YourSubscriptionId>, <YourResourceGroup>, and <YourStorageAccountName> with your service principal ID, subscription ID, resource group, and storage account name.

\n

 

\n
    \n
  1. Use SAS tokens or managed identities to secure access to the Blob Storage account. To generate a SAS token for the storage account using Azure CLI:
  2. \n
\n

 

\n

 

\naz storage account generate-sas --account-name <YourStorageAccountName> --permissions rwl --expiry <YYYY-MM-DD> --resource-types sco --services b --https-only\n

 

\n

 

\n

If your app is using a managed identity, the role assignment from previous step, it will automatically secure the storage account access, and no additional steps are required.

\n

Replace <YourStorageAccountName> and <YYYY-MM-DD> with your storage account name and desired expiry date.

\n

 

\n

Implementing Client-Side Encryption for Python App

\n

 

\n

Encryption and Uploading in Python:

\n

 

\n
    \n
  1. Install the required libraries in bash command
  2. \n
\n

  

\n

 

\n

 

\n pip install cryptography azure-storage-blob\n

 

\n

 

\n

 

\n
    \n
  1. Encryption and Uploading in Python, for example:
  2. \n
\n

  

\n

 

\n

 

\n\n from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes\n\n from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC\n\n from cryptography.hazmat.backends import default_backend\n\n from cryptography.hazmat.primitives import hashes\n\n from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient\n\n import os\n\n from base64 import urlsafe_b64encode\n\n\n\n # Configuration\n\n account_url = \"https://<your_storage_account>.blob.core.windows.net\"\n\n container_name = \"my-container\"\n\n blob_name = \"my-encrypted-blob\"\n\n key = b'secret_key' # Replace with your secret key\n\n\n\n # Function to encrypt data\n\n def encrypt_data(data, key):\n\n backend = default_backend()\n\n salt = os.urandom(16)\n\n kdf = PBKDF2HMAC(\n\n algorithm=hashes.SHA256(),\n\n length=32,\n\n salt=salt,\n\n iterations=100000,\n\n backend=backend\n\n )\n\n key = kdf.derive(key)\n\n iv = os.urandom(16)\n\n cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=backend)\n\n encryptor = cipher.encryptor()\n\n encrypted_data = encryptor.update(data) + encryptor.finalize()\n\n return salt + iv + encrypted_data\n\n\n\n # Sample data to encrypt\n\n data = b\"Sensitive data that needs encryption\"\n\n\n\n # Encrypt the data\n\n encrypted_data = encrypt_data(data, key)\n\n\n\n # Upload encrypted data to Azure Blob Storage\n\n blob_service_client = BlobServiceClient(account_url=account_url)\n\n blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)\n\n blob_client.upload_blob(encrypted_data, overwrite=True)\n\n\n\n print(\"Data encrypted and uploaded successfully.\")\n\n \n\n\n

 

\n

 

\n

Downloading and Decrypting in Python:

\n

 

\n

Decrypt and Download Data:

\n

  

\n

 

\n

 

\n\n from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes\n\n from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC\n\n from cryptography.hazmat.backends import default_backend\n\n from cryptography.hazmat.primitives import hashes\n\n from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient\n\n import os\n\n\n\n # Configuration\n\n account_url = \"https://<your_storage_account>.blob.core.windows.net\"\n\n container_name = \"my-container\"\n\n blob_name = \"my-encrypted-blob\"\n\n key = b'secret_key' # Replace with your secret key\n\n\n\n # Function to decrypt data\n\n def decrypt_data(encrypted_data, key):\n\n backend = default_backend()\n\n salt = encrypted_data[:16]\n\n iv = encrypted_data[16:32]\n\n ciphertext = encrypted_data[32:]\n\n kdf = PBKDF2HMAC(\n\n algorithm=hashes.SHA256(),\n\n length=32,\n\n salt=salt,\n\n iterations=100000,\n\n backend=backend\n\n )\n\n key = kdf.derive(key)\n\n cipher = Cipher(algorithms.AES(key), modes.CFB(iv), backend=backend)\n\n decryptor = cipher.decryptor()\n\n decrypted_data = decryptor.update(ciphertext) + decryptor.finalize()\n\n return decrypted_data\n\n # Download encrypted data from Azure Blob Storage\n\n blob_service_client = BlobServiceClient(account_url=account_url)\n\n blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)\n\n encrypted_data = blob_client.download_blob().readall()\n\n\n # Decrypt the data\n\n decrypted_data = decrypt_data(encrypted_data, key)\n\n print(f\"Decrypted data: {decrypted_data.decode('utf-8')}\")\n\n \n

 

\n

 

\n

 

\n

Implementing Client-Side Encryption for .NET Core Blazor App using C#

\n

 

\n

Encryption and uploading in C#:

\n

 

\n

 

\n
    \n
  1. Irrespective of IDE you are using, Install the required NuGet packages:
  2. \n
\n

  

\n

 

\n

 

\ndotnet add package Azure.Storage.Blobs\ndotnet add package System.Security.Cryptography.Algorithms\n

 

\n

 

\n

 

\n
    \n
  1. Encryption and Uploading code example:
  2. \n
\n

 

\n

 

\n

 

\n using System;\n using System.IO;\n using System.Security.Cryptography;\n using Azure.Storage.Blobs;\n using Azure.Storage.Blobs.Models;\n\n\n // Configuration\n string accountUrl = \"https://<your_storage_account>.blob.core.windows.net\";\n string containerName = \"my-container\";\n string blobName = \"my-encrypted-blob\";\n byte[] key = Convert.FromBase64String(\"your_base64_secret_key\"); // Replace with your Base64 encoded secret key\n\n\n // Function to encrypt data\n byte[] EncryptData(byte[] data, byte[] key)\n {\n using var aes = Aes.Create();\n aes.Key = key;\n aes.GenerateIV();\n using var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);\n using var ms = new MemoryStream();\n ms.Write(aes.IV, 0, aes.IV.Length);\n using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))\n {\n cs.Write(data, 0, data.Length);\n }\n return ms.ToArray();\n\n }\n\n // Sample data to encrypt\n byte[] data = System.Text.Encoding.UTF8.GetBytes(\"Sensitive data that needs encryption\");\n\n\n // Encrypt the data\n byte[] encryptedData = EncryptData(data, key);\n\n // Upload encrypted data to Azure Blob Storage\n BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(accountUrl));\n BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);\n BlobClient blobClient = containerClient.GetBlobClient(blobName);\n using (var ms = new MemoryStream(encryptedData))\n {\n blobClient.Upload(ms, new BlobHttpHeaders { ContentType = \"application/octet-stream\" }, true);\n\n }\n\n Console.WriteLine(\"Data encrypted and uploaded successfully.\");\n\n\n\n\n

 

\n

 

\n

Downloading and Decrypting Example in C#:

\n

 

\n

Decrypt and Download Data:

\n

 

\n

 

\n using System;\n using System.IO;\n using System.Security.Cryptography;\n using Azure.Storage.Blobs;\n\n // Configuration\n string accountUrl = \"https://<your_storage_account>.blob.core.windows.net\";\n string containerName = \"my-container\";\n string blobName = \"my-encrypted-blob\";\n byte[] key = Convert.FromBase64String(\"your_base64_secret_key\"); // Replace with your Base64 encoded secret key\n\n\n // Function to decrypt data\n byte[] DecryptData(byte[] encryptedData, byte[] key)\n {\n using var aes = Aes.Create();\n using var ms = new MemoryStream(encryptedData);\n byte[] iv = new byte[aes.BlockSize / 8];\n ms.Read(iv, 0, iv.Length);\n using var decryptor = aes.CreateDecryptor(key, iv);\n using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);\n using var result = new MemoryStream();\n cs.CopyTo(result);\n return result.ToArray();\n }\n\n\n // Download encrypted data from Azure Blob Storage\n BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(accountUrl));\n BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);\n BlobClient blobClient = containerClient.GetBlobClient(blobName);\n\n\n using var ms = new MemoryStream();\n blobClient.DownloadTo(ms);\n byte[] encryptedData = ms.ToArray();\n\n // Decrypt the data\n byte[] decryptedData = DecryptData(encryptedData, key);\n Console.WriteLine($\"Decrypted data: {System.Text.Encoding.UTF8.GetString(decryptedData)}\");\n

 

\n

 

\n

 

\n

Replace <your_storage_account> and your_base64_secret_key with your actual storage account URL and Base64 encoded secret key, respectively.

\n

 

\n

Implementing Client-Side Encryption for Java application

\n

 

\n

Encryption and Uploading in Java:

\n

 

\n
    \n
  1. You will first need to add the required dependencies to your pom.xml:
  2. \n
\n

 

\n

 

\n <dependency>\n <groupId>com.azure</groupId>\n <artifactId>azure-storage-blob</artifactId>\n <version>12.16.0</version>\n </dependency>\n <dependency>\n <groupId>org.bouncycastle</groupId>\n <artifactId>bcprov-jdk15on</artifactId>\n <version>1.70</version>\n </dependency>\n\n

 

\n

 

\n

  

\n

 

\n
    \n
  1. Encryption and uploading similar code sample:
  2. \n
\n

 

\n

 

\n import com.azure.storage.blob.BlobClient;\n import com.azure.storage.blob.BlobContainerClient;\n import com.azure.storage.blob.BlobServiceClient;\n import com.azure.storage.blob.BlobServiceClientBuilder;\n import org.bouncycastle.jce.provider.BouncyCastleProvider;\n import javax.crypto.Cipher;\n import javax.crypto.KeyGenerator;\n import javax.crypto.SecretKey;\n import javax.crypto.spec.IvParameterSpec;\n import java.nio.file.Files;\n import java.nio.file.Path;\n import java.nio.file.Paths;\n import java.security.Security;\n import java.util.Base64;\n\n public class EncryptAndUpload {\n static {\n Security.addProvider(new BouncyCastleProvider());\n }\n\n private static final String ACCOUNT_URL = \"https://<your_storage_account>.blob.core.windows.net\";\n private static final String CONTAINER_NAME = \"my-container\";\n private static final String BLOB_NAME = \"my-encrypted-blob\";\n private static final String SECRET_KEY = \"your_base64_secret_key\"; // Replace with your Base64 encoded secret key\n\n public static void main(String[] args) throws Exception {\n \n // Sample data to encrypt\n byte[] data = \"Sensitive data that needs encryption\".getBytes();\n\n // Encrypt the data\n byte[] encryptedData = encryptData(data);\n\n // Upload encrypted data to Azure Blob Storage\n BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(ACCOUNT_URL).buildClient();\n BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(CONTAINER_NAME);\n BlobClient blobClient = containerClient.getBlobClient(BLOB_NAME);\n\n Path tempFile = Files.createTempFile(\"encrypted\", \".dat\");\n Files.write(tempFile, encryptedData);\n blobClient.uploadFromFile(tempFile.toString(), true);\n System.out.println(\"Data encrypted and uploaded successfully.\");\n }\n\n private static byte[] encryptData(byte[] data) throws Exception {\n SecretKey key = getKeyFromBase64(SECRET_KEY);\n Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\", \"BC\");\n byte[] iv = new byte[cipher.getBlockSize()];\n new java.security.SecureRandom().nextBytes(iv);\n cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));\n byte[] encryptedData = cipher.doFinal(data);\n byte[] ivAndEncryptedData = new byte[iv.length + encryptedData.length];\n System.arraycopy(iv, 0, ivAndEncryptedData, 0, iv.length);\n System.arraycopy(encryptedData, 0, ivAndEncryptedData, iv.length, encryptedData.length);\n return ivAndEncryptedData;\n }\n\n private static SecretKey getKeyFromBase64(String base64Key) {\n byte[] decodedKey = Base64.getDecoder().decode(base64Key);\n return new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, \"AES\");\n }\n }\n

 

\n

 

\n

  

\n

Downloading and Decrypting in Java

\n

 

\n

Decrypt and Download Data:

\n

  

\n

 

\n

 

\n import com.azure.storage.blob.BlobClient;\n import com.azure.storage.blob.BlobContainerClient;\n import com.azure.storage.blob.BlobServiceClient;\n import com.azure.storage.blob.BlobServiceClientBuilder;\n import org.bouncycastle.jce.provider.BouncyCastleProvider;\n import javax.crypto.Cipher;\n import javax.crypto.SecretKey;\n import javax.crypto.spec.IvParameterSpec;\n import java.nio.file.Files;\n import java.nio.file.Path;\n import java.nio.file.Paths;\n import java.security.Security;\n import java.util.Base64;\n\n public class DownloadAndDecrypt {\n static {\n Security.addProvider(new BouncyCastleProvider());\n }\n\n private static final String ACCOUNT_URL = \"https://<your_storage_account>.blob.core.windows.net\";\n private static final String CONTAINER_NAME = \"my-container\";\n private static final String BLOB_NAME = \"my-encrypted-blob\";\n private static final String SECRET_KEY = \"your_base64_secret_key\"; // Replace with your Base64 encoded secret key\n\n public static void main(String[] args) throws Exception {\n \n // Download encrypted data from Azure Blob Storage\n BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(ACCOUNT_URL).buildClient();\n BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(CONTAINER_NAME);\n BlobClient blobClient = containerClient.getBlobClient(BLOB_NAME);\n\n\n Path tempFile = Files.createTempFile(\"encrypted\", \".dat\");\n blobClient.downloadToFile(tempFile.toString());\n byte[] encryptedData = Files.readAllBytes(tempFile);\n\n\n // Decrypt the data\n byte[] decryptedData = decryptData(encryptedData);\n\n System.out.println(\"Decrypted data: \" + new String(decryptedData));\n }\n\n\n private static byte[] decryptData(byte[] encryptedData) throws Exception {\n SecretKey key = getKeyFromBase64(SECRET_KEY);\n Cipher cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\", \"BC\");\n byte[] iv = new byte[cipher.getBlockSize()];\n System.arraycopy(encryptedData, 0, iv, 0, iv.length);\n byte[] encryptedContent = new byte[encryptedData.length - iv.length];\n System.arraycopy(encryptedData, iv.length, encryptedContent, 0, encryptedContent.length);\n cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));\n return cipher.doFinal(encryptedContent);\n }\n\n private static SecretKey getKeyFromBase64(String base64Key) {\n byte[] decodedKey = Base64.getDecoder().decode(base64Key);\n return new javax.crypto.spec.SecretKeySpec(decodedKey, 0, decodedKey.length, \"AES\");\n }\n }\n

 

\n

 

\n

 

\n

Likewise, you will replace <your_storage_account> and your_base64_secret_key with your actual storage account URL and Base64 encoded secret key, respectively and ensure you are using the latest Azure SDK.

\n

 

\n

Managing Encryption Keys

\n\n

 

\n

Verifying and Testing

\n\n

 

\n

Outcome

\n\n

 

\n

Conclusion

\n

We have seen so far, how Client-Side Encryption (CSE) provides an enhanced level of security by ensuring that data is encrypted before it leaves the client’s environment, and how we can implement this with three different programing languages for Azure App using Azure Key Vault, Azure Blob and create Azure Storage Account. This method aligns well with regulatory requirements such as GDPR, PCI-DSS, and FERPA, offering greater control over sensitive information and protecting it from breaches and unauthorized access. By implementing CSE, can better meet security and regulatory requirements, ensuring the highest level of data protection. It helps provides enhanced protection against data breaches. While it involves more complexity than Client-Side Key Encryption (CSKE), it offers significant security benefits that are crucial for handling sensitive data. CSE enhances security by allowing you to manage encryption keys independently. It's a valuable practice for safeguarding sensitive information in cloud solutions!

\n

 

\n

 

\n

CAUTION:

\n
    \n
  1. The code might need to upgrade depend on the time you are performing these tasks.
  2. \n
  3. If you are using Azure file share as a Persistent Volume Claim (PVC) in Azure Kubernetes Service (AKS) with POD workload identity to retrieve secret you will use the Secrets Store CSI Driver to natively retrieve secret contents from Azure Key Vault. This driver securely provides secrets to the requesting pods: https://learn.microsoft.com/en-us/azure/aks/developer-best-practices-pod-security
  4. \n
\n

 

\n

References

\n

For more information on Azure's support for Client-Side Encryption and to access further resources on Azure's official documentation and security best practices.

\n\n

 

\n

 

","kudosSumWeight":0,"postTime":"2024-09-05T00:00:00.029-07:00","images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1MWkxNkZGODg3QzU4QTRCNkU0?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI0MWkxOUM0MTM4MzRCN0U0RUNF?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI0M2k1NEI0OUU2NzRDNzdGOEFG?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1NmlBNjQ0QzIzMTlCM0U1NTFC?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1N2k2NjRGMzNGNDMwODIwQTZD?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDY","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1OWk0NDc3NEI1NjIzRDdGNDFD?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDc","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI2MGkyNTE3OEE1MDU4RkEyNEU0?revision=5\"}"}}],"totalCount":7,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":true,"endCursor":"MjUuM3wyLjF8b3wxMHxfTlZffDEw","hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:app service","text":"app service","time":"2017-08-17T07:52:29.819-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDI","node":{"__typename":"Tag","id":"tag:azure","text":"azure","time":"2016-09-06T09:34:09.130-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDM","node":{"__typename":"Tag","id":"tag:azure deployment environments","text":"azure deployment environments","time":"2024-08-07T04:55:06.159-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDQ","node":{"__typename":"Tag","id":"tag:best practices","text":"best practices","time":"2016-08-17T10:05:07.769-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDU","node":{"__typename":"Tag","id":"tag:developer","text":"developer","time":"2016-07-01T11:00:22.155-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDY","node":{"__typename":"Tag","id":"tag:functions","text":"functions","time":"2017-11-02T14:58:04.448-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDc","node":{"__typename":"Tag","id":"tag:java","text":"java","time":"2018-11-16T06:58:14.484-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDg","node":{"__typename":"Tag","id":"tag:python","text":"python","time":"2018-05-02T23:53:46.520-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDk","node":{"__typename":"Tag","id":"tag:software architecture","text":"software architecture","time":"2019-06-13T05:38:40.627-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDEw","node":{"__typename":"Tag","id":"tag:tips and tricks","text":"tips and tricks","time":"2016-08-01T14:39:11.268-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":16,"rawTeaser":"

Enhancing Data Security and Digital Trust in the Cloud by Implementing Client-Side Encryption (CSE) using Azure Apps, Azure Storage and Azure Key Vault. Think of Client-Side Encryption (CSE) as a strategy that has proven to be most effective in augmenting data security and modern precursor to traditional approaches. CSE can provide superior protection for your data, particularly if an authentication and authorization account is compromised.

","introduction":"","coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""},"currentRevision":{"__ref":"Revision:revision:4234937_5"},"latestVersion":{"__typename":"FriendlyVersion","major":"2","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":2695},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":"Enhancing Data Security and Digital Trust in the Cloud using Azure Apps, Azure Storage and Azure Key Vault.","seoDescription":"Think of Client-Side Encryption (CSE) as a strategy that has proven to be most effective in augmenting data security and modern precursor to traditional approaches. CSE can provide superior protection for your data, particularly if an authentication and authorization account is compromised.","placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"blogMessagePolicies":{"__typename":"BlogMessagePolicies","canDoAuthoringActionsOnBlog":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","key":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":5}},"Conversation:conversation:4234937":{"__typename":"Conversation","id":"conversation:4234937","solved":false,"topic":{"__ref":"BlogTopicMessage:message:4234937"},"lastPostingActivityTime":"2024-09-12T00:00:00.027-07:00","lastPostTime":"2024-09-05T00:00:00.029-07:00","unreadReplyCount":0,"isSubscribed":false},"ModerationData:moderation_data:4234937":{"__typename":"ModerationData","id":"moderation_data:4234937","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1MWkxNkZGODg3QzU4QTRCNkU0?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1MWkxNkZGODg3QzU4QTRCNkU0?revision=5","title":"sasina_1-1725321078051.png","associationType":"BODY","width":711,"height":466,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI0MWkxOUM0MTM4MzRCN0U0RUNF?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI0MWkxOUM0MTM4MzRCN0U0RUNF?revision=5","title":"sasina_1-1725318039624.png","associationType":"BODY","width":892,"height":687,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI0M2k1NEI0OUU2NzRDNzdGOEFG?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI0M2k1NEI0OUU2NzRDNzdGOEFG?revision=5","title":"sasina_2-1725318039633.png","associationType":"BODY","width":876,"height":631,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1NmlBNjQ0QzIzMTlCM0U1NTFC?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1NmlBNjQ0QzIzMTlCM0U1NTFC?revision=5","title":"sasina_2-1725321919514.png","associationType":"BODY","width":515,"height":692,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1N2k2NjRGMzNGNDMwODIwQTZD?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1N2k2NjRGMzNGNDMwODIwQTZD?revision=5","title":"sasina_3-1725322239660.png","associationType":"BODY","width":817,"height":358,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1OWk0NDc3NEI1NjIzRDdGNDFD?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI1OWk0NDc3NEI1NjIzRDdGNDFD?revision=5","title":"sasina_0-1725323432636.png","associationType":"BODY","width":797,"height":708,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI2MGkyNTE3OEE1MDU4RkEyNEU0?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MjM0OTM3LTYxNjI2MGkyNTE3OEE1MDU4RkEyNEU0?revision=5","title":"sasina_1-1725323706338.png","associationType":"BODY","width":682,"height":268,"altText":null},"Revision:revision:4234937_5":{"__typename":"Revision","id":"revision:4234937_5","lastEditTime":"2024-09-07T21:58:50.425-07:00"},"CachedAsset:theme:customTheme1-1747123676492":{"__typename":"CachedAsset","id":"theme:customTheme1-1747123676492","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","defaultMessageFontFamily":"var(--lia-bs-font-family-base)","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#1E1E1E","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1745505307000","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/blogs/BlogMessagePage:board:AzureDevCommunityBlog-1747123674709":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/blogs/BlogMessagePage:board:AzureDevCommunityBlog-1747123674709","value":{"id":"BlogMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"blog-article","layout":"ONE_COLUMN","bgColor":null,"showTitle":null,"showDescription":null,"textPosition":null,"textColor":null,"sectionEditLevel":"LOCKED","bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"OneColumnQuiltSection","columnMap":{"main":[{"id":"blogs.widget.blogArticleWidget","className":"lia-blog-container","props":null,"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"}},{"id":"section-1729184836777","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":false,"showDescription":false,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[],"side":[],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1745505307000","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-pages/blogs/BlogMessagePage-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-pages/blogs/BlogMessagePage-1745505307000","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This blog post cannot be found","name":"Blog Message Page","section.blog-article.title":"Blog Post","archivedMessageTitle":"This Content Has Been Archived","section.section-1729184836777.title":"","section.section-1729184836777.description":"","section.CncIde.title":"Blog Post","section.tifEmD.description":"","section.tifEmD.title":""},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1747123608412":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1747123608412","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-microsoft365-copilot-link","params":{"categoryId":"Microsoft365Copilot"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-content_management-link","params":{"categoryId":"Content_Management"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoftintune"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"MicrosoftforNonprofits"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1745505307000","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"QueryVariables:TopicReplyList:message:4234937:5":{"__typename":"QueryVariables","id":"TopicReplyList:message:4234937:5","value":{"id":"message:4234937","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:component:custom.widget.HeroBanner-en-us-1747150703148":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-us-1747150703148","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search.","blogs.sidebar.pagetitle":"Latest Blogs | Microsoft Tech Community","followThisNode":"Follow this node","unfollowThisNode":"Unfollow this node"},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-us-1747150703148":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-us-1747150703148","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n\n.social-share {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n\n.sharing-options {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 43px;\n border-radius: 0px 7px 7px 0px;\n}\n.linkedin-icon {\n border-top-right-radius: 7px;\n}\n.linkedin-icon:hover {\n border-radius: 0;\n}\n.social-share-rss-image {\n border-bottom-right-radius: 7px;\n}\n.social-share-rss-image:hover {\n border-radius: 0;\n}\n\n.social-link-footer {\n position: relative;\n display: block;\n margin: -2px 0;\n transition: all 0.2s ease;\n}\n.social-link-footer:hover .linkedin-icon {\n border-radius: 0;\n}\n.social-link-footer:hover .social-share-rss-image {\n border-radius: 0;\n}\n\n.social-link-footer img {\n width: 40px;\n height: auto;\n transition: filter 0.3s ease;\n}\n\n.social-share-list {\n width: 40px;\n}\n.social-share-rss-image {\n width: 40px;\n}\n\n.share-icon {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n\n.share-icon:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n\n.share-icon:hover .label {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n\n.label {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 10px;\n top: 50%;\n transform: translateY(-50%);\n height: 40px;\n border-radius: 0 6px 6px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 5px 20px 8px;\n margin-left: -1px;\n}\n.linkedin {\n background-color: #0474b4;\n}\n.facebook {\n background-color: #3c5c9c;\n}\n.twitter {\n background-color: white;\n color: black;\n}\n.reddit {\n background-color: #fc4404;\n}\n.mail {\n background-color: #848484;\n}\n.bluesky {\n background-color: white;\n color: black;\n}\n.rss {\n background-color: #ec7b1c;\n}\n#RSS {\n width: 40px;\n height: 40px;\n}\n\n@media (max-width: 991px) {\n .social-share {\n display: none;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_105bp_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_105bp_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_105bp_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_105bp_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_105bp_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n.custom_widget_MicrosoftFooter_social-share_105bp_138 {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n.custom_widget_MicrosoftFooter_sharing-options_105bp_146 {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 2.6875rem;\n border-radius: 0 0.4375rem 0.4375rem 0;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-top-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-bottom-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 {\n position: relative;\n display: block;\n margin: -0.125rem 0;\n transition: all 0.2s ease;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 img {\n width: 2.5rem;\n height: auto;\n transition: filter 0.3s ease;\n}\n.custom_widget_MicrosoftFooter_social-share-list_105bp_188 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195 {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover .custom_widget_MicrosoftFooter_label_105bp_207 {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n.custom_widget_MicrosoftFooter_label_105bp_207 {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 0.625rem;\n top: 50%;\n transform: translateY(-50%);\n height: 2.5rem;\n border-radius: 0 0.375rem 0.375rem 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.25rem 0.3125rem 1.25rem 0.5rem;\n margin-left: -0.0625rem;\n}\n.custom_widget_MicrosoftFooter_linkedin_105bp_156 {\n background-color: #0474b4;\n}\n.custom_widget_MicrosoftFooter_facebook_105bp_237 {\n background-color: #3c5c9c;\n}\n.custom_widget_MicrosoftFooter_twitter_105bp_240 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_reddit_105bp_244 {\n background-color: #fc4404;\n}\n.custom_widget_MicrosoftFooter_mail_105bp_247 {\n background-color: #848484;\n}\n.custom_widget_MicrosoftFooter_bluesky_105bp_250 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_rss_105bp_254 {\n background-color: #ec7b1c;\n}\n#custom_widget_MicrosoftFooter_RSS_105bp_1 {\n width: 2.5rem;\n height: 2.5rem;\n}\n@media (max-width: 991px) {\n .custom_widget_MicrosoftFooter_social-share_105bp_138 {\n display: none;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_105bp_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_105bp_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_105bp_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_105bp_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58","c-list":"custom_widget_MicrosoftFooter_c-list_105bp_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_105bp_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_105bp_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107","social-share":"custom_widget_MicrosoftFooter_social-share_105bp_138","sharing-options":"custom_widget_MicrosoftFooter_sharing-options_105bp_146","linkedin-icon":"custom_widget_MicrosoftFooter_linkedin-icon_105bp_156","social-share-rss-image":"custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162","social-link-footer":"custom_widget_MicrosoftFooter_social-link-footer_105bp_169","social-share-list":"custom_widget_MicrosoftFooter_social-share-list_105bp_188","share-icon":"custom_widget_MicrosoftFooter_share-icon_105bp_195","label":"custom_widget_MicrosoftFooter_label_105bp_207","linkedin":"custom_widget_MicrosoftFooter_linkedin_105bp_156","facebook":"custom_widget_MicrosoftFooter_facebook_105bp_237","twitter":"custom_widget_MicrosoftFooter_twitter_105bp_240","reddit":"custom_widget_MicrosoftFooter_reddit_105bp_244","mail":"custom_widget_MicrosoftFooter_mail_105bp_247","bluesky":"custom_widget_MicrosoftFooter_bluesky_105bp_250","rss":"custom_widget_MicrosoftFooter_rss_105bp_254","RSS":"custom_widget_MicrosoftFooter_RSS_105bp_1"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1745505307000","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1745505307000","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1745505307000","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solution","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1745505307000","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1745505307000","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftforNonprofits":{"__typename":"Category","id":"category:MicrosoftforNonprofits","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Microsoft365Copilot":{"__typename":"Category","id":"category:Microsoft365Copilot","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Content_Management":{"__typename":"Category","id":"category:Content_Management","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoftintune":{"__typename":"Category","id":"category:microsoftintune","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"CachedAsset:text:en_US-components/community/Navbar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1745505307000","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Nonprofit Community","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","Common-content_management-link":"Content Management","microsoft-learn":"Microsoft Learn","s-q-l-server":"Content Management","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Outlook","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","Common-microsoft365-copilot-link":"Microsoft 365 Copilot","outlook":"Microsoft 365 Copilot","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1745505307000","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1745505307000","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1745505307000","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1745505307000","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1745505307000","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCoverImage-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCoverImage-1745505307000","value":{"coverImageTitle":"Cover Image"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeTitle-1745505307000","value":{"nodeTitle":"{nodeTitle, select, community {Community} other {{nodeTitle}}} "},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTimeToRead-1745505307000","value":{"minReadText":"{min} MIN READ"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1745505307000","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1745505307000","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1745505307000","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1745505307000","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1745505307000","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1745505307000","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1745505307000","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1745505307000","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1745505307000","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1745505307000","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1745505307000","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1745505307000","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1745505307000","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1745505307000","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505307000","value":{"loadMore":"Show More"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1745505307000","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeAvatar-1745505307000","value":{"altTitle":"Node avatar for {nodeTitle}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeDescription-1745505307000","value":{"description":"{description}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1745505307000","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false}}}},"page":"/blogs/BlogMessagePage/BlogMessagePage","query":{"boardId":"azuredevcommunityblog","messageSubject":"enhancing-data-security-and-digital-trust-in-the-cloud-using-azure-services-","messageId":"4234937"},"buildId":"YK32GCbhJqbL-HLk4DLXM","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.3.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/blogs/BlogArticleWidget/BlogArticleWidget.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","./components/external/components/ExternalComponent.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx","../shared/client/components/common/Pager/PagerLoadMore/PagerLoadMore.tsx","./components/customComponent/CustomComponentContent/TemplateContent.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=BlogMessagePage&entity.id=board%3Aazuredevcommunityblog&entity.id=message%3A4234937","strategy":"afterInteractive"}]}