In the healthcare industry, data security is paramount, especially with the strict requirements of HIPAA compliance. One critical aspect of data security is ensuring that data at rest is encrypted, protecting it from unauthorized access or breaches.
Exploring the different security levels and the solutions for them at Endatix, we would like to share three of our approaches and convenient ways to implement them using Microsoft Azure. This cloud platform offers a range of encryption solutions to meet the compliance needs, each with its own level of control and security options.
In this article, we’ll explore three practical approaches to encrypting data at rest in Azure: Server-Side Encryption (SSE), Client-Side Encryption (CSE), and Client-Side Encryption with Role-Based Access Control (RBAC). Each approach offers unique benefits, from hands-off encryption management to fine-grained control over who can access sensitive data.
For organizations seeking a straightforward encryption method, Server-Side Encryption (SSE) provides a seamless solution. With SSE, encryption is handled automatically by Azure. This means that data is encrypted and decrypted by the storage provider without requiring extra configuration from the client. SSE is ideal for Minimum Viable Product (MVP) setups or environments where rapid deployment and ease of use are top priorities.
In Azure, SSE is enabled through Transparent Data Encryption (TDE) for SQL Server and automatic encryption for Blob Storage. When TDE is enabled on an Azure SQL Database, the database files and transaction logs are encrypted at rest. For Blob Storage, Azure encrypts all data as soon as it is persisted, ensuring the data is protected.
Once your SQL database is present, open it in Azure Portal. Under the database settings, navigate to Security > Data Encryption. Here, you’ll find an option to enable Transparent Data Encryption. Simply toggle this on, and Azure will handle the rest, securing your data without requiring any additional code or configuration changes.
Turning on TDE from Azure Portal is quite straightforward.
SSE meets HIPAA’s encryption requirements, although it provides less control over data access compared to other methods. This approach works well when ease of use and compliance are sufficient, but for scenarios requiring a more restricted access, a more robust encryption approach may be necessary.
For clients who need complete control over their data’s encryption, Client-Side Encryption (CSE) is the answer. CSE ensures that data is encrypted on the client’s side before it is stored in Azure, meaning that only those with the encryption keys can decrypt and access the data. This approach is particularly advantageous for sensitive data since it provides end-to-end encryption and eliminates the risk of unauthorized access at the server level.
In Azure SQL, CSE can be achieved with Always Encrypted, a feature that lets you designate specific columns in a SQL database for encryption. Encryption and decryption are managed by Entity Framework (EF) with keys stored securely in Azure Key Vault. For files or blobs in Azure Blob Storage client-side encryption is achieved in a similar way, encrypting and decrypting using the Azure Key Vault before uploading and after downloading the data.
1. Create an Azure Key Vault and Encrypt Sensitive Data: This includes several actions, which are well described in Tutorial: Getting started with Always Encrypted. Following it, you will have your sensitive data encrypted with a key stored in Azure Key Vault. Use the Azure role-based access control (RBAC) described in the Prerequisites section.
2. Set Up App Registration: To allow programmatic access to Key Vault, create an app registration in Entra ID. In Azure Portal go to Entra ID, Manage > App Registrations and create an app using New registration. The app will be seen in the list as below.
For access from the code, you need an app registration.
Open the app to see its client and tenant IDs, which will be needed later.
Client ID and Tenant ID are displayed on the overview screen.
Finally, an app client secret is needed to get programmatic access. It is created from Manage > Certificates & secrets when the app registration is open. Create a client secret and do not forget to copy it before closing the screen as its value would not be displayed anymore!
After Client secret creation its value must be copied and stored securely.
3. Provide Vault Access to the Registered App: Back to the screen with the newly created vault, go to Access control (IAM) and choose Add / Add role assignment. On the Role tab assign a role with the minimum privileges needed to use the key (details at Azure built-in roles). On the Members tab, choose User, group, or service principal, then from Select members choose the created in the app registration step. The registered app should appear in the list on the Role assignments tab.
The registered app needs to have an assigned role from the key vault.
4. Application Code Changes: Firstly, refer Microsoft.Data.SqlClient
, Azure.Identity
and Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
in the project responsible for the connection to the SQL Server. The connection string to the server should also have Column Encryption Setting=Enabled;
added to it.
Following is an example code responsible for accessing the key stored in Azure Key Vault. For AZURE_TENANT_ID
, AZURE_CLIENT_ID
and AZURE_CLIENT_SECRET
use the corresponding values obtained in the previous steps.
using Azure.Identity;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
namespace Endatix.Persistence.SqlServer.Security;
public class SqlEncryptionInitializer
{
private const string AZURE_TENANT_ID = "";
private const string AZURE_CLIENT_ID = "";
private const string AZURE_CLIENT_SECRET = "";
private static bool _initialized;
private static readonly object _lock = new();
public void Initialize()
{
if (_initialized)
{
return;
}
lock (_lock)
{
if (_initialized)
{
return;
}
var clientCredential = new ClientSecretCredential(AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET);
var akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(clientCredential);
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
new(capacity: 1)
{
{ SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvProvider }
};
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
_initialized = true;
}
}
}
The class SqlEncryptionInitializer
must be registered in the application’s services and initialized as part of the DbContext
registration. Following is an example code snippet:
endatixApp.Services.AddSingleton<SqlEncryptionInitializer>();
endatixApp.Services.AddDbContext<AppDbContext>((serviceProvider, options) =>
{
var encryptionInitializer = serviceProvider.GetRequiredService<SqlEncryptionInitializer>();
encryptionInitializer.Initialize();
options.UseSqlServer(connectionString, b => b.MigrationsAssembly(migrationsAssembly));
});
Having these code changes provides the DB context with the ability to use the encryption key in order to encrypt/decrypt the columns set with Always Encrypted. To understand better how they can fit in setting up a DB context, you can check how Endatix database persistence is implemented at GitHub Endatix repository.
5. Enable Azure Blob Storage Client-Side Encryption: For files or blobs, Azure Blob Storage supports client-side encryption using the Azure Key Vault. For more details you can check Client-side encryption for blobs and Tutorial: Encrypt and decrypt blobs using Azure Key Vault.
By encrypting data on the client side, CSE with Key Vault provides HIPAA-compliant encryption that protects data throughout its lifecycle. This approach is especially useful for clients who require stringent control over encryption keys and sensitive data access.
Client-Side Encryption (CSE) with Role-Based Access Control (RBAC) enables precise access management by encrypting data client-side and controlling decryption permissions through specific roles. This setup is ideal for ensuring that only authorized application users can access sensitive data, aligning with HIPAA’s stringent access control requirements.
Using Azure, the data is encrypted client-side using Always Encrypted for SQL Server and client encryption for Azure Blob Storage in the same way as described in Client-Side Encryption section above. In addition, the client application allows only users with the appropriate roles to access encrypted data, having complete control over sensitive data access.
1. Register Users with Different Roles: Begin by implementing user registration that assigns each user to a specific role within your application. This can be achieved by either Azure Entra ID or a custom role system.
2. Define Decryption Roles: Clearly specify which roles should have or lack access to decrypted data. For example, sensitive data might only be accessible to “Admin” roles, while other roles may only view masked data.
3. Add Role-Based Decryption Checks in Logic: Modify your data access layer (e.g., Entity Framework or API middleware) to check a user’s role before granting access to decrypted data.
4. Adjust Key Vault Access Based on Role: Change your logic for accessing Azure Key Vault to only retrieve decryption keys when a user’s role allows it. If the role lacks decryption privileges, access to the decryption key should be denied, and the application should return masked data instead or deny write actions in case they need data encryption.
Combining CSE with RBAC in Azure provides HIPAA-compliant encryption, ensuring that only designated roles can decrypt data, reinforcing strict data access controls.
Azure provides multiple paths to encrypt data at rest, each offering a unique balance of security and control. From the simplicity of Server-Side Encryption for MVPs to the comprehensive control of Client-Side Encryption with RBAC, Azure’s encryption solutions can support a variety of compliance and security requirements. By choosing the approach that best aligns with your organization’s needs, you can ensure your data remains HIPAA-compliant and secure, giving both your clients and your team peace of mind.
We offer expert advice on architecture, provide training for SurveyJS and the Endatix backend, and assist with development and implementation of your solution. Feel free to contact us—we're passionate about software and always happy to chat!