Skip to content

Sensitive Data Logging

Data logging services are intended to publish the logs to external/third-party services i.e.:Datadog. In sensitive data logging, the sensitive personal identifiable information (PII) information in the logs are masked.

The following sections will brief the mechanism of sensitive logging.

Settings

The following configurations need to be added in order to configure sensitive logging.

SensitiveLoggingPolicy.HashSensitiveFieldsEnabled : Hash the fields in the request and response that are identified as sensitive.

SensitiveLoggingPolicy.HashSPParametersEnabled : Hash the input parameters that are identified as sensitive in the stored procedures.

SensitiveLoggingPolicy.HashDictionaryKeysEnabled : Hash the value of input parameters that contain dictionaries in the stored procedures.

Hashing sensitive data

Request and response payloads may contain sensitive PII properties. The request and response flows are passed through a policy that identifies the sensitive PIIs tagged as SensitiveData in the respective commands, queries, and DTOs. This can be achieved using the SensitiveLoggingPolicy.HashSensitiveFieldsEnabled property.

Stored procedure param filtering

In the appsettings.json file, the identified PIIs are listed within the SensitiveLoggingPolicy.SensitiveSPParams. If SensitiveLoggingPolicy.HashSPParametersEnabled is enabled, filter out the SensitiveSPParams from the input paramters of the stored procedure.

The following example shows a section of the sensitive parameters defined for the payment repo service:

"SensitiveSPParams": [
            "requestorToken",
            "responderToken",
            "senderToken",
            "recipientToken",
            "tokenIdentifier",
            "externalEntityIdentifier",
            "fullName",
            "firstName",
            "lastName",
            "businessName",
            "accountNumber"
]

Hashing sensitive data in dictionaries

Dictionary hashing is a sub-section of the stored procedure param filtering section. This can be achieved by enabling the following properties:

    - SensitiveLoggingPolicy.HashSPParametersEnabled
    - SensitiveLoggingPolicy.HashDictionaryKeysEnabled

A dictionary is an object that contains a list of key-value pairs in the format of { "key": "value" }.

In the input parameters list of a stored procedure, the value of a parameter could contain a dictionary or a collection of dictionaries. These values need to be hashed. If the above two settings are enabled, the value of a key of a dictionary is hashed.

Example behaviors

The following sections describe how sensitive data filtering will behave in different contexts, including:

  • Requests and Responses
  • Events
  • JX Calls

Example: Request and Response Logging

This example shows how sensitive data filtering is applied to the logs during "/zelle/api/zelle/payment-profiles" request. As shown in the following curl, it includes a Personally Identifiable Information (PII) field, TokenIdentifier.

curl --location 'https://<server>/zelle/api/zelle/payment-profiles' \
--header 'BSV-TokenIdentifier: jhones@gmail.com' \
--header 'BSV-TokenType: Email'
Note: In this curl example and the log examples below, unnecessary parts have been removed for simplicity.

The request will be logged with the tokenIdentifier field hashed, as shown below, when HashSensitiveFieldsEnabled is enabled.

    "Request": {
        "ExternalPaymentProfileId": null,
        "TokenIdentifier": "2F400DCE83A1B1D60C75B38EC56854338D5638018E521491F6B60DFE8D83428E",
        "TokenType": "Email",
        "CustomerId": null,
        "ExternalCustomerId": null,
        "Status": null,
        "FinancialAccountNumber": null,
        "FinancialAccountType": null,
        "RoutingNumber": null,
        "CoreCustomerId": null,
        "Offset": null,
        "Count": null,
        "$type": "GetPaymentProfileQuery"
    }
During the processing of the payment-profiles request, the stored procedure "spGetPaymentProfiles" will be called. When HashSPParametersEnabled is enabled, the sensitive field tokenIdentifier will be hashed in the related logs, as follows.

    "dbDetails": {
        "Server": "<DB-Server>",
        "Instance": "Boyar_Zelle",
        "Statement": "[dbo].[spGetPaymentProfiles]",
        "Operation": "Execute",
        "User": "",
        "Parameters": {
            "externalPaymentProfileId": {
                "$type": "DBNull"
            },
            "tokenIdentifier": "2F400DCE83A1B1D60C75B38EC56854338D5638018E521491F6B60DFE8D83428E",
            "tokenTypeId": 1,
            "externalCustomerId": {
                "$type": "DBNull"
            },
            "statusId": {
                "$type": "DBNull"
            },
            "offset": 0,
            "Count": 100
        },
        "$type": "DatabaseDetail"
    }

