How to Build Custom Email Redaction in Salesforce: A Step-by-Step Guide

We’ve all been there. A customer sends an email containing a credit card number, a password, or sensitive medical information. The email routes perfectly into Salesforce, attaches to a record as a fresh Activity, and suddenly your org is storing sensitive customer data inside Tasks, Cases, or EmailMessage records.

Once sensitive information enters Salesforce activity logs, it may become accessible to users with record visibility, replicated in backups, and potentially exposed to compliance risks under regulations like GDPR, HIPAA, or PCI-DSS.

While there are several paid AppExchange solutions available, you can also build a fully native redaction engine using Apex Email Services and Regular Expressions (Regex).

In this blog, we’ll walk through building a custom email redaction solution in Salesforce step-by-step.

The Core Architecture: How Custom Redaction Works

To intercept and clean data before it gets permanently logged into the Salesforce database, you must bypass standard Email-to-Case or Einstein Activity Capture for these specific workflows. Instead, you will route incoming emails through a custom Inbound Email Service.

The native execution flow looks like this:

  • Email Ingestion: An email is sent to a generated Salesforce routing address.
  • Apex Interception: The InboundEmailHandler intercepts the text in-memory before any record is created.
  • Regex Pattern Matching: The code scans the email body and subject line for defined patterns (like credit cards or SSNs).
  • Data Masking/Substitution: The matching text is replaced with a compliant placeholder.
  • Clean Insert: The sanitized text is saved to a Task, EmailMessage, or Case record.

Implementation Guide

Step 1: Create Custom Metadata Type for Regex Patterns

Navigate to:

Setup → Custom Metadata Types

Create a new Custom Metadata Type with:

Label: Redaction Pattern

Plural Label: Redaction Patterns

Object Name: Redaction_Pattern

Redaction_Pattern

Step 2: Create Metadata Fields

Field 1 — Regex Expression

Field Type: Long Text Area

API Name: Regex_Expression__c

Field 2 — Replacement Text

Field Type: Text

API Name generated in our org: Replacement__c

Replacement__c

Step 3: Add Redaction Patterns

Create a metadata record with:

Label: Credit Card

Regex Expression: \b(?:\d[ -]*?){13,16}\b

Replacement Text: [REDACTED CREDIT CARD]

Redaction Patterns

Step 4: Create Apex Redaction Utility Class

Code:

                           
                           
                              
                              public class EmailRedactionUtility {

   public static String redactText(String inputText) {

      if(String.isBlank(inputText)) {
            return inputText;
      }

      String sanitizedText = inputText;

         List patterns = [
            SELECT Regex_Expression__c,
                  Replacement__c
            FROM Redaction_Pattern__mdt
      ];

      for(Redaction_Pattern__mdt pattern : patterns) {

            try {

               System.Pattern p =
                     System.Pattern.compile(
                         pattern.Regex_Expression__c
                  );

               System.Matcher m =
                     p.matcher(sanitizedText);

               sanitizedText =
                  m.replaceAll(
                         pattern.Replacement__c
                  );

            } catch(Exception e) {

               System.debug(
                  'Regex Error: ' +
                  e.getMessage()
               );
            }
      }

      return sanitizedText;
   }
 }

                           
                        

Redaction Utility Class

Step 5: Create Inbound Email Handler

Code:

                           
                           
                              
                               global class SecureEmailActivityHandler
 implements Messaging.InboundEmailHandler {

   global Messaging.InboundEmailResult handleInboundEmail(
      Messaging.InboundEmail email,
      Messaging.InboundEnvelope envelope
   ) {

      Messaging.InboundEmailResult result =
            new Messaging.InboundEmailResult();

      try {

            String cleanBody =
                 EmailRedactionUtility.redactText(
                  email.plainTextBody
               );

            Task t = new Task();

            t.Subject = 'REDACTED EMAIL';

            t.Description = 'Body: ' + cleanBody;

            t.Status = 'Not Started';

            t.Priority = 'Normal';

            t.ActivityDate = Date.today();

            insert t;

            result.success = true;

      } catch(Exception e) {

            result.success = false;

            result.message =
               e.getMessage();
      }

      return result;
   }
 }

                           

                        

Step 6: Configure Salesforce Email Service

Navigate to:

Setup → Email Services

Create:
Email Service Name: SecureActivityLogger Apex Class: SecureEmailActivityHandler

Secure Email Activity Handler

Step 7: Create Email Address

Create a new email address:

Email Address Name: SecureLogger

Local Part: secureactivitylogger

Salesforce generates a routing email like:secureactivitylogger@xyz.apex.salesforce.com

Create Email Address

Step 8: Test the Redaction Engine

Send:

Subject: Card Test

Body:

My card is 4111-1111-1111-1111

Expected Output:

Body: My card is [REDACTED CREDIT CARD]

Redaction Engine

Best Practices

  • Optimize regex patterns for governor limits
  • Test regex carefully to avoid false positives
  • Process both plainTextBody and htmlBody if required
  • Use descriptive replacement values like [REDACTED CREDIT CARD]

Summary

By combining Apex Email Services, Custom Metadata Types, and Regex-based pattern matching, Salesforce developers can build a fully native email redaction engine that prevents sensitive customer information from being permanently stored inside Salesforce activity records.

If you're interested in exploring more Salesforce solutions, visit our Sales Cloud page.

For any queries please reach out to support@astreait.com