Sensitive PII Information Detection in Email Sends using Azure AI, .NET and Twilio SendGrid

February 05, 2025
Written by
Eman Hassan
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by

Sensitive PII Information Detection in Email Sends using Azure AI, .NET and Twilio SendGrid

Introduction

Accidentally sharing sensitive data in automated or manual emails can lead to data leaks. In this post, you’ll learn how to implement PII detection using Azure AI and .NET, then automatically mask confidential information before sending emails via Twilio SendGrid.

Prerequisites

In order to be successful in this tutorial, you will need the following:

Building the app

The expected flow of the application is: when an email send is triggered, the app passes it to a PII detection service to identify and mask any sensitive data. The sanitized email is then sent to SendGrid to complete the sending process.

Setup Azure Text Analytics Resource

Log in to the Azure Portal then click on Create a resource as shown below:

Create Azure resource

Search for “language” then click on Create for a Language service.

Create a language service

Then select Custom text classification, Custom named entity recognition, Custom sentiment analysis & Custom Text Analytics for health. Finally, click Continue to create your resource as shown below.

Azure portal screen for selecting additional Language Service features, with custom features highlighted.

Select your Azure subscription and region you want to deploy your service. Add a name for the resource, then choose the free pricing plan, and the storage of type Standard ZRS as shown below.

Screenshot of Azure setup prompt for custom text analytics with a highlighted storage account type dropdown.

Then review the AI policies and check the acceptance checkbox. Click on Review + Create. Wait for the deployment to finish, which may take a few seconds. When the deployment is complete, click on Go to resource group then select the created language service. Click on the left navigation’s Resource Management > Keys and Endpoint and observe the keys and endpoint as you will need them later in the application.

Screenshot of Azure AI Services Key Management interface with options to regenerate keys.

Create the .NET application

Open Visual Studio Code and select a folder to save your application. Run the following commands in the terminal to create a .NET console application.

dotnet new console -n SensitivePiiEmailApp
cd SensitivePiiEmailApp

Install Required NuGet Packages

Next, run the following commands in the terminal to install SendGrid and Azure.AI.TextAnalysis.

dotnet add package Azure.AI.TextAnalytics
dotnet add package SendGrid

Setup the application configuration keys

You’ll need to create a new SendGrid API Key with restricted access. On the Restricted Access tab, be sure your API Key is set to allow Email Sending access. Give your API key a name, and click Create + View. Keep this key somewhere safe as you will need it in the subsequent steps, and SendGrid will not show it again.

In the app, create a new file called AppConfig.cs and add the language service’s endpoint and key, the SendGrid API key and sender email and name in the code below.

public static class AppConfig
{
    // Replace with your actual Azure Cognitive Services Key and Endpoint
    public const string AzureCognitiveServicesEndpoint = "https://<YOUR-TEXTANALYTICS-ENDPOINT>.cognitiveservices.azure.com/";
    public const string AzureCognitiveServicesKey = "<YOUR-TEXTANALYTICS-KEY>";
    // Replace with your actual SendGrid Key
    public const string SendGridApiKey = "<YOUR-SENDGRID-API-KEY>";
    // Sender email and name
    public const string SenderEmail = "sender@example.com";
    public const string SenderName = "Sender Demo";
}
Typically, you store your keys in a secure way (like Azure Key Vault, user-secrets, or environment variables). For demo purposes, we will store them as constants in the code, but this is not recommended for production. For more information, refer to this article on C# environment configuration.

Create the PII detector service

Create a new file called PiiDetector.cs. Then add the following code to use Azure.AI.TextAnalysis to detect and redact sensitive data before sending the text to the email send service.