When HashSensitiveFieldsEnabled is enabled, the response will be logged with all the sensitive fields hashed. In addition to the tokenIdentifier, other Personally Identifiable Information (PII) fields, such as AccountNumber and the FirstName and LastName fields from the PersonalProfile, will also be hashed during response logging as shown below.

    "Response": {
        "Result": {
            "Items": [
                {
                    "Id": 194567000,
                    "CustomerId": 164233000,
                    "CreatedAt": "2024-10-11T11:00:30.5200000",
                    "ModifiedAt": null,
                    "Status": "Active",
                    "ExternalPaymentProfileId": "br_prof_lNzGWjIQ2E",
                    "ExternalCustomerId": "br_cust_fg7SeUJTLI",
                    "IgnoreNameMatch": true,
                    "AcceptanceMode": "Auto",
                    "CanReceiveExpeditedPayments": true,
                    "TCHRoutingNumber": "",
                    "PhotoId": "",
                    "PhotoLocatorUrl": "",
                    "Token": {
                        "Identifier": "2F400DCE83A1B1D60C75B38EC56854338D5638018E521491F6B60DFE8D83428E",
                        "Status": "Active",
                        "Type": "Email",
                        "CreatedAt": "2024-10-11T10:42:17.6000000",
                        "ModifiedAt": "2024-10-11T11:00:29.9400000",
                        "$type": "Token"
                    },
                    "FinancialAccount": {
                        "AccountNumber": "43F5736CD62AFA2F98F0332B0DA24487542EF337255F7610E0B8A5512881435A",
                        "AccountType": "Checking",
                        "RoutingNumber": "111025466",
                        "$type": "FinancialAccount"
                    },
                    "PersonalProfile": {
                        "FirstName": "4F69905A2FDF3232F20E16F046E3C64563DC6DEE02A6659C9D67BA0D2845C6A8",
                        "LastName": "46AF9696F97A2A5C00B4E3839EE0A4189F61E755E39FDCFD0F671546FF366637",
                        "$type": "PersonalProfile"
                    },
                    "$type": "PaymentProfileDto"
                }   
            ],
            "Paging": {
                "Results": 1,
                "Total": 1,
                "NextOffset": "0",
                "$type": "PagedResultStatus"
            },
            "$type": "PagedResult`1"
        },
        "Errors": [],
        "$type": "BaseResponse`1"
    }

Example: Event Logging

When a "/paymentrepo/API/Zelle/payments" request is received, it triggers a "PaymentActivityCreatedDomainEvent" to pass the required information, such as limits, to other systems.

During the logging of the "PaymentActivityCreatedDomainEvent", the sensitive field BankAccount will be hashed as follows if HashSensitiveFieldsEnabled is enabled.

    "Key": {
        "InitiatedAt": "2024-10-10T05:35:36.5112632Z",
        "OccurredAt": "2024-10-10T05:35:36.5112816Z",
        "Direction": "Inbound",
        "Amount": 1,
        "PayCenterMemberFIId": null,
        "SenderCustomerId": "cus_pay_8930",
        "RecipientCustomerId": "cus_pay_8358",
        "ExternalPaymentId": "ZP_343734662",
        "Status": "Created",
        "PayCenterNetworkName": "Zelle",
        "PayCenterNetworkId": 1,
        "BankAccount": "81EA96707FB0643653507E2ECC9905DEEEB7793C8C8DF87FC89681D5AF356AF7",
        "RoutingNumber": "011103097",
        "PayCenterNetworkProductId": 1020,
        "PaymentMode": "Expedited",
        "EventId": "c8e6eea0-a428-4b3f-bd12-9ea0a06a20d9",
        "OccurredOn": "2024-10-10T05:35:36.6509162Z",
        "$type": "PaymentStatusChanged"
    }

Example: Sensitive Data Masking in JX Calls

When a "/mono/api/notifier/alerts/recipient-alerts" request is received to the system, it sends the notification with the help of external notification service. This communication occurs via JX calls. Below is a log of a JX AddAlert call, where the sensitive fields (AccountLastFour, FirstName, and TransactionAmount) will be hashed if HashSensitiveFieldsEnabled is enabled.

    <?xml version="1.0" encoding="utf-8"?>
    <NotSndAdd>
        <jXchangeHdr>
            <AuditUsrId>AuditUserID</AuditUsrId>
            <AuditWsId>AuditWorkStationId</AuditWsId>
            <InstRtId>111025466</InstRtId>
            <BusCorrelId>&lt;string&gt;</BusCorrelId>
            <WorkflowCorrelId>W001</WorkflowCorrelId>
        </jXchangeHdr>
        <AlrtDataInfoArray>
            <AlrtDataInfoRec>
                <Name>AccountLastFour</Name>
                <Val>506DED66EB8BE8051C3BFCC0BA961FCD194D8299BBDF76EDAFF0C52CBA80BCD8</Val>
            </AlrtDataInfoRec>
            <AlrtDataInfoRec>
                <Name>FirstName</Name>
                <Val>F76B1BD34C016EF9CD41944F1E306B793F1929024822F7E6CEF1A33BC700C74E</Val>
            </AlrtDataInfoRec>
            <AlrtDataInfoRec>
                <Name>TransactionAmount</Name>
                <Val>6B86B273FF34FCE19D6B804EFF5A3F5747ADA4EAA22F1D49C01E52DDB7875B4B</Val>
            </AlrtDataInfoRec>
        </AlrtDataInfoArray>
    </NotSndAdd>