using Azure;
using Azure.AI.TextAnalytics;
public class PiiDetector
{
    private readonly TextAnalyticsClient _client;
    public PiiDetector()
    {
        var credentials = new AzureKeyCredential(AppConfig.AzureCognitiveServicesKey);
        _client = new TextAnalyticsClient(new Uri(AppConfig.AzureCognitiveServicesEndpoint), credentials);
    }
    public (bool piiFound, string redactedText) DetectAndRedactPII(string text)
    {
        var options = new RecognizePiiEntitiesOptions
        {
            DomainFilter = PiiEntityDomain.ProtectedHealthInformation
        };
        // Recognize PII in the text
        var response = _client.RecognizePiiEntities(text, "en", options);
        // Return the redacted text (PII replaced with '*')
        // and a flag indicating whether PII was found or not
        var redactedText = response.Value.RedactedText;
        bool piiFound = response.Value.Count > 0;
        return (piiFound, redactedText);
    }
}

Create the email service

Create a new file called EmailService.cs and add the following code.

using SendGrid;
using SendGrid.Helpers.Mail;
public class EmailService
{
    private readonly SendGridClient _client;
    public EmailService()
    {
        _client = new SendGridClient(AppConfig.SendGridApiKey);
    }
    public async Task<bool> SendEmailAsync(string toEmail, string toName, string subject, string bodyContent)
    {
        var from = new EmailAddress(AppConfig.SenderEmail, AppConfig.SenderName);
        var to = new EmailAddress(toEmail, toName);
        var msg = new SendGridMessage
        {
            From = from,
            Subject = subject,
            PlainTextContent = bodyContent,
            HtmlContent = $"<p>{bodyContent}</p>"
        };
        msg.AddTo(to);
        // Optionally configure additional properties
        // For example: msg.SetClickTracking(false, false);
        var response = await _client.SendEmailAsync(msg).ConfigureAwait(false);
        // Return true if the message was successfully queued for delivery (2xx status)
        return response.IsSuccessStatusCode;
    }
}

Configure the console

Open program.cs and replace it with the following code. This code will enable the application flow of entering the email data, then trigger PII detection, and, finally, send the email.

// Initialize services
var piiDetector = new PiiDetector();
var emailService = new EmailService();
// Sample email content that might contain PII
Console.WriteLine("Enter the email body (sample: My SSN is 123-45-6789):");
string emailBody = Console.ReadLine();
// Detect PII
var (piiFound, redactedText) = piiDetector.DetectAndRedactPII(emailBody);
if (piiFound)
{
    Console.WriteLine("Sensitive PII detected in the email body.");
    // Decide what to do:
    // 1) Block sending
    // 2) Send masked version
    // For demonstration, let's choose to send the redacted text:
    Console.WriteLine("Sending redacted content...");
    // Replace the original email body with the redacted text
    emailBody = redactedText;
}
else
{
    Console.WriteLine("No PII detected, sending the original content...");
}
// Send the email
Console.Write("Enter recipient email: ");
string recipientEmail = Console.ReadLine();
Console.Write("Enter recipient name: ");
string recipientName = Console.ReadLine();
bool result = await emailService.SendEmailAsync(recipientEmail, recipientName, 
    "Sensitive PII Detection Demo", emailBody);
if (result)
{
    Console.WriteLine("Email sent successfully!");
}
else
{
    Console.WriteLine("Failed to send the email.");
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();

Running the app

To run the console application you can write the following command in the terminal in VS Code

dotnet run

It will ask you in the console to enter the email text, recipient’s email and name. Make sure to enter example (fake!) sensitive data in the email text to be able to test the redaction of the sensitive data as shown below.

Running the app

Then check the recipient’s email. You will see the email text sent with redacted data if any PII information was detected.

Redacted email
If no PII data was entered in the email text, the text will be sent as it is with no redaction.
If you no longer plan to use the demo resource groups you created in Azure, remember to delete them to avoid incurring unnecessary costs.

Extending your Azure Application

By proactively detecting and handling PII, you significantly reduce the risk of accidentally leaking sensitive information, maintaining compliance and user trust. You can extend this application to be used for messages, files and any shared resources to detect any data leaks. You can also extend the applications to APIs or automated job runs.

Eman Hassan, a dedicated software engineer and a technical author, prioritizes innovation, cutting-edge technologies, leadership, and mentorship. She finds joy in both learning and sharing expertise with the community. Explore more courses, code labs and tutorials here https://app.pluralsight.com/profile/author/eman-m