Cloud Data Loss Prevention (Cloud DLP) is now a part of Sensitive Data Protection. The API name remains the same: Cloud Data Loss Prevention API (DLP API). For information about the services that make up Sensitive Data Protection, see Sensitive Data Protection overview.
Stay organized with collections
Save and categorize content based on your preferences.
Sensitive Data Protection can detect, classify, and
de-identify sensitive data within structured data.
When de-identifying content as a table, the structure and columns provide
Sensitive Data Protection with additional clues that may enable it to provide
better results for some use cases. For example, you can scan a single column for
a certain data type instead of the entire table structure.
This topic provides examples of how to configure de-identification of sensitive
data within structured text. De-identification is enabled through record
transformations. These
transformations are applied to values within tabular text data that are
identified as a specific infoType, or to an entire column of tabular data.
This topic also provides examples of tabular data transformations using the
cryptographic hash method. The cryptographic transformation methods are unique
because of their requirement of a cryptographic key.
The JSON given in the following examples can be inserted into any
de-identification request inside the
"deidentifyConfig"
(DeidentifyConfig)
attribute. Click the "APIs Explorer example" link to try out the example JSON in
APIs
Explorer.
Transform a column without inspection
To transform a specific column in which the content is already known, you
can skip inspection and specify a transformation directly. The example
following the table buckets the "HAPPINESS SCORE" column
into increments of 10.
using System;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
public class DeidentifyUsingTableBucketing
{
public static Table DeidentifyData(
string projectId,
Table tableToInspect = null)
{
// Instantiate dlp client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
if (tableToInspect == null)
{
var row1 = new Value[]
{
new Value { StringValue = "101" },
new Value { StringValue = "Charles Dickens" },
new Value { StringValue = "95" }
};
var row2 = new Value[]
{
new Value { StringValue = "22" },
new Value { StringValue = "Jane Austin" },
new Value { StringValue = "21" }
};
var row3 = new Value[]
{
new Value { StringValue = "55" },
new Value { StringValue = "Mark Twain" },
new Value { StringValue = "75" }
};
tableToInspect = new Table
{
Headers =
{
new FieldId { Name = "AGE" },
new FieldId { Name = "PATIENT" },
new FieldId { Name = "HAPPINESS SCORE" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } },
new Table.Types.Row { Values = { row3 } }
}
};
}
// Construct the table content item.
var contentItem = new ContentItem { Table = tableToInspect };
// Specify how the content should be de-identified.
var fixedSizeBucketingConfig = new FixedSizeBucketingConfig
{
BucketSize = 10,
LowerBound = new Value { IntegerValue = 0 },
UpperBound = new Value { IntegerValue = 100 },
};
// Specify the fields to be encrypted.
var fields = new FieldId[] { new FieldId { Name = "HAPPINESS SCORE" } };
// Associate the encryption with the specified field.
var fieldTransformation = new FieldTransformation
{
PrimitiveTransformation = new PrimitiveTransformation
{
FixedSizeBucketingConfig = fixedSizeBucketingConfig
},
Fields = { fields }
};
// Construct the deidentify config.
var deidentifyConfig = new DeidentifyConfig
{
RecordTransformations = new RecordTransformations
{
FieldTransformations = { fieldTransformation }
}
};
// Construct the request.
var request = new DeidentifyContentRequest
{
ParentAsLocationName = new LocationName(projectId, "global"),
DeidentifyConfig = deidentifyConfig,
Item = contentItem,
};
// Call the API.
var response = dlp.DeidentifyContent(request);
// Inspect the response.
Console.WriteLine(response.Item.Table);
return response.Item.Table;
}
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.FieldTransformation;
import com.google.privacy.dlp.v2.FixedSizeBucketingConfig;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.Table.Row;
import com.google.privacy.dlp.v2.Value;
import java.io.IOException;
public class DeIdentifyTableBucketing {
public static void main(String[] args) throws IOException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "your-project-id";
Table tableToDeIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("AGE").build())
.addHeaders(FieldId.newBuilder().setName("PATIENT").build())
.addHeaders(FieldId.newBuilder().setName("HAPPINESS SCORE").build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("101").build())
.addValues(Value.newBuilder().setStringValue("Charles Dickens").build())
.addValues(Value.newBuilder().setStringValue("95").build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("22").build())
.addValues(Value.newBuilder().setStringValue("Jane Austen").build())
.addValues(Value.newBuilder().setStringValue("21").build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("55").build())
.addValues(Value.newBuilder().setStringValue("Mark Twain").build())
.addValues(Value.newBuilder().setStringValue("75").build())
.build())
.build();
deIdentifyTableBucketing(projectId, tableToDeIdentify);
}
public static Table deIdentifyTableBucketing(String projectId, Table tableToDeIdentify)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to de-identify.
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToDeIdentify).build();
// Specify how the content should be de-identified.
FixedSizeBucketingConfig fixedSizeBucketingConfig =
FixedSizeBucketingConfig.newBuilder()
.setBucketSize(10)
.setLowerBound(Value.newBuilder().setIntegerValue(0).build())
.setUpperBound(Value.newBuilder().setIntegerValue(100).build())
.build();
PrimitiveTransformation primitiveTransformation =
PrimitiveTransformation.newBuilder()
.setFixedSizeBucketingConfig(fixedSizeBucketingConfig)
.build();
// Specify field to be encrypted.
FieldId fieldId = FieldId.newBuilder().setName("HAPPINESS SCORE").build();
// Associate the encryption with the specified field.
FieldTransformation fieldTransformation =
FieldTransformation.newBuilder()
.setPrimitiveTransformation(primitiveTransformation)
.addFields(fieldId)
.build();
RecordTransformations transformations =
RecordTransformations.newBuilder().addFieldTransformations(fieldTransformation).build();
DeidentifyConfig deidentifyConfig =
DeidentifyConfig.newBuilder().setRecordTransformations(transformations).build();
// Combine configurations into a request for the service.
DeidentifyContentRequest request =
DeidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setDeidentifyConfig(deidentifyConfig)
.build();
// Send the request and receive response from the service.
DeidentifyContentResponse response = dlp.deidentifyContent(request);
// Print the results.
System.out.println("Table after de-identification: " + response.getItem().getTable());
return response.getItem().getTable();
}
}
}
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\FieldTransformation;
use Google\Cloud\Dlp\V2\FixedSizeBucketingConfig;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\Value;
/**
* De-identify data using table bucketing
* Transform a column without inspection. To transform a column in which the content is
* already known, you can skip inspection and specify a transformation directly.
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to deidentify
* @param string $outputCsvFile The oupt file path to save deidentify content
*
*/
function deidentify_table_bucketing(
// TODO(developer): Replace sample parameters before running the code.
string $callingProjectId,
string $inputCsvFile = './test/data/table2.csv',
string $outputCsvFile = './test/data/deidentify_table_bucketing_output.csv'
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
// Read a CSV file
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify what content you want the service to de-identify.
$contentItem = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify how the content should be de-identified.
$fixedSizeBucketingConfig = (new FixedSizeBucketingConfig())
->setBucketSize(10)
->setLowerBound((new Value())
->setIntegerValue(10))
->setUpperBound((new Value())
->setIntegerValue(100));
$primitiveTransformation = (new PrimitiveTransformation())
->setFixedSizeBucketingConfig($fixedSizeBucketingConfig);
// Specify the field to to apply bucketing transform on
$fieldId = (new FieldId())
->setName('HAPPINESS_SCORE');
// Associate the encryption with the specified field.
$fieldTransformation = (new FieldTransformation())
->setPrimitiveTransformation($primitiveTransformation)
->setFields([$fieldId]);
$recordTransformations = (new RecordTransformations())
->setFieldTransformations([$fieldTransformation]);
// Create the deidentification configuration object
$deidentifyConfig = (new DeidentifyConfig())
->setRecordTransformations($recordTransformations);
$parent = "projects/$callingProjectId/locations/global";
// Run request
$deidentifyContentRequest = (new DeidentifyContentRequest())
->setParent($parent)
->setDeidentifyConfig($deidentifyConfig)
->setItem($contentItem);
$response = $dlp->deidentifyContent($deidentifyContentRequest);
// Print results
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf($outputCsvFile);
}
from typing import Dict, List, Union
import google.cloud.dlp
from google.cloud.dlp_v2 import types
def deidentify_table_bucketing(
project: str,
table_data: Dict[str, Union[List[str], List[List[str]]]],
deid_content_list: List[str],
bucket_size: int,
bucketing_lower_bound: int,
bucketing_upper_bound: int,
) -> types.dlp.Table:
"""Uses the Data Loss Prevention API to de-identify sensitive data in a
table by replacing them with fixed size bucket ranges.
Args:
project: The Google Cloud project id to use as a parent resource.
table_data: Dictionary representing table data.
deid_content_list: A list of fields in table to de-identify.
bucket_size: Size of each bucket for fixed sized bucketing
(except for minimum and maximum buckets). So if ``bucketing_lower_bound`` = 10,
``bucketing_upper_bound`` = 89, and ``bucket_size`` = 10, then the
following buckets would be used: -10, 10-20, 20-30, 30-40,
40-50, 50-60, 60-70, 70-80, 80-89, 89+.
bucketing_lower_bound: Lower bound value of buckets.
bucketing_upper_bound: Upper bound value of buckets.
Returns:
De-identified table is returned;
the response from the API is also printed to the terminal.
Example:
>> $ python deidentify_table_bucketing.py \
'{"header": ["email", "phone number", "age"],
"rows": [["robertfrost@example.com", "4232342345", "35"],
["johndoe@example.com", "4253458383", "68"]]}' \
["age"] 10 0 100
>> '{"header": ["email", "phone number", "age"],
"rows": [["robertfrost@example.com", "4232342345", "30:40"],
["johndoe@example.com", "4253458383", "60:70"]]}'
"""
# Instantiate a client.
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_data["header"]]
rows = []
for row in table_data["rows"]:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Construct the `item`.
item = {"table": table}
# Construct fixed sized bucketing configuration
fixed_size_bucketing_config = {
"bucket_size": bucket_size,
"lower_bound": {"integer_value": bucketing_lower_bound},
"upper_bound": {"integer_value": bucketing_upper_bound},
}
# Specify fields to be de-identified
deid_content_list = [{"name": _i} for _i in deid_content_list]
# Construct Deidentify Config
deidentify_config = {
"record_transformations": {
"field_transformations": [
{
"fields": deid_content_list,
"primitive_transformation": {
"fixed_size_bucketing_config": fixed_size_bucketing_config
},
}
]
}
}
# Call the API.
response = dlp.deidentify_content(
request={"parent": parent, "deidentify_config": deidentify_config, "item": item}
)
# Print the results.
print(f"Table after de-identification: {response.item.table}")
# Return the response.
return response.item.table
using System;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
public class DeidentifyTableUsingMaskingAndLogic
{
public static Table DeidentifyTable(
string projectId,
Table tableToInspect = null)
{
// Instantiate the client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
if (tableToInspect == null)
{
var row1 = new Value[]
{
new Value { StringValue = "101" },
new Value { StringValue = "Charles Dickens" },
new Value { StringValue = "95" },
new Value { StringValue = "Charles Dickens name was a curse invented by Shakespeare." }
};
var row2 = new Value[]
{
new Value { StringValue = "22" },
new Value { StringValue = "Jane Austin" },
new Value { StringValue = "21" },
new Value { StringValue = "There are 14 kisses in Jane Austen's novels." }
};
var row3 = new Value[]
{
new Value { StringValue = "55" },
new Value { StringValue = "Mark Twain" },
new Value { StringValue = "75" },
new Value { StringValue = "Mark Twain loved cats." }
};
tableToInspect = new Table
{
Headers =
{
new FieldId { Name = "AGE" },
new FieldId { Name = "PATIENT" },
new FieldId { Name = "HAPPINESS SCORE" },
new FieldId { Name = "FACTOID" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } },
new Table.Types.Row { Values = { row3 } }
}
};
}
// Construct the table content item.
var contentItem = new ContentItem { Table = tableToInspect };
//Specify how the content should be de-identified.
var primitiveTransformation = new PrimitiveTransformation
{
CharacterMaskConfig = new CharacterMaskConfig
{
MaskingCharacter = "*"
}
};
// Specify the fields to be de-identified.
var fields = new FieldId[] { new FieldId { Name = "HAPPINESS SCORE" } };
// Specify when the above fields should be de-identified using condition.
var condition = new RecordCondition.Types.Conditions
{
Conditions_ =
{
new RecordCondition.Types.Condition
{
Field = new FieldId { Name = "AGE" },
Operator = RelationalOperator.GreaterThan,
Value = new Value { IntegerValue = 89 }
}
}
};
// Apply the condition to records
var recordCondition = new RecordCondition
{
Expressions = new RecordCondition.Types.Expressions
{
Conditions = condition
}
};
// Associate the de-identification and conditions with the specified fields.
var deidentifiedConfig = new DeidentifyConfig
{
RecordTransformations = new RecordTransformations
{
FieldTransformations =
{
new FieldTransformation
{
PrimitiveTransformation = primitiveTransformation,
Fields = { fields },
Condition = recordCondition
}
}
}
};
// Construct the request.
var request = new DeidentifyContentRequest
{
ParentAsLocationName = new LocationName(projectId, "global"),
DeidentifyConfig = deidentifiedConfig,
Item = contentItem
};
// Call the API.
var response = dlp.DeidentifyContent(request);
// Inspect the response.
Console.WriteLine(response.Item.Table);
return response.Item.Table;
}
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.CharacterMaskConfig;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.FieldTransformation;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.RecordCondition;
import com.google.privacy.dlp.v2.RecordCondition.Condition;
import com.google.privacy.dlp.v2.RecordCondition.Conditions;
import com.google.privacy.dlp.v2.RecordCondition.Expressions;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.RelationalOperator;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.Table.Row;
import com.google.privacy.dlp.v2.Value;
import java.io.IOException;
public class DeIdentifyTableConditionMasking {
public static void main(String[] args) throws IOException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "your-project-id";
Table tableToDeIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("AGE").build())
.addHeaders(FieldId.newBuilder().setName("PATIENT").build())
.addHeaders(FieldId.newBuilder().setName("HAPPINESS SCORE").build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("101").build())
.addValues(Value.newBuilder().setStringValue("Charles Dickens").build())
.addValues(Value.newBuilder().setStringValue("95").build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("22").build())
.addValues(Value.newBuilder().setStringValue("Jane Austen").build())
.addValues(Value.newBuilder().setStringValue("21").build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("55").build())
.addValues(Value.newBuilder().setStringValue("Mark Twain").build())
.addValues(Value.newBuilder().setStringValue("75").build())
.build())
.build();
deIdentifyTableConditionMasking(projectId, tableToDeIdentify);
}
public static Table deIdentifyTableConditionMasking(String projectId, Table tableToDeIdentify)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to de-identify.
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToDeIdentify).build();
// Specify how the content should be de-identified.
CharacterMaskConfig characterMaskConfig =
CharacterMaskConfig.newBuilder().setMaskingCharacter("*").build();
PrimitiveTransformation primitiveTransformation =
PrimitiveTransformation.newBuilder().setCharacterMaskConfig(characterMaskConfig).build();
// Specify field to be de-identified.
FieldId fieldId = FieldId.newBuilder().setName("HAPPINESS SCORE").build();
// Specify when the above field should be de-identified.
Condition condition =
Condition.newBuilder()
.setField(FieldId.newBuilder().setName("AGE").build())
.setOperator(RelationalOperator.GREATER_THAN)
.setValue(Value.newBuilder().setIntegerValue(89).build())
.build();
// Apply the condition to records
RecordCondition recordCondition =
RecordCondition.newBuilder()
.setExpressions(
Expressions.newBuilder()
.setConditions(Conditions.newBuilder().addConditions(condition).build())
.build())
.build();
// Associate the de-identification and conditions with the specified field.
FieldTransformation fieldTransformation =
FieldTransformation.newBuilder()
.setPrimitiveTransformation(primitiveTransformation)
.addFields(fieldId)
.setCondition(recordCondition)
.build();
RecordTransformations transformations =
RecordTransformations.newBuilder().addFieldTransformations(fieldTransformation).build();
DeidentifyConfig deidentifyConfig =
DeidentifyConfig.newBuilder().setRecordTransformations(transformations).build();
// Combine configurations into a request for the service.
DeidentifyContentRequest request =
DeidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setDeidentifyConfig(deidentifyConfig)
.build();
// Send the request and receive response from the service.
DeidentifyContentResponse response = dlp.deidentifyContent(request);
// Print the results.
System.out.println("Table after de-identification: " + response.getItem().getTable());
return response.getItem().getTable();
}
}
}
use Google\Cloud\Dlp\V2\CharacterMaskConfig;
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\FieldTransformation;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RecordCondition;
use Google\Cloud\Dlp\V2\RecordCondition\Condition;
use Google\Cloud\Dlp\V2\RecordCondition\Conditions;
use Google\Cloud\Dlp\V2\RecordCondition\Expressions;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\RelationalOperator;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\Value;
/**
* De-identify table data using masking and conditional logic.
* Transform a column based on the value of another column.
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to deidentify
* @param string $outputCsvFile The oupt file path to save deidentify content
*/
function deidentify_table_condition_masking(
// TODO(developer): Replace sample parameters before running the code.
string $callingProjectId,
string $inputCsvFile = './test/data/table2.csv',
string $outputCsvFile = './test/data/deidentify_table_condition_masking_output.csv'
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
$parent = "projects/$callingProjectId/locations/global";
// Read a CSV file
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify what content you want the service to de-identify.
$content = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify how the content should be de-identified.
$characterMaskConfig = (new CharacterMaskConfig())
->setMaskingCharacter('*');
$primitiveTransformation = (new PrimitiveTransformation())
->setCharacterMaskConfig($characterMaskConfig);
// Specify field to be de-identified.
$fieldId = (new FieldId())
->setName('HAPPINESS_SCORE');
// Specify when the above fields should be de-identified.
$condition = (new Condition())
->setField((new FieldId())
->setName('AGE'))
->setOperator(RelationalOperator::GREATER_THAN)
->setValue((new Value())
->setIntegerValue(89));
// Apply the condition to records
$recordCondition = (new RecordCondition())
->setExpressions((new Expressions())
->setConditions((new Conditions())
->setConditions([$condition])
)
);
// Associate the de-identification and conditions with the specified fields.
$fieldTransformation = (new FieldTransformation())
->setPrimitiveTransformation($primitiveTransformation)
->setFields([$fieldId])
->setCondition($recordCondition);
$recordtransformations = (new RecordTransformations())
->setFieldTransformations([$fieldTransformation]);
$deidentifyConfig = (new DeidentifyConfig())
->setRecordTransformations($recordtransformations);
// Run request
$deidentifyContentRequest = (new DeidentifyContentRequest())
->setParent($parent)
->setDeidentifyConfig($deidentifyConfig)
->setItem($content);
$response = $dlp->deidentifyContent($deidentifyContentRequest);
// Print results
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf('After de-identify the table data (Output File Location): %s', $outputCsvFile);
}
from typing import Dict, List, Union
import google.cloud.dlp
from google.cloud.dlp_v2 import types
def deidentify_table_condition_masking(
project: str,
table_data: Dict[str, Union[List[str], List[List[str]]]],
deid_content_list: List[str],
condition_field: str = None,
condition_operator: str = None,
condition_value: int = None,
masking_character: str = None,
) -> types.dlp.Table:
""" Uses the Data Loss Prevention API to de-identify sensitive data in a
table by masking them based on a condition.
Args:
project: The Google Cloud project id to use as a parent resource.
table_data: Json string representing table data.
deid_content_list: A list of fields in table to de-identify.
condition_field: A table Field within the record this condition is evaluated against.
condition_operator: Operator used to compare the field or infoType to the value. One of:
RELATIONAL_OPERATOR_UNSPECIFIED, EQUAL_TO, NOT_EQUAL_TO, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUALS,
LESS_THAN_OR_EQUALS, EXISTS.
condition_value: Value to compare against. [Mandatory, except for ``EXISTS`` tests.].
masking_character: The character to mask matching sensitive data with.
Returns:
De-identified table is returned;
the response from the API is also printed to the terminal.
Example:
>> $ python deidentify_table_condition_masking.py \
'{"header": ["email", "phone number", "age", "happiness_score"],
"rows": [["robertfrost@example.com", "4232342345", "35", "21"],
["johndoe@example.com", "4253458383", "64", "34"]]}' \
["happiness_score"] "age" "GREATER_THAN" 50
>> '{"header": ["email", "phone number", "age", "happiness_score"],
"rows": [["robertfrost@example.com", "4232342345", "35", "21"],
["johndoe@example.com", "4253458383", "64", "**"]]}'
"""
# Instantiate a client.
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_data["header"]]
rows = []
for row in table_data["rows"]:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Construct the `item`
item = {"table": table}
# Specify fields to be de-identified
deid_content_list = [{"name": _i} for _i in deid_content_list]
# Construct condition list
condition = [
{
"field": {"name": condition_field},
"operator": condition_operator,
"value": {"integer_value": condition_value},
}
]
# Construct deidentify configuration dictionary
deidentify_config = {
"record_transformations": {
"field_transformations": [
{
"primitive_transformation": {
"character_mask_config": {
"masking_character": masking_character
}
},
"fields": deid_content_list,
"condition": {
"expressions": {"conditions": {"conditions": condition}}
},
}
]
}
}
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Call the API.
response = dlp.deidentify_content(
request={"parent": parent, "deidentify_config": deidentify_config, "item": item}
)
# Print the result
print(f"Table after de-identification: {response.item.table}")
# Return the response
return response.item.table
You can transform findings that make up either only part of a cell's
content or all of it. In this example, all instances of PERSON_NAME are
anonymized.
Input
Transformed table
AGE
PATIENT
HAPPINESS SCORE
FACTOID
101
Charles Dickens
95
Charles Dickens name was a curse, possibly invented by Shakespeare.
22
Jane Austen
21
There are 14 kisses in Jane Austen's novels.
55
Mark Twain
75
Mark Twain loved cats.
AGE
PATIENT
HAPPINESS SCORE
FACTOID
101
[PERSON_NAME]
95
[PERSON_NAME] name was a curse, possibly invented by Shakespeare.
using System;
using System.Collections.Generic;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
public class DeidentifyTableWithInfoTypes
{
public static Table DeidentifyTable(
string projectId,
Table tableToInspect = null,
IEnumerable<InfoType> infoTypes = null)
{
// Instantiate a client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
if (tableToInspect == null)
{
var row1 = new Value[]
{
new Value { StringValue = "101" },
new Value { StringValue = "Charles Dickens" },
new Value { StringValue = "95" },
new Value { StringValue = "Charles Dickens name was a curse invented by Shakespeare." }
};
var row2 = new Value[]
{
new Value { StringValue = "22" },
new Value { StringValue = "Jane Austin" },
new Value { StringValue = "21" },
new Value { StringValue = "There are 14 kisses in Jane Austen's novels." }
};
var row3 = new Value[]
{
new Value { StringValue = "55" },
new Value { StringValue = "Mark Twain" },
new Value { StringValue = "75" },
new Value { StringValue = "Mark Twain loved cats." }
};
tableToInspect = new Table
{
Headers =
{
new FieldId { Name = "AGE" },
new FieldId { Name = "PATIENT" },
new FieldId { Name = "HAPPINESS SCORE" },
new FieldId { Name = "FACTOID" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } },
new Table.Types.Row { Values = { row3 } }
}
};
}
// Construct the table content item.
var contentItem = new ContentItem { Table = tableToInspect };
// Construct Replace With InfoTypes config to replace the match.
var replaceInfoTypesConfig = new ReplaceWithInfoTypeConfig();
// Construct Fields to be de-identified.
var fieldIds = new FieldId[] { new FieldId { Name = "PATIENT" }, new FieldId { Name = "FACTOID" } };
// Construct InfoType Transformation.
var infoTypeTransformations = new InfoTypeTransformations
{
Transformations =
{
new InfoTypeTransformations.Types.InfoTypeTransformation
{
PrimitiveTransformation = new PrimitiveTransformation
{
ReplaceWithInfoTypeConfig = replaceInfoTypesConfig
},
InfoTypes = { infoTypes ?? new InfoType[] { new InfoType { Name = "PERSON_NAME" } } }
}
}
};
// Construct the de-identify config using replace config.
var deidentifyConfig = new DeidentifyConfig
{
RecordTransformations = new RecordTransformations
{
FieldTransformations =
{
new FieldTransformation
{
InfoTypeTransformations = infoTypeTransformations,
Fields = { fieldIds }
}
}
}
};
// Construct the request.
var request = new DeidentifyContentRequest
{
ParentAsLocationName = new LocationName(projectId, "global"),
DeidentifyConfig = deidentifyConfig,
Item = contentItem
};
// Call the API.
var response = dlp.DeidentifyContent(request);
// Inspect the response.
Console.WriteLine(response.Item.Table);
return response.Item.Table;
}
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.FieldTransformation;
import com.google.privacy.dlp.v2.InfoType;
import com.google.privacy.dlp.v2.InfoTypeTransformations;
import com.google.privacy.dlp.v2.InfoTypeTransformations.InfoTypeTransformation;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.ReplaceWithInfoTypeConfig;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.Table.Row;
import com.google.privacy.dlp.v2.Value;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DeIdentifyTableInfoTypes {
public static void main(String[] args) throws IOException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "your-project-id";
Table tableToDeIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("AGE").build())
.addHeaders(FieldId.newBuilder().setName("PATIENT").build())
.addHeaders(FieldId.newBuilder().setName("HAPPINESS SCORE").build())
.addHeaders(FieldId.newBuilder().setName("FACTOID").build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("101").build())
.addValues(Value.newBuilder().setStringValue("Charles Dickens").build())
.addValues(Value.newBuilder().setStringValue("95").build())
.addValues(
Value.newBuilder()
.setStringValue(
"Charles Dickens name was a curse invented by Shakespeare.")
.build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("22").build())
.addValues(Value.newBuilder().setStringValue("Jane Austen").build())
.addValues(Value.newBuilder().setStringValue("21").build())
.addValues(
Value.newBuilder()
.setStringValue("There are 14 kisses in Jane Austen's novels.")
.build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("55").build())
.addValues(Value.newBuilder().setStringValue("Mark Twain").build())
.addValues(Value.newBuilder().setStringValue("75").build())
.addValues(Value.newBuilder().setStringValue("Mark Twain loved cats.").build())
.build())
.build();
deIdentifyTableInfoTypes(projectId, tableToDeIdentify);
}
public static Table deIdentifyTableInfoTypes(String projectId, Table tableToDeIdentify)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to de-identify.
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToDeIdentify).build();
// Specify how the content should be de-identified.
// Select type of info to be replaced.
InfoType infoType = InfoType.newBuilder().setName("PERSON_NAME").build();
// Specify that findings should be replaced with corresponding info type name.
ReplaceWithInfoTypeConfig replaceWithInfoTypeConfig =
ReplaceWithInfoTypeConfig.getDefaultInstance();
PrimitiveTransformation primitiveTransformation =
PrimitiveTransformation.newBuilder()
.setReplaceWithInfoTypeConfig(replaceWithInfoTypeConfig)
.build();
// Associate info type with the replacement strategy
InfoTypeTransformation infoTypeTransformation =
InfoTypeTransformation.newBuilder()
.addInfoTypes(infoType)
.setPrimitiveTransformation(primitiveTransformation)
.build();
InfoTypeTransformations infoTypeTransformations =
InfoTypeTransformations.newBuilder().addTransformations(infoTypeTransformation).build();
// Specify fields to be de-identified.
List<FieldId> fieldIds =
Stream.of("PATIENT", "FACTOID")
.map(id -> FieldId.newBuilder().setName(id).build())
.collect(Collectors.toList());
// Associate the de-identification and conditions with the specified field.
FieldTransformation fieldTransformation =
FieldTransformation.newBuilder()
.setInfoTypeTransformations(infoTypeTransformations)
.addAllFields(fieldIds)
.build();
RecordTransformations transformations =
RecordTransformations.newBuilder().addFieldTransformations(fieldTransformation).build();
DeidentifyConfig deidentifyConfig =
DeidentifyConfig.newBuilder().setRecordTransformations(transformations).build();
// Combine configurations into a request for the service.
DeidentifyContentRequest request =
DeidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setDeidentifyConfig(deidentifyConfig)
.build();
// Send the request and receive response from the service.
DeidentifyContentResponse response = dlp.deidentifyContent(request);
// Print the results.
System.out.println("Table after de-identification: " + response.getItem().getTable());
return response.getItem().getTable();
}
}
}
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\FieldTransformation;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\ReplaceWithInfoTypeConfig;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\Value;
/**
* De-identify table data with infoTypes
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to deidentify
* @param string $outputCsvFile The oupt file path to save deidentify content
*/
function deidentify_table_infotypes(
// TODO(developer): Replace sample parameters before running the code.
string $callingProjectId,
string $inputCsvFile = './test/data/table1.csv',
string $outputCsvFile = './test/data/deidentify_table_infotypes_output.csv'
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
$parent = "projects/$callingProjectId/locations/global";
// Read a CSV file
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify the content to be inspected.
$content = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify the type of info the inspection will look for.
$personNameInfoType = (new InfoType())
->setName('PERSON_NAME');
// Specify that findings should be replaced with corresponding info type name.
$primitiveTransformation = (new PrimitiveTransformation())
->setReplaceWithInfoTypeConfig(new ReplaceWithInfoTypeConfig());
// Associate info type with the replacement strategy
$infoTypeTransformation = (new InfoTypeTransformation())
->setPrimitiveTransformation($primitiveTransformation)
->setInfoTypes([$personNameInfoType]);
$infoTypeTransformations = (new InfoTypeTransformations())
->setTransformations([$infoTypeTransformation]);
// Specify fields to be de-identified.
$fieldIds = [
(new FieldId())->setName('PATIENT'),
(new FieldId())->setName('FACTOID'),
];
// Associate the de-identification and transformation with the specified fields.
$fieldTransformation = (new FieldTransformation())
->setInfoTypeTransformations($infoTypeTransformations)
->setFields($fieldIds);
$recordtransformations = (new RecordTransformations())
->setFieldTransformations([$fieldTransformation]);
$deidentifyConfig = (new DeidentifyConfig())
->setRecordTransformations($recordtransformations);
// Run request
$deidentifyContentRequest = (new DeidentifyContentRequest())
->setParent($parent)
->setDeidentifyConfig($deidentifyConfig)
->setItem($content);
$response = $dlp->deidentifyContent($deidentifyContentRequest);
// Print the results
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf('After de-identify the table data (Output File Location): %s', $outputCsvFile);
}
from typing import Dict, List, Union
import google.cloud.dlp
def deidentify_table_replace_with_info_types(
project: str,
table_data: Dict[str, Union[List[str], List[List[str]]]],
info_types: List[str],
deid_content_list: List[str],
) -> None:
""" Uses the Data Loss Prevention API to de-identify sensitive data in a
table by replacing them with info type.
Args:
project: The Google Cloud project id to use as a parent resource.
table_data: Json string representing table data.
info_types: A list of strings representing info types to look for.
A full list of info type categories can be fetched from the API.
deid_content_list: A list of fields in table to de-identify
Returns:
None; the response from the API is printed to the terminal.
Example:
>> $ python deidentify_table_infotypes.py \
'{
"header": ["name", "email", "phone number"],
"rows": [
["Robert Frost", "robertfrost@example.com", "4232342345"],
["John Doe", "johndoe@example.com", "4253458383"]
]
}' \
["PERSON_NAME"] ["name"]
>> '{
"header": ["name", "email", "phone number"],
"rows": [
["[PERSON_NAME]", "robertfrost@example.com", "4232342345"],
["[PERSON_NAME]", "johndoe@example.com", "4253458383"]
]
}'
"""
# Instantiate a client.
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_data["header"]]
rows = []
for row in table_data["rows"]:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Construct item
item = {"table": table}
# Specify fields to be de-identified
deid_content_list = [{"name": _i} for _i in deid_content_list]
# Construct inspect configuration dictionary
inspect_config = {"info_types": [{"name": info_type} for info_type in info_types]}
# Construct deidentify configuration dictionary
deidentify_config = {
"record_transformations": {
"field_transformations": [
{
"info_type_transformations": {
"transformations": [
{
"primitive_transformation": {
"replace_with_info_type_config": {}
}
}
]
},
"fields": deid_content_list,
}
]
}
}
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Call the API.
response = dlp.deidentify_content(
request={
"parent": parent,
"deidentify_config": deidentify_config,
"item": item,
"inspect_config": inspect_config,
}
)
# Print the result
print(f"Table after de-identification: {response.item.table}")
You can remove a row entirely based on the content that appears in any column.
This example suppresses the record for "Charles Dickens," as this patient is
over 89 years old.
using System;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
public class DeidentifyTableWithRowSuppress
{
public static Table DeidentifyTable(
string projectId,
Table tableToInspect = null)
{
// Instantiate a client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
if (tableToInspect == null)
{
var row1 = new Value[]
{
new Value { StringValue = "101" },
new Value { StringValue = "Charles Dickens" },
new Value { StringValue = "95" }
};
var row2 = new Value[]
{
new Value { StringValue = "22" },
new Value { StringValue = "Jane Austin" },
new Value { StringValue = "21" }
};
var row3 = new Value[]
{
new Value { StringValue = "55" },
new Value { StringValue = "Mark Twain" },
new Value { StringValue = "75" }
};
tableToInspect = new Table
{
Headers =
{
new FieldId { Name = "AGE" },
new FieldId { Name = "PATIENT" },
new FieldId { Name = "HAPPINESS SCORE" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } },
new Table.Types.Row { Values = { row3 } }
}
};
}
// Construct the byte content item.
var contentItem = new ContentItem { Table = tableToInspect };
// Construct the conditions.
var conditions = new RecordCondition.Types.Conditions
{
Conditions_ =
{
new RecordCondition.Types.Condition
{
Field = new FieldId { Name = "AGE" },
Operator = RelationalOperator.GreaterThan,
Value = new Value { IntegerValue = 89 }
}
}
};
// Construct the deidentify config using the record suppression and conditions.
var deidentifyConfig = new DeidentifyConfig
{
RecordTransformations = new RecordTransformations
{
RecordSuppressions =
{
new RecordSuppression
{
Condition = new RecordCondition
{
Expressions = new RecordCondition.Types.Expressions
{
Conditions = conditions
}
}
}
}
}
};
// Construct the request.
var request = new DeidentifyContentRequest
{
ParentAsLocationName = new LocationName(projectId, "global"),
DeidentifyConfig = deidentifyConfig,
Item = contentItem
};
// Call the API.
var response = dlp.DeidentifyContent(request);
// Inspect the response.
Console.WriteLine(response.Item.Table);
return response.Item.Table;
}
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.RecordCondition;
import com.google.privacy.dlp.v2.RecordCondition.Condition;
import com.google.privacy.dlp.v2.RecordCondition.Conditions;
import com.google.privacy.dlp.v2.RecordCondition.Expressions;
import com.google.privacy.dlp.v2.RecordSuppression;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.RelationalOperator;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.Table.Row;
import com.google.privacy.dlp.v2.Value;
import java.io.IOException;
public class DeIdentifyTableRowSuppress {
public static void main(String[] args) throws IOException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "your-project-id";
Table tableToDeIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("AGE").build())
.addHeaders(FieldId.newBuilder().setName("PATIENT").build())
.addHeaders(FieldId.newBuilder().setName("HAPPINESS SCORE").build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("101").build())
.addValues(Value.newBuilder().setStringValue("Charles Dickens").build())
.addValues(Value.newBuilder().setStringValue("95").build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("22").build())
.addValues(Value.newBuilder().setStringValue("Jane Austen").build())
.addValues(Value.newBuilder().setStringValue("21").build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("55").build())
.addValues(Value.newBuilder().setStringValue("Mark Twain").build())
.addValues(Value.newBuilder().setStringValue("75").build())
.build())
.build();
deIdentifyTableRowSuppress(projectId, tableToDeIdentify);
}
public static Table deIdentifyTableRowSuppress(String projectId, Table tableToDeIdentify)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to de-identify.
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToDeIdentify).build();
// Specify when the content should be de-identified.
Condition condition =
Condition.newBuilder()
.setField(FieldId.newBuilder().setName("AGE").build())
.setOperator(RelationalOperator.GREATER_THAN)
.setValue(Value.newBuilder().setIntegerValue(89).build())
.build();
// Apply the condition to record suppression.
RecordSuppression recordSuppressions =
RecordSuppression.newBuilder()
.setCondition(
RecordCondition.newBuilder()
.setExpressions(
Expressions.newBuilder()
.setConditions(
Conditions.newBuilder().addConditions(condition).build())
.build())
.build())
.build();
// Use record suppression as the only transformation
RecordTransformations transformations =
RecordTransformations.newBuilder().addRecordSuppressions(recordSuppressions).build();
DeidentifyConfig deidentifyConfig =
DeidentifyConfig.newBuilder().setRecordTransformations(transformations).build();
// Combine configurations into a request for the service.
DeidentifyContentRequest request =
DeidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setDeidentifyConfig(deidentifyConfig)
.build();
// Send the request and receive response from the service.
DeidentifyContentResponse response = dlp.deidentifyContent(request);
// Print the results.
System.out.println("Table after de-identification: " + response.getItem().getTable());
return response.getItem().getTable();
}
}
}
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\RecordCondition;
use Google\Cloud\Dlp\V2\RecordCondition\Condition;
use Google\Cloud\Dlp\V2\RecordCondition\Conditions;
use Google\Cloud\Dlp\V2\RecordCondition\Expressions;
use Google\Cloud\Dlp\V2\RecordSuppression;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\RelationalOperator;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\Value;
/**
* De-identify table data: Suppress a row based on the content of a column
* Suppress a row based on the content of a column. You can remove a row entirely based on the content that appears in any column. This example suppresses the record for "Charles Dickens," as this patient is over 89 years old.
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to deidentify
* @param string $outputCsvFile The oupt file path to save deidentify content */
function deidentify_table_row_suppress(
// TODO(developer): Replace sample parameters before running the code.
string $callingProjectId,
string $inputCsvFile = './test/data/table2.csv',
string $outputCsvFile = './test/data/deidentify_table_row_suppress_output.csv'
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
$parent = "projects/$callingProjectId/locations/global";
// Read a CSV file
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify what content you want the service to de-identify.
$content = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify when the content should be de-identified.
$condition = (new Condition())
->setField((new FieldId())
->setName('AGE'))
->setOperator(RelationalOperator::GREATER_THAN)
->setValue((new Value())
->setIntegerValue(89));
// Apply the condition to record suppression.
$recordSuppressions = (new RecordSuppression())
->setCondition((new RecordCondition())
->setExpressions((new Expressions())
->setConditions((new Conditions())
->setConditions([$condition])
)
)
);
// Use record suppression as the only transformation
$recordtransformations = (new RecordTransformations())
->setRecordSuppressions([$recordSuppressions]);
// Create the deidentification configuration object
$deidentifyConfig = (new DeidentifyConfig())
->setRecordTransformations($recordtransformations);
// Run request
$deidentifyContentRequest = (new DeidentifyContentRequest())
->setParent($parent)
->setDeidentifyConfig($deidentifyConfig)
->setItem($content);
$response = $dlp->deidentifyContent($deidentifyContentRequest);
// Print the results
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf($outputCsvFile);
}
from typing import Dict, List, Union
import google.cloud.dlp
def deidentify_table_suppress_row(
project: str,
table_data: Dict[str, Union[List[str], List[List[str]]]],
condition_field: str,
condition_operator: str,
condition_value: int,
) -> None:
""" Uses the Data Loss Prevention API to de-identify sensitive data in a
table by suppressing entire row/s based on a condition.
Args:
project: The Google Cloud project id to use as a parent resource.
table_data: Dictionary representing table data.
condition_field: A table field within the record this condition is evaluated against.
condition_operator: Operator used to compare the field or infoType to the value. One of:
RELATIONAL_OPERATOR_UNSPECIFIED, EQUAL_TO, NOT_EQUAL_TO, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUALS,
LESS_THAN_OR_EQUALS, EXISTS.
condition_value: Value to compare against. [Mandatory, except for ``EXISTS`` tests.].
Example:
>> $ python deidentify_table_row_suppress.py \
'{"header": ["email", "phone number", "age"],
"rows": [["robertfrost@example.com", "4232342345", "35"],
["johndoe@example.com", "4253458383", "64"]]}' \
"age" "GREATER_THAN" 50
>> '{"header": ["email", "phone number", "age"],
"rows": [["robertfrost@example.com", "4232342345", "35", "21"]]}'
"""
# Instantiate a client.
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_data["header"]]
rows = []
for row in table_data["rows"]:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Construct the `item` containing the table data.
item = {"table": table}
# Construct condition list.
condition = [
{
"field": {"name": condition_field},
"operator": condition_operator,
"value": {"integer_value": condition_value},
}
]
# Construct deidentify configuration dictionary
deidentify_config = {
"record_transformations": {
"record_suppressions": [
{
"condition": {
"expressions": {"conditions": {"conditions": condition}}
}
}
]
}
}
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Call the API.
response = dlp.deidentify_content(
request={"parent": parent, "deidentify_config": deidentify_config, "item": item}
)
# Print the result.
print(f"Table after de-identification: {response.item.table}")
using System;
using System.Collections.Generic;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
public class DeidentifyTableUsingLogicInfoTypes
{
public static Table Deidentify(
string projectId,
Table tableToInspect = null,
IEnumerable<InfoType> infoTypes = null)
{
// Instantiate the dlp client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
if (tableToInspect == null)
{
var row1 = new Value[]
{
new Value { StringValue = "101" },
new Value { StringValue = "Charles Dickens" },
new Value { StringValue = "95" },
new Value { StringValue = "Charles Dickens name was a curse invented by Shakespeare." }
};
var row2 = new Value[]
{
new Value { StringValue = "22" },
new Value { StringValue = "Jane Austin" },
new Value { StringValue = "21" },
new Value { StringValue = "There are 14 kisses in Jane Austen's novels." }
};
var row3 = new Value[]
{
new Value { StringValue = "55" },
new Value { StringValue = "Mark Twain" },
new Value { StringValue = "75" },
new Value { StringValue = "Mark Twain loved cats." }
};
tableToInspect = new Table
{
Headers =
{
new FieldId { Name = "AGE" },
new FieldId { Name = "PATIENT" },
new FieldId { Name = "HAPPINESS SCORE" },
new FieldId { Name = "FACTOID" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } },
new Table.Types.Row { Values = { row3 } }
}
};
}
// Construct the table content item.
var contentItem = new ContentItem { Table = tableToInspect };
// Specify that findings should be replaced with corresponding info type name.
var infoTypeTransformation = new InfoTypeTransformations
{
Transformations =
{
new InfoTypeTransformations.Types.InfoTypeTransformation
{
InfoTypes = { infoTypes ?? new InfoType[] { new InfoType { Name = "PERSON_NAME" } } },
PrimitiveTransformation = new PrimitiveTransformation
{
ReplaceWithInfoTypeConfig = new ReplaceWithInfoTypeConfig()
}
}
}
};
// Specify the fields to be de-identified.
var fields = new FieldId[] { new FieldId { Name = "PATIENT" }, new FieldId { Name = "FACTOID" } };
// Specify when the above fields should be de-identified using condition.
var condition = new RecordCondition.Types.Conditions
{
Conditions_ =
{
new RecordCondition.Types.Condition
{
Field = new FieldId { Name = "AGE" },
Operator = RelationalOperator.GreaterThan,
Value = new Value { IntegerValue = 89 }
}
}
};
// Apply the condition to records.
var recordCondition = new RecordCondition
{
Expressions = new RecordCondition.Types.Expressions
{
Conditions = condition
}
};
// Associate the de-identification and conditions with the specified fields.
var deidentifiedConfig = new DeidentifyConfig
{
RecordTransformations = new RecordTransformations
{
FieldTransformations =
{
new FieldTransformation
{
InfoTypeTransformations = infoTypeTransformation,
Fields = { fields },
Condition = recordCondition
}
}
}
};
// Construct the request.
var request = new DeidentifyContentRequest
{
ParentAsLocationName = new LocationName(projectId, "global"),
DeidentifyConfig = deidentifiedConfig,
Item = contentItem
};
// Call the API.
var response = dlp.DeidentifyContent(request);
// Inspect the response.
Console.WriteLine(response.Item.Table);
return response.Item.Table;
}
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.FieldTransformation;
import com.google.privacy.dlp.v2.InfoType;
import com.google.privacy.dlp.v2.InfoTypeTransformations;
import com.google.privacy.dlp.v2.InfoTypeTransformations.InfoTypeTransformation;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.RecordCondition;
import com.google.privacy.dlp.v2.RecordCondition.Condition;
import com.google.privacy.dlp.v2.RecordCondition.Conditions;
import com.google.privacy.dlp.v2.RecordCondition.Expressions;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.RelationalOperator;
import com.google.privacy.dlp.v2.ReplaceWithInfoTypeConfig;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.Table.Row;
import com.google.privacy.dlp.v2.Value;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DeIdentifyTableConditionInfoTypes {
public static void main(String[] args) throws IOException {
// TODO(developer): Replace these variables before running the sample.
String projectId = "your-project-id";
Table tableToDeIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("AGE").build())
.addHeaders(FieldId.newBuilder().setName("PATIENT").build())
.addHeaders(FieldId.newBuilder().setName("HAPPINESS SCORE").build())
.addHeaders(FieldId.newBuilder().setName("FACTOID").build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("101").build())
.addValues(Value.newBuilder().setStringValue("Charles Dickens").build())
.addValues(Value.newBuilder().setStringValue("95").build())
.addValues(
Value.newBuilder()
.setStringValue(
"Charles Dickens name was a curse invented by Shakespeare.")
.build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("22").build())
.addValues(Value.newBuilder().setStringValue("Jane Austen").build())
.addValues(Value.newBuilder().setStringValue("21").build())
.addValues(
Value.newBuilder()
.setStringValue("There are 14 kisses in Jane Austen's novels.")
.build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("55").build())
.addValues(Value.newBuilder().setStringValue("Mark Twain").build())
.addValues(Value.newBuilder().setStringValue("75").build())
.addValues(Value.newBuilder().setStringValue("Mark Twain loved cats.").build())
.build())
.build();
deIdentifyTableConditionInfoTypes(projectId, tableToDeIdentify);
}
public static Table deIdentifyTableConditionInfoTypes(String projectId, Table tableToDeIdentify)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to de-identify.
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToDeIdentify).build();
// Specify how the content should be de-identified.
// Select type of info to be replaced.
InfoType infoType = InfoType.newBuilder().setName("PERSON_NAME").build();
// Specify that findings should be replaced with corresponding info type name.
ReplaceWithInfoTypeConfig replaceWithInfoTypeConfig =
ReplaceWithInfoTypeConfig.getDefaultInstance();
PrimitiveTransformation primitiveTransformation =
PrimitiveTransformation.newBuilder()
.setReplaceWithInfoTypeConfig(replaceWithInfoTypeConfig)
.build();
// Associate info type with the replacement strategy
InfoTypeTransformation infoTypeTransformation =
InfoTypeTransformation.newBuilder()
.addInfoTypes(infoType)
.setPrimitiveTransformation(primitiveTransformation)
.build();
InfoTypeTransformations infoTypeTransformations =
InfoTypeTransformations.newBuilder().addTransformations(infoTypeTransformation).build();
// Specify fields to be de-identified.
List<FieldId> fieldIds =
Stream.of("PATIENT", "FACTOID")
.map(id -> FieldId.newBuilder().setName(id).build())
.collect(Collectors.toList());
// Specify when the above fields should be de-identified.
Condition condition =
Condition.newBuilder()
.setField(FieldId.newBuilder().setName("AGE").build())
.setOperator(RelationalOperator.GREATER_THAN)
.setValue(Value.newBuilder().setIntegerValue(89).build())
.build();
// Apply the condition to records
RecordCondition recordCondition =
RecordCondition.newBuilder()
.setExpressions(
Expressions.newBuilder()
.setConditions(Conditions.newBuilder().addConditions(condition).build())
.build())
.build();
// Associate the de-identification and conditions with the specified fields.
FieldTransformation fieldTransformation =
FieldTransformation.newBuilder()
.setInfoTypeTransformations(infoTypeTransformations)
.addAllFields(fieldIds)
.setCondition(recordCondition)
.build();
RecordTransformations transformations =
RecordTransformations.newBuilder().addFieldTransformations(fieldTransformation).build();
DeidentifyConfig deidentifyConfig =
DeidentifyConfig.newBuilder().setRecordTransformations(transformations).build();
// Combine configurations into a request for the service.
DeidentifyContentRequest request =
DeidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setDeidentifyConfig(deidentifyConfig)
.build();
// Send the request and receive response from the service.
DeidentifyContentResponse response = dlp.deidentifyContent(request);
// Print the results.
System.out.println("Table after de-identification: " + response.getItem().getTable());
return response.getItem().getTable();
}
}
}
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\FieldTransformation;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RecordCondition;
use Google\Cloud\Dlp\V2\RecordCondition\Condition;
use Google\Cloud\Dlp\V2\RecordCondition\Conditions;
use Google\Cloud\Dlp\V2\RecordCondition\Expressions;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\RelationalOperator;
use Google\Cloud\Dlp\V2\ReplaceWithInfoTypeConfig;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\Value;
/**
* De-identify table data using conditional logic and replace with infoTypes.
* Transform findings only when specific conditions are met on another field.
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to deidentify
* @param string $outputCsvFile The oupt file path to save deidentify content
*/
function deidentify_table_condition_infotypes(
// TODO(developer): Replace sample parameters before running the code.
string $callingProjectId,
string $inputCsvFile = './test/data/table1.csv',
string $outputCsvFile = './test/data/deidentify_table_condition_infotypes_output.csv'
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
$parent = "projects/$callingProjectId/locations/global";
// Read a CSV file
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify what content you want the service to de-identify.
$content = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify the type of info the inspection will look for.
$personNameInfoType = (new InfoType())
->setName('PERSON_NAME');
// Specify that findings should be replaced with corresponding info type name.
$primitiveTransformation = (new PrimitiveTransformation())
->setReplaceWithInfoTypeConfig(new ReplaceWithInfoTypeConfig());
// Associate info type with the replacement strategy
$infoTypeTransformation = (new InfoTypeTransformation())
->setPrimitiveTransformation($primitiveTransformation)
->setInfoTypes([$personNameInfoType]);
$infoTypeTransformations = (new InfoTypeTransformations())
->setTransformations([$infoTypeTransformation]);
// Specify fields to be de-identified.
$fieldIds = [
(new FieldId())->setName('PATIENT'),
(new FieldId())->setName('FACTOID'),
];
// Specify when the above fields should be de-identified.
$condition = (new Condition())
->setField((new FieldId())
->setName('AGE'))
->setOperator(RelationalOperator::GREATER_THAN)
->setValue((new Value())
->setIntegerValue(89));
// Apply the condition to records
$recordCondition = (new RecordCondition())
->setExpressions((new Expressions())
->setConditions((new Conditions())
->setConditions([$condition])
)
);
// Associate the de-identification and conditions with the specified fields.
$fieldTransformation = (new FieldTransformation())
->setInfoTypeTransformations($infoTypeTransformations)
->setFields($fieldIds)
->setCondition($recordCondition);
$recordtransformations = (new RecordTransformations())
->setFieldTransformations([$fieldTransformation]);
$deidentifyConfig = (new DeidentifyConfig())
->setRecordTransformations($recordtransformations);
// Run request
$deidentifyContentRequest = (new DeidentifyContentRequest())
->setParent($parent)
->setDeidentifyConfig($deidentifyConfig)
->setItem($content);
$response = $dlp->deidentifyContent($deidentifyContentRequest);
// Print results
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf($outputCsvFile);
}
from typing import Dict, List, Union
import google.cloud.dlp
from google.cloud.dlp_v2 import types
def deidentify_table_condition_replace_with_info_types(
project: str,
table_data: Dict[str, Union[List[str], List[List[str]]]],
deid_content_list: List[str],
info_types: List[str],
condition_field: str = None,
condition_operator: str = None,
condition_value: int = None,
) -> types.dlp.Table:
"""Uses the Data Loss Prevention API to de-identify sensitive data in a
table by replacing them with info-types based on a condition.
Args:
project: The Google Cloud project id to use as a parent resource.
table_data: Json string representing table data.
deid_content_list: A list of fields in table to de-identify.
info_types: A list of strings representing info types to look for.
A full list of info categories and types is available from the API.
Examples include "FIRST_NAME", "LAST_NAME", "EMAIL_ADDRESS". '
condition_field: A table field within the record this condition is evaluated against.
condition_operator: Operator used to compare the field or infoType to the value. One of:
RELATIONAL_OPERATOR_UNSPECIFIED, EQUAL_TO, NOT_EQUAL_TO, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUALS,
LESS_THAN_OR_EQUALS, EXISTS.
condition_value: Value to compare against. [Mandatory, except for ``EXISTS`` tests.].
Returns:
De-identified table is returned;
the response from the API is also printed to the terminal.
Example:
>> $ python deidentify_table_condition_infotypes.py \
'{"header": ["email", "phone number", "age"],
"rows": [["robertfrost@example.com", "4232342345", "45"],
["johndoe@example.com", "4253458383", "63"]]}' ["email"] \
["EMAIL_ADDRESS"] "age" "GREATER_THAN" 50
>> '{"header": ["email", "phone number", "age"],
"rows": [["robertfrost@example.com", "4232342345", "45"],
["[EMAIL_ADDRESS]", "4253458383", "63"]]}'
"""
# Instantiate a client.
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_data["header"]]
rows = []
for row in table_data["rows"]:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Construct the item
item = {"table": table}
# Specify fields to be de-identified
deid_field_list = [{"name": _i} for _i in deid_content_list]
# Construct inspect configuration dictionary
inspect_config = {"info_types": [{"name": info_type} for info_type in info_types]}
# Construct condition list
condition = [
{
"field": {"name": condition_field},
"operator": condition_operator,
"value": {"integer_value": condition_value},
}
]
# Construct deidentify configuration dictionary
deidentify_config = {
"record_transformations": {
"field_transformations": [
{
"info_type_transformations": {
"transformations": [
{
"primitive_transformation": {
"replace_with_info_type_config": {}
}
}
]
},
"fields": deid_field_list,
"condition": {
"expressions": {"conditions": {"conditions": condition}}
},
}
]
}
}
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Call the API.
response = dlp.deidentify_content(
request={
"parent": parent,
"deidentify_config": deidentify_config,
"item": item,
"inspect_config": inspect_config,
}
)
print(f"Table after de-identification: {response.item.table}")
return response.item.table
Transform findings using a cryptographic hash transformation
The following JSON examples use infoType
transformations
to instruct the DLP API to inspect the entire table structure
for specific infoTypes, and then to encrypt the matching
values using a transient
CryptoKey.
The following example demonstrates de-identifying two infoTypes using a
cryptographic hash transformation.
Input:
userid
comments
user1@example.org
my email is user1@example.org and phone is 858-555-0222
user2@example.org
my email is user2@example.org and phone is 858-555-0223
user3@example.org
my email is user3@example.org and phone is 858-555-0224
Transformed table:
userid
comments
1kSfj3Op64MH1BiznupEpX0BdQrHMm62X6abgsPH5zM=
my email is 1kSfj3Op64MH1BiznupEpX0BdQrHMm62X6abgsPH5zM= and phone is hYXPcsJNBCe1rr51sHiVw2KhtoyMe4HEFKNHWFcDVm0=
4ESy7+rEN8NVaUJ6J7kwvcgW8wcm0cm5gbBAcu6SfdM=
my email is 4ESy7+rEN8NVaUJ6J7kwvcgW8wcm0cm5gbBAcu6SfdM= and phone is KKqW1tQwgvGiC6iWJHhLiz2enNSEFRzhmLOf9fSTxRw=
bu1blyd/mbjLmpF2Rdi6zpgsLatSwpJLVki2fMeudM0=
my email is bu1blyd/mbjLmpF2Rdi6zpgsLatSwpJLVki2fMeudM0= and phone is eNt7qtZVLmxRb8z8NBR/+z00In07CI3hEMStbwofWoc=
using System;
using System.Collections.Generic;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
public class DeidentifyTableWithCryptoHash
{
public static Table Deidentify(
string projectId,
Table tableToDeidentify = null,
IEnumerable<InfoType> infoTypes = null,
string transientKeyName = null)
{
// Instantiate the client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
if (tableToDeidentify == null)
{
var row1 = new Value[]
{
new Value { StringValue = "user1@example.org" },
new Value { StringValue = "my email is user1@example.org and phone is 858-555-0222" }
};
var row2 = new Value[]
{
new Value { StringValue = "user2@example.org" },
new Value { StringValue = "my email is user2@example.org and phone is 858-555-0223" }
};
var row3 = new Value[]
{
new Value { StringValue = "user3@example.org" },
new Value { StringValue = "my email is user3@example.org and phone is 858-555-0224" }
};
tableToDeidentify = new Table
{
Headers =
{
new FieldId { Name = "User ID" },
new FieldId { Name = "comments" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } },
new Table.Types.Row { Values = { row3 } }
}
};
}
// Specify the table and construct the content item.
var contentItem = new ContentItem { Table = tableToDeidentify };
// Construct the infoTypes by specifying the type of info to be inspected if null.
var infotypes = infoTypes ?? new InfoType[]
{
new InfoType { Name = "EMAIL_ADDRESS" },
new InfoType { Name = "PHONE_NUMBER" }
};
// Construct the crypto hash config using transient crypto key name.
var cryptoHashConfig = new CryptoHashConfig
{
CryptoKey = new CryptoKey
{
Transient = new TransientCryptoKey
{
Name = transientKeyName ?? "[TRANSIENT-CRYPTO-KEY]"
}
}
};
// Construct the de-identify config using crypto hash config.
var deidentifyConfig = new DeidentifyConfig
{
InfoTypeTransformations = new InfoTypeTransformations
{
Transformations =
{
new InfoTypeTransformations.Types.InfoTypeTransformation
{
PrimitiveTransformation = new PrimitiveTransformation
{
CryptoHashConfig = cryptoHashConfig
},
InfoTypes = { infotypes }
}
}
}
};
// Construct the inspect config.
var inspectConfig = new InspectConfig
{
InfoTypes = { infotypes },
IncludeQuote = true
};
// Construct the request.
var request = new DeidentifyContentRequest
{
ParentAsLocationName = new LocationName(projectId, "global"),
DeidentifyConfig = deidentifyConfig,
Item = contentItem,
InspectConfig = inspectConfig
};
// Call the API.
DeidentifyContentResponse response = dlp.DeidentifyContent(request);
// Print the table.
Console.WriteLine(response.Item.Table);
return response.Item.Table;
}
}
import (
"context"
"fmt"
"io"
dlp "cloud.google.com/go/dlp/apiv2"
"cloud.google.com/go/dlp/apiv2/dlppb"
)
// deIdentifyTableWithCryptoHash transforms findings using a cryptographic hash transformation.
func deIdentifyTableWithCryptoHash(w io.Writer, projectID, transientKeyName string) error {
// projectId := "your-project-id"
// transientKeyName := "YOUR_TRANSIENT_CRYPTO_KEY_NAME"
row1 := &dlppb.Table_Row{
Values: []*dlppb.Value{
{Type: &dlppb.Value_StringValue{StringValue: "user1@example.org"}},
{Type: &dlppb.Value_StringValue{StringValue: "my email is user1@example.org and phone is 858-555-0222"}},
},
}
row2 := &dlppb.Table_Row{
Values: []*dlppb.Value{
{Type: &dlppb.Value_StringValue{StringValue: "user2@example.org"}},
{Type: &dlppb.Value_StringValue{StringValue: "my email is user2@example.org and phone is 858-555-0232"}},
},
}
row3 := &dlppb.Table_Row{
Values: []*dlppb.Value{
{Type: &dlppb.Value_StringValue{StringValue: "user3@example.org"}},
{Type: &dlppb.Value_StringValue{StringValue: "my email is user3@example.org and phone is 858-555-0224"}},
},
}
tableToDeidentify := &dlppb.Table{
Headers: []*dlppb.FieldId{
{Name: "userid"},
{Name: "comments"},
},
Rows: []*dlppb.Table_Row{
{Values: row1.Values},
{Values: row2.Values},
{Values: row3.Values},
},
}
ctx := context.Background()
// Initialize a client once and reuse it to send multiple requests. Clients
// are safe to use across goroutines. When the client is no longer needed,
// call the Close method to cleanup its resources.
client, err := dlp.NewClient(ctx)
if err != nil {
return err
}
// Closing the client safely cleans up background resources.
defer client.Close()
// Specify what content you want the service to de-identify.
contentItem := &dlppb.ContentItem{
DataItem: &dlppb.ContentItem_Table{
Table: tableToDeidentify,
},
}
// Specify the type of info the inspection will look for.
// See https://cloud.google.com/dlp/docs/infotypes-reference for complete list of info types
infoTypes := []*dlppb.InfoType{
{Name: "PHONE_NUMBER"},
{Name: "EMAIL_ADDRESS"},
}
inspectConfig := &dlppb.InspectConfig{
InfoTypes: infoTypes,
}
// Specify the transient key which will encrypt the data.
if transientKeyName == "" {
transientKeyName = "YOUR_TRANSIENT_CRYPTO_KEY_NAME"
}
// Specify the transient key which will encrypt the data.
cryptoKey := &dlppb.CryptoKey{
Source: &dlppb.CryptoKey_Transient{
Transient: &dlppb.TransientCryptoKey{
Name: transientKeyName,
},
},
}
// Specify how the info from the inspection should be encrypted.
cryptoHashConfig := &dlppb.CryptoHashConfig{
CryptoKey: cryptoKey,
}
// Define type of de-identification as cryptographic hash transformation.
primitiveTransformation := &dlppb.PrimitiveTransformation_CryptoHashConfig{
CryptoHashConfig: cryptoHashConfig,
}
infoTypeTransformation := &dlppb.InfoTypeTransformations_InfoTypeTransformation{
InfoTypes: infoTypes,
PrimitiveTransformation: &dlppb.PrimitiveTransformation{
Transformation: primitiveTransformation,
},
}
transformations := &dlppb.InfoTypeTransformations{
Transformations: []*dlppb.InfoTypeTransformations_InfoTypeTransformation{
infoTypeTransformation,
},
}
// Specify the config for the de-identify request.
deidentifyConfig := &dlppb.DeidentifyConfig{
Transformation: &dlppb.DeidentifyConfig_InfoTypeTransformations{
InfoTypeTransformations: transformations,
},
}
// Construct the de-identification request to be sent by the client.
req := &dlppb.DeidentifyContentRequest{
Parent: fmt.Sprintf("projects/%s/locations/global", projectID),
DeidentifyConfig: deidentifyConfig,
InspectConfig: inspectConfig,
Item: contentItem,
}
// Send the request.
resp, err := client.DeidentifyContent(ctx, req)
if err != nil {
return err
}
// Print the results.
fmt.Fprintf(w, "Table after de-identification : %v", resp.GetItem().GetTable())
return nil
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.CryptoHashConfig;
import com.google.privacy.dlp.v2.CryptoKey;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.InfoType;
import com.google.privacy.dlp.v2.InfoTypeTransformations;
import com.google.privacy.dlp.v2.InspectConfig;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.TransientCryptoKey;
import com.google.privacy.dlp.v2.Value;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DeIdentifyTableWithCryptoHash {
public static void main(String[] args) throws Exception {
// TODO(developer): Replace these variables before running the sample.
// The Google Cloud project id to use as a parent resource.
String projectId = "your-project-id";
// The table to de-identify.
Table tableToDeIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("userid").build())
.addHeaders(FieldId.newBuilder().setName("comments").build())
.addRows(
Table.Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("user1@example.org").build())
.addValues(
Value.newBuilder()
.setStringValue(
"my email is user1@example.org and phone is 858-555-0222")
.build())
.build())
.addRows(
Table.Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("user2@example.org").build())
.addValues(
Value.newBuilder()
.setStringValue(
"my email is user2@example.org and phone is 858-555-0223")
.build())
.build())
.addRows(
Table.Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("user3@example.org").build())
.addValues(
Value.newBuilder()
.setStringValue(
"my email is user3@example.org and phone is 858-555-0224")
.build())
.build())
.build();
// The randomly generated crypto key to encrypt the data.
String transientKeyName = "YOUR_TRANSIENT_CRYPTO_KEY";
deIdentifyWithCryptHashTransformation(projectId, tableToDeIdentify, transientKeyName);
}
// Transforms findings using a cryptographic hash transformation.
public static void deIdentifyWithCryptHashTransformation(
String projectId, Table tableToDeIdentify, String transientKeyName) throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to DeIdentify
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToDeIdentify).build();
// Specify the type of info the inspection will look for.
// See https://cloud.google.com/dlp/docs/infotypes-reference for complete list of info types
List<InfoType> infoTypes =
Stream.of("PHONE_NUMBER", "EMAIL_ADDRESS")
.map(it -> InfoType.newBuilder().setName(it).build())
.collect(Collectors.toList());
InspectConfig inspectConfig = InspectConfig.newBuilder()
.addAllInfoTypes(infoTypes)
.build();
// Specify the transient key which will encrypt the data.
TransientCryptoKey transientCryptoKey = TransientCryptoKey.newBuilder()
.setName(transientKeyName)
.build();
CryptoKey cryptoKey = CryptoKey.newBuilder()
.setTransient(transientCryptoKey)
.build();
// Specify how the info from the inspection should be encrypted.
CryptoHashConfig cryptoHashConfig = CryptoHashConfig.newBuilder()
.setCryptoKey(cryptoKey)
.build();
// Define type of de-identification as cryptographic hash transformation.
PrimitiveTransformation primitiveTransformation = PrimitiveTransformation.newBuilder()
.setCryptoHashConfig(cryptoHashConfig)
.build();
InfoTypeTransformations.InfoTypeTransformation infoTypeTransformation =
InfoTypeTransformations.InfoTypeTransformation.newBuilder()
.setPrimitiveTransformation(primitiveTransformation)
.addAllInfoTypes(infoTypes)
.build();
InfoTypeTransformations transformations = InfoTypeTransformations.newBuilder()
.addTransformations(infoTypeTransformation)
.build();
// Specify the config for the de-identify request
DeidentifyConfig deidentifyConfig = DeidentifyConfig.newBuilder()
.setInfoTypeTransformations(transformations)
.build();
// Combine configurations into a request for the service.
DeidentifyContentRequest request =
DeidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setInspectConfig(inspectConfig)
.setDeidentifyConfig(deidentifyConfig)
.build();
// Send the request and receive response from the service
DeidentifyContentResponse response = dlp.deidentifyContent(request);
// Print the results
System.out.println("Table after de-identification: " + response.getItem().getTable());
}
}
}
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\CryptoHashConfig;
use Google\Cloud\Dlp\V2\CryptoKey;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\InspectConfig;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\TransientCryptoKey;
use Google\Cloud\Dlp\V2\Value;
/**
* De-identify table data with crypto hash.
* Transform findings using a cryptographic hash transformation.
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to deidentify.
* @param string $outputCsvFile The oupt file path to save deidentify content.
* @param string $transientCryptoKeyName Specify the random string.
*/
function deidentify_table_with_crypto_hash(
// TODO(developer): Replace sample parameters before running the code.
string $callingProjectId,
string $inputCsvFile = './test/data/table5.csv',
string $outputCsvFile = './test/data/deidentify_table_with_crypto_hash_output.csv',
string $transientCryptoKeyName = 'YOUR-TRANSIENT-CRYPTO-KEY'
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
$parent = "projects/$callingProjectId/locations/global";
// Read a CSV file.
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects.
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object.
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify what content you want the service to de-identify.
$content = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify the type of info the inspection will look for.
// See https://cloud.google.com/dlp/docs/infotypes-reference for complete list of info types
$infoTypes = [
(new InfoType())->setName('EMAIL_ADDRESS'),
(new InfoType())->setName('PHONE_NUMBER')
];
$inspectConfig = (new InspectConfig())
->setInfoTypes($infoTypes);
// Specify the transient key which will encrypt the data.
$cryptoKey = (new CryptoKey())
->setTransient((new TransientCryptoKey())
->setName($transientCryptoKeyName));
// Specify how the info from the inspection should be encrypted.
$cryptoHashConfig = (new CryptoHashConfig())
->setCryptoKey($cryptoKey);
// Define type of de-identification as cryptographic hash transformation.
$primitiveTransformation = (new PrimitiveTransformation())
->setCryptoHashConfig($cryptoHashConfig);
$infoTypeTransformation = (new InfoTypeTransformation())
->setPrimitiveTransformation($primitiveTransformation)
->setInfoTypes($infoTypes);
$infoTypeTransformations = (new InfoTypeTransformations())
->setTransformations([$infoTypeTransformation]);
// Specify the config for the de-identify request
$deidentifyConfig = (new DeidentifyConfig())
->setInfoTypeTransformations($infoTypeTransformations);
// Send the request and receive response from the service.
$deidentifyContentRequest = (new DeidentifyContentRequest())
->setParent($parent)
->setInspectConfig($inspectConfig)
->setDeidentifyConfig($deidentifyConfig)
->setItem($content);
$response = $dlp->deidentifyContent($deidentifyContentRequest);
// Print the results.
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf('Table after deidentify (File Location): %s', $outputCsvFile);
}
from typing import Dict, List, Union
import google.cloud.dlp
def deidentify_table_with_crypto_hash(
project: str,
table_data: Dict[str, Union[List[str], List[List[str]]]],
info_types: List[str],
transient_key_name: str,
) -> None:
"""Uses the Data Loss Prevention API to de-identify sensitive data
in a table using a cryptographic hash transformation.
Args:
project: The Google Cloud project id to use as a parent resource.
table_data: Dictionary representing table data.
info_types: A list of strings representing info types to look for.
A full list of info type categories can be fetched from the API.
transient_key_name: Name of the transient crypto key used for encryption.
The scope of this key is a single API call. It is generated for
the transformation and then discarded.
"""
# Instantiate a client
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_data["header"]]
rows = []
for row in table_data["rows"]:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Construct the `item` that service will de-identify.
item = {"table": table}
# Prepare info_types by converting the list of strings into a list of
# dictionaries.
info_types = [{"name": info_type} for info_type in info_types]
# Construct cryptographic hash configuration using the transient key
# which will encrypt the data.
crypto_hash_config = {"crypto_key": {"transient": {"name": transient_key_name}}}
# Specify the type of info the inspection will look for.
inspect_config = {
"info_types": info_types,
}
# Construct deidentify configuration dictionary.
deidentify_config = {
"info_type_transformations": {
"transformations": [
{
"info_types": info_types,
"primitive_transformation": {
"crypto_hash_config": crypto_hash_config
},
}
]
}
}
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Call the API.
response = dlp.deidentify_content(
request={
"parent": parent,
"deidentify_config": deidentify_config,
"inspect_config": inspect_config,
"item": item,
}
)
# Print the result.
print(f"Table after de-identification: {response.item.table}")
Transform findings using two separate cryptographic hash transformations
This example demonstrates how you can use different cryptographic keys in
different transformations within a single de-identification configuration.
First, a field transformation on the "userid" field is declared. That
transformation does not include any infoType transformations, so the "userid"
field in each row is transformed, regardless of its data type. Then, another
field transformation is declared, this one on the "comments" field.
Input:
userid
comments
user1@example.org
my email is user1@example.org and phone is 858-555-0222
abbyabernathy1
my userid is abbyabernathy1 and my email is aabernathy@example.com
Transformed table:
userid
comments
5WvS4+aJtCCwWWG79cmRNamDgyvJ+CkuwNpA2gaR1VQ=
my email is vjqGLaA6+NUUnZAWXpI72lU1GfwQdOKu7XqWaJPcvQQ= and phone is BY+mSXXTu6mOoX5pr0Xbse60uelsSHmwRCq6HcscKtk=
t0dOmHvkT0VsM++SVmESVKHenLkmhBmFezH3hSDldDg=
my userid is abbyabernathy1 and my email is TQ3ancdUn9zgwO5qe6ahkmVrBuNhvlMknxjPjIt0N2w=
using System;
using System.Collections.Generic;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
public class DeidentifyTableWithMultipleCryptoHash
{
public static Table Deidentify(
string projectId,
Table tableToDeidentify = null,
IEnumerable<InfoType> infoTypes = null,
string transientKeyName1 = null,
string transientKeyName2 = null)
{
// Instantiate the client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
if (tableToDeidentify == null)
{
var row1 = new Value[]
{
new Value { StringValue = "user1@example.org" },
new Value { StringValue = "my email is user1@example.org and phone is 858-555-0222" }
};
var row2 = new Value[]
{
new Value { StringValue = "user2@example.org" },
new Value { StringValue = "my email is user2@example.org and phone is 858-555-0223" }
};
var row3 = new Value[]
{
new Value { StringValue = "user3@example.org" },
new Value { StringValue = "my email is user3@example.org and phone is 858-555-0224" }
};
tableToDeidentify = new Table
{
Headers =
{
new FieldId { Name = "User ID" },
new FieldId { Name = "comments" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } },
new Table.Types.Row { Values = { row3 } }
}
};
}
// Specify the table and construct the content item.
var contentItem = new ContentItem { Table = tableToDeidentify };
// Construct the crypto hash config for primitive transformation using
// transient crypto key name.
var cryptoHashConfig1 = new CryptoHashConfig
{
CryptoKey = new CryptoKey
{
Transient = new TransientCryptoKey
{
Name = transientKeyName1 ?? "[TRANSIENT-CRYPTO-KEY-1]"
}
}
};
// Construct the crypto hash config for infoType transformation using
// transient crypto key name.
var cryptoHashConfig2 = new CryptoHashConfig
{
CryptoKey = new CryptoKey
{
Transient = new TransientCryptoKey
{
Name = transientKeyName2 ?? "[TRANSIENT-CRYPTO-KEY-2]"
}
}
};
// Construct the infoTypes by specifying the type of info to be inspected if null.
var infotypes = infoTypes ?? new InfoType[]
{
new InfoType { Name = "EMAIL_ADDRESS" },
new InfoType { Name = "PERSON_NAME" }
};
// Construct the deidentify config using crypto hash configs.
var deidentifyConfig = new DeidentifyConfig
{
RecordTransformations = new RecordTransformations
{
FieldTransformations =
{
new FieldTransformation
{
Fields = { new FieldId[] { new FieldId { Name = "User ID" } } },
PrimitiveTransformation = new PrimitiveTransformation
{
CryptoHashConfig = cryptoHashConfig1
}
},
new FieldTransformation
{
Fields = { new FieldId[] { new FieldId { Name = "comments" } } },
InfoTypeTransformations = new InfoTypeTransformations
{
Transformations =
{
new InfoTypeTransformations.Types.InfoTypeTransformation
{
PrimitiveTransformation = new PrimitiveTransformation
{
CryptoHashConfig = cryptoHashConfig2
},
InfoTypes = { infotypes }
}
}
}
}
}
}
};
// Construct the inspect config.
var inspectConfig = new InspectConfig
{
InfoTypes = { infotypes },
IncludeQuote = true
};
// Construct the request.
var request = new DeidentifyContentRequest
{
ParentAsLocationName = new LocationName(projectId, "global"),
DeidentifyConfig = deidentifyConfig,
Item = contentItem,
InspectConfig = inspectConfig
};
// Call the API.
var response = dlp.DeidentifyContent(request);
// Print the table.
Console.WriteLine(response.Item.Table);
return response.Item.Table;
}
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.CryptoHashConfig;
import com.google.privacy.dlp.v2.CryptoKey;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.FieldTransformation;
import com.google.privacy.dlp.v2.InfoType;
import com.google.privacy.dlp.v2.InfoTypeTransformations;
import com.google.privacy.dlp.v2.InspectConfig;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.TransientCryptoKey;
import com.google.privacy.dlp.v2.Value;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DeIdentifyTableWithMultipleCryptoHash {
public static void main(String[] args) throws Exception {
// TODO(developer): Replace these variables before running the sample.
// The Google Cloud project id to use as a parent resource.
String projectId = "your-project-id";
// The table to de-identify.
Table tableToDeIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("userid").build())
.addHeaders(FieldId.newBuilder().setName("comments").build())
.addRows(
Table.Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("user1@example.org").build())
.addValues(
Value.newBuilder()
.setStringValue(
"my email is user1@example.org and phone is 858-555-0222")
.build())
.build())
.addRows(
Table.Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("user2@example.org").build())
.addValues(
Value.newBuilder()
.setStringValue(
"my email is user2@example.org and phone is 858-555-0223")
.build())
.build())
.addRows(
Table.Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("user3@example.org").build())
.addValues(
Value.newBuilder()
.setStringValue(
"my email is user3@example.org and phone is 858-555-0224")
.build())
.build())
.build();
// The names of the keys used to encrypt the data.
String transientKeyName1 = "YOUR_TRANSIENT_CRYPTO_KEY";
String transientKeyName2 = "YOUR_TRANSIENT_CRYPTO_KEY_2";
deIdentifyWithCryptHashTransformation(
projectId, tableToDeIdentify, transientKeyName1, transientKeyName2);
}
// Transforms findings using two separate cryptographic hash transformations.
public static void deIdentifyWithCryptHashTransformation(
String projectId, Table tableToDeIdentify, String transientKeyName1, String transientKeyName2)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to DeIdentify
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToDeIdentify).build();
// Specify the type of info the inspection will look for.
// See https://cloud.google.com/dlp/docs/infotypes-reference for complete list of info types
List<InfoType> infoTypes =
Stream.of("PHONE_NUMBER", "EMAIL_ADDRESS")
.map(it -> InfoType.newBuilder().setName(it).build())
.collect(Collectors.toList());
InspectConfig inspectConfig = InspectConfig.newBuilder()
.addAllInfoTypes(infoTypes)
.build();
// Specify the transient key which will encrypt the data.
TransientCryptoKey transientCryptoKey = TransientCryptoKey.newBuilder()
.setName(transientKeyName1)
.build();
TransientCryptoKey transientCryptoKey2 = TransientCryptoKey.newBuilder()
.setName(transientKeyName2)
.build();
CryptoKey cryptoKey = CryptoKey.newBuilder()
.setTransient(transientCryptoKey)
.build();
CryptoKey cryptoKey2 = CryptoKey.newBuilder()
.setTransient(transientCryptoKey2)
.build();
CryptoHashConfig cryptoHashConfig = CryptoHashConfig.newBuilder()
.setCryptoKey(cryptoKey)
.build();
CryptoHashConfig cryptoHashConfig2 = CryptoHashConfig.newBuilder()
.setCryptoKey(cryptoKey2)
.build();
// Define type of de-identification as cryptographic hash transformation.
PrimitiveTransformation primitiveTransformation = PrimitiveTransformation.newBuilder()
.setCryptoHashConfig(cryptoHashConfig)
.build();
PrimitiveTransformation primitiveTransformation2 = PrimitiveTransformation.newBuilder()
.setCryptoHashConfig(cryptoHashConfig2)
.build();
InfoTypeTransformations.InfoTypeTransformation infoTypeTransformation =
InfoTypeTransformations.InfoTypeTransformation.newBuilder()
.setPrimitiveTransformation(primitiveTransformation2)
.addAllInfoTypes(infoTypes)
.build();
InfoTypeTransformations transformations =
InfoTypeTransformations.newBuilder().addTransformations(infoTypeTransformation).build();
// Specify fields to be de-identified.
List<FieldId> fieldIds =
Stream.of("userid")
.map(id -> FieldId.newBuilder().setName(id).build())
.collect(Collectors.toList());
List<FieldId> fieldIds1 =
Stream.of("comments")
.map(id -> FieldId.newBuilder().setName(id).build())
.collect(Collectors.toList());
List<FieldTransformation> fieldTransformations = new ArrayList<>();
fieldTransformations.add(
FieldTransformation.newBuilder()
.addAllFields(fieldIds)
.setPrimitiveTransformation(primitiveTransformation)
.build());
fieldTransformations.add(
FieldTransformation.newBuilder()
.addAllFields(fieldIds1)
.setInfoTypeTransformations(transformations)
.build());
RecordTransformations recordTransformations = RecordTransformations.newBuilder()
.addAllFieldTransformations(fieldTransformations)
.build();
// Specify the config for the de-identify request
DeidentifyConfig deidentifyConfig = DeidentifyConfig.newBuilder()
.setRecordTransformations(recordTransformations)
.build();
// Combine configurations into a request for the service.
DeidentifyContentRequest request =
DeidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setInspectConfig(inspectConfig)
.setDeidentifyConfig(deidentifyConfig)
.build();
// Send the request and receive response from the service.
DeidentifyContentResponse response = dlp.deidentifyContent(request);
// Print the results.
System.out.println("Table after de-identification: " + response.getItem().getTable());
}
}
}
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\CryptoHashConfig;
use Google\Cloud\Dlp\V2\CryptoKey;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\FieldTransformation;
use Google\Cloud\Dlp\V2\InfoType;
use Google\Cloud\Dlp\V2\InfoTypeTransformations;
use Google\Cloud\Dlp\V2\InfoTypeTransformations\InfoTypeTransformation;
use Google\Cloud\Dlp\V2\InspectConfig;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\TransientCryptoKey;
use Google\Cloud\Dlp\V2\Value;
/**
* De-identify table data with multiple crypto hash.
* Transform findings using two separate cryptographic hash transformations.
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to deidentify.
* @param string $outputCsvFile The oupt file path to save deidentify content.
* @param string $transientCryptoKeyName1 Specify the random string.
* @param string $transientCryptoKeyName2 Specify the random string.
*/
function deidentify_table_with_multiple_crypto_hash(
// TODO(developer): Replace sample parameters before running the code.
string $callingProjectId,
string $inputCsvFile = './test/data/table6.csv',
string $outputCsvFile = './test/data/deidentify_table_with_multiple_crypto_hash_output.csv',
string $transientCryptoKeyName1 = 'YOUR-TRANSIENT-CRYPTO-KEY-1',
string $transientCryptoKeyName2 = 'YOUR-TRANSIENT-CRYPTO-KEY-2'
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
$parent = "projects/$callingProjectId/locations/global";
// Read a CSV file.
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects.
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object.
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify what content you want the service to de-identify.
$content = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify the type of info the inspection will look for.
// See https://cloud.google.com/dlp/docs/infotypes-reference for complete list of info types
$infoTypes = [
(new InfoType())->setName('EMAIL_ADDRESS'),
(new InfoType())->setName('PHONE_NUMBER')
];
$inspectConfig = (new InspectConfig())
->setInfoTypes($infoTypes);
// ---- First Crypto Hash Rule ----
// Specify the transient key which will encrypt the data.
$cryptoHashConfig1 = (new CryptoHashConfig())
->setCryptoKey((new CryptoKey())
->setTransient((new TransientCryptoKey())
->setName($transientCryptoKeyName1)));
// Define type of de-identification as cryptographic hash transformation.
$primitiveTransformation1 = (new PrimitiveTransformation())
->setCryptoHashConfig($cryptoHashConfig1);
$fieldTransformation1 = (new FieldTransformation())
->setPrimitiveTransformation($primitiveTransformation1)
// Specify fields to be de-identified.
->setFields([
(new FieldId())->setName('userid')
]);
// ---- Second Crypto Hash Rule ----
// Specify the transient key which will encrypt the data.
$cryptoHashConfig2 = (new CryptoHashConfig())
->setCryptoKey((new CryptoKey())
->setTransient((new TransientCryptoKey())
->setName($transientCryptoKeyName2)));
// Define type of de-identification as cryptographic hash transformation.
$primitiveTransformation2 = (new PrimitiveTransformation())
->setCryptoHashConfig($cryptoHashConfig2);
$infoTypeTransformation = (new InfoTypeTransformation())
->setPrimitiveTransformation($primitiveTransformation2)
->setInfoTypes($infoTypes);
$infoTypeTransformations = (new InfoTypeTransformations())
->setTransformations([$infoTypeTransformation]);
$fieldTransformation2 = (new FieldTransformation())
->setInfoTypeTransformations($infoTypeTransformations)
// Specify fields to be de-identified.
->setFields([
(new FieldId())->setName('comments')
]);
$recordtransformations = (new RecordTransformations())
->setFieldTransformations([$fieldTransformation1, $fieldTransformation2]);
// Specify the config for the de-identify request
$deidentifyConfig = (new DeidentifyConfig())
->setRecordTransformations($recordtransformations);
// Send the request and receive response from the service.
$deidentifyContentRequest = (new DeidentifyContentRequest())
->setParent($parent)
->setInspectConfig($inspectConfig)
->setDeidentifyConfig($deidentifyConfig)
->setItem($content);
$response = $dlp->deidentifyContent($deidentifyContentRequest);
// Print the results.
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf('Table after deidentify (File Location): %s', $outputCsvFile);
}
from typing import Dict, List, Union
import google.cloud.dlp
def deidentify_table_with_multiple_crypto_hash(
project: str,
table_data: Dict[str, Union[List[str], List[List[str]]]],
info_types: List[str],
transient_key_name_1: str,
transient_key_name_2: str,
deid_fields_1: List[str],
deid_fields_2: List[str],
) -> None:
"""Uses the Data Loss Prevention API to de-identify sensitive data
in table using multiple transient cryptographic hash keys.
Args:
project: The Google Cloud project id to use as a parent resource.
table_data: Dictionary representing table data.
info_types: A list of strings representing info types to look for.
A full list of info type categories can be fetched from the API.
transient_key_name_1: Name of the first transient crypto key used
for encryption. The scope of this key is a single API call.
It is generated for the transformation and then discarded.
transient_key_name_2: Name of the second transient crypto key used
for encryption. The scope of this key is a single API call.
It is generated for the transformation and then discarded.
deid_fields_1: List of column names in table to de-identify using
transient_key_name_1.
deid_fields_2: List of column names in table to de-identify using
transient_key_name_2.
"""
# Instantiate a client
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_data["header"]]
rows = []
for row in table_data["rows"]:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Construct the `item`
item = {"table": table}
# Prepare info_types by converting the list of strings into a list of
# dictionaries.
info_types = [{"name": info_type} for info_type in info_types]
# Construct cryptographic hash configurations using two transient keys
# which will encrypt the data.
crypto_hash_config_1 = {"crypto_key": {"transient": {"name": transient_key_name_1}}}
crypto_hash_config_2 = {"crypto_key": {"transient": {"name": transient_key_name_2}}}
# Prepare fields to be de-identified by converting list of strings
# into list of dictionaries.
deid_fields_1 = [{"name": field} for field in deid_fields_1]
deid_fields_2 = [{"name": field} for field in deid_fields_2]
# Specify the type of info the inspection will look for.
inspect_config = {
"info_types": info_types,
}
# Construct deidentify configuration dictionary.
deidentify_config = {
"record_transformations": {
"field_transformations": [
{
"fields": deid_fields_1,
"primitive_transformation": {
"crypto_hash_config": crypto_hash_config_1
},
},
{
"fields": deid_fields_2,
"info_type_transformations": {
"transformations": [
{
"info_types": info_types,
"primitive_transformation": {
"crypto_hash_config": crypto_hash_config_2
},
}
]
},
},
]
}
}
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Call the API.
response = dlp.deidentify_content(
request={
"parent": parent,
"deidentify_config": deidentify_config,
"inspect_config": inspect_config,
"item": item,
}
)
# Print the result.
print(f"Table after de-identification: {response.item.table}")
Transform findings using format-preserving encryption
This example demonstrates how to use
Sensitive Data Protection to replace a sensitive string with a token that has the
same length and alphabet as the original string. This example uses the
CryptoReplaceFfxFpeConfig
transformation method. For more information, see Format-preserving
encryption.
using System;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
using Google.Protobuf;
using static Google.Cloud.Dlp.V2.CryptoReplaceFfxFpeConfig.Types;
public class DeidentifyTableWithFpe
{
public static Table DeidentifyTable(
string projectId,
string keyName,
string wrappedKey,
FfxCommonNativeAlphabet alphabet = FfxCommonNativeAlphabet.Numeric,
Table tableToInspect = null)
{
// Instantiate a client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
if (tableToInspect == null)
{
var row1 = new Value[]
{
new Value { StringValue = "11111" },
new Value { StringValue = "2015" },
new Value { StringValue = "$10" }
};
var row2 = new Value[]
{
new Value { StringValue = "33333" },
new Value { StringValue = "2016" },
new Value { StringValue = "$20" }
};
var row3 = new Value[]
{
new Value { StringValue = "22222" },
new Value { StringValue = "2016" },
new Value { StringValue = "$15" }
};
tableToInspect = new Table
{
Headers =
{
new FieldId { Name = "Employee ID" },
new FieldId { Name = "Date" },
new FieldId { Name = "Compensation" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } },
new Table.Types.Row { Values = { row3 } }
}
};
}
// Provide the table and construct the content item.
var contentItem = new ContentItem { Table = tableToInspect };
// Specify an encrypted AES-256 key and the name of the Cloud KMS Key that
// encrypted it and specify how it should be encrypted.
var cryptoReplaceFfxFpeConfig = new CryptoReplaceFfxFpeConfig
{
CryptoKey = new CryptoKey
{
KmsWrapped = new KmsWrappedCryptoKey
{
CryptoKeyName = keyName,
WrappedKey = ByteString.FromBase64(wrappedKey)
}
},
CommonAlphabet = alphabet
};
// Specify fields to be encrypted.
var fields = new FieldId[] { new FieldId { Name = "Employee ID" } };
// Construct the deidentify config using crypto replace config created above.
var deidentifyConfig = new DeidentifyConfig
{
RecordTransformations = new RecordTransformations
{
FieldTransformations =
{
new FieldTransformation
{
PrimitiveTransformation = new PrimitiveTransformation
{
CryptoReplaceFfxFpeConfig = cryptoReplaceFfxFpeConfig
},
Fields = { fields }
}
}
}
};
// Construct the request.
var request = new DeidentifyContentRequest
{
ParentAsLocationName = new LocationName(projectId, "global"),
DeidentifyConfig = deidentifyConfig,
Item = contentItem,
};
// Call the API.
DeidentifyContentResponse response = dlp.DeidentifyContent(request);
// Inspect the response.
Console.WriteLine(response.Item.Table);
return response.Item.Table;
}
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.common.io.BaseEncoding;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.CryptoKey;
import com.google.privacy.dlp.v2.CryptoReplaceFfxFpeConfig;
import com.google.privacy.dlp.v2.CryptoReplaceFfxFpeConfig.FfxCommonNativeAlphabet;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.DeidentifyContentRequest;
import com.google.privacy.dlp.v2.DeidentifyContentResponse;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.FieldTransformation;
import com.google.privacy.dlp.v2.KmsWrappedCryptoKey;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.Table.Row;
import com.google.privacy.dlp.v2.Value;
import com.google.protobuf.ByteString;
import java.io.IOException;
public class DeIdentifyTableWithFpe {
public static void main(String[] args) throws Exception {
// TODO(developer): Replace these variables before running the sample.
String projectId = "your-project-id";
String kmsKeyName =
"projects/YOUR_PROJECT/"
+ "locations/YOUR_KEYRING_REGION/"
+ "keyRings/YOUR_KEYRING_NAME/"
+ "cryptoKeys/YOUR_KEY_NAME";
String wrappedAesKey = "YOUR_ENCRYPTED_AES_256_KEY";
Table tableToDeIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("Employee ID").build())
.addHeaders(FieldId.newBuilder().setName("Date").build())
.addHeaders(FieldId.newBuilder().setName("Compensation").build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("11111").build())
.addValues(Value.newBuilder().setStringValue("2015").build())
.addValues(Value.newBuilder().setStringValue("$10").build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("22222").build())
.addValues(Value.newBuilder().setStringValue("2016").build())
.addValues(Value.newBuilder().setStringValue("$20").build())
.build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("33333").build())
.addValues(Value.newBuilder().setStringValue("2016").build())
.addValues(Value.newBuilder().setStringValue("$15").build())
.build())
.build();
deIdentifyTableWithFpe(projectId, tableToDeIdentify, kmsKeyName, wrappedAesKey);
}
public static void deIdentifyTableWithFpe(
String projectId, Table tableToDeIdentify, String kmsKeyName, String wrappedAesKey)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to de-identify.
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToDeIdentify).build();
// Specify an encrypted AES-256 key and the name of the Cloud KMS key that encrypted it
KmsWrappedCryptoKey kmsWrappedCryptoKey =
KmsWrappedCryptoKey.newBuilder()
.setWrappedKey(ByteString.copyFrom(BaseEncoding.base64().decode(wrappedAesKey)))
.setCryptoKeyName(kmsKeyName)
.build();
CryptoKey cryptoKey = CryptoKey.newBuilder().setKmsWrapped(kmsWrappedCryptoKey).build();
// Specify how the content should be encrypted.
CryptoReplaceFfxFpeConfig cryptoReplaceFfxFpeConfig =
CryptoReplaceFfxFpeConfig.newBuilder()
.setCryptoKey(cryptoKey)
// Set of characters in the input text. For more info, see
// https://cloud.google.com/dlp/docs/reference/rest/v2/organizations.deidentifyTemplates#DeidentifyTemplate.FfxCommonNativeAlphabet
.setCommonAlphabet(FfxCommonNativeAlphabet.NUMERIC)
.build();
PrimitiveTransformation primitiveTransformation =
PrimitiveTransformation.newBuilder()
.setCryptoReplaceFfxFpeConfig(cryptoReplaceFfxFpeConfig)
.build();
// Specify field to be encrypted.
FieldId fieldId = FieldId.newBuilder().setName("Employee ID").build();
// Associate the encryption with the specified field.
FieldTransformation fieldTransformation =
FieldTransformation.newBuilder()
.setPrimitiveTransformation(primitiveTransformation)
.addFields(fieldId)
.build();
RecordTransformations transformations =
RecordTransformations.newBuilder().addFieldTransformations(fieldTransformation).build();
DeidentifyConfig deidentifyConfig =
DeidentifyConfig.newBuilder().setRecordTransformations(transformations).build();
// Combine configurations into a request for the service.
DeidentifyContentRequest request =
DeidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setDeidentifyConfig(deidentifyConfig)
.build();
// Send the request and receive response from the service.
DeidentifyContentResponse response = dlp.deidentifyContent(request);
// Print the results.
System.out.println(
"Table after format-preserving encryption: " + response.getItem().getTable());
}
}
}
// Imports the Google Cloud Data Loss Prevention library
const DLP = require('@google-cloud/dlp');
// Instantiates a client
const dlp = new DLP.DlpServiceClient();
// The project ID to run the API call under
// const projectId = 'my-project';
// The set of characters to replace sensitive ones with
// For more information, see https://cloud.google.com/dlp/docs/reference/rest/v2/organizations.deidentifyTemplates#ffxcommonnativealphabet
// const alphabet = 'NUMERIC';
// The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key
// const keyName = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME';
// The encrypted ('wrapped') AES-256 key to use
// This key should be encrypted using the Cloud KMS key specified above
// const wrappedKey = 'YOUR_ENCRYPTED_AES_256_KEY'
// Table to de-identify
const tablularData = {
headers: [{name: 'Employee ID'}, {name: 'Date'}, {name: 'Compensation'}],
rows: [
{
values: [
{stringValue: '11111'},
{stringValue: '2015'},
{stringValue: '$10'},
],
},
{
values: [
{stringValue: '22222'},
{stringValue: '2016'},
{stringValue: '$20'},
],
},
{
values: [
{stringValue: '33333'},
{stringValue: '2016'},
{stringValue: '$15'},
],
},
],
};
async function deidentifyTableWithFpe() {
// Specify field to be encrypted.
const fieldIds = [{name: 'Employee ID'}];
// Specify an encrypted AES-256 key and the name of the Cloud KMS key that encrypted it
const cryptoKeyConfig = {
kmsWrapped: {
wrappedKey: wrappedKey,
cryptoKeyName: keyName,
},
};
// Specify how the content should be encrypted.
const cryptoReplaceFfxFpeConfig = {
cryptoKey: cryptoKeyConfig,
commonAlphabet: alphabet,
};
// Associate the encryption with the specified field.
const fieldTransformations = [
{
fields: fieldIds,
primitiveTransformation: {
cryptoReplaceFfxFpeConfig,
},
},
];
// Combine configurations into a request for the service.
const request = {
parent: `projects/${projectId}/locations/global`,
deidentifyConfig: {
recordTransformations: {
fieldTransformations,
},
},
item: {
table: tablularData,
},
};
// Send the request and receive response from the service.
const [response] = await dlp.deidentifyContent(request);
// Print the results.
console.log(
`Table after de-identification: ${JSON.stringify(response.item.table)}`
);
}
await deidentifyTableWithFpe();
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\CryptoKey;
use Google\Cloud\Dlp\V2\CryptoReplaceFfxFpeConfig;
use Google\Cloud\Dlp\V2\CryptoReplaceFfxFpeConfig\FfxCommonNativeAlphabet;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\DeidentifyContentRequest;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\FieldTransformation;
use Google\Cloud\Dlp\V2\KmsWrappedCryptoKey;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\Value;
/**
* De-identify table data with format-preserving encryption.
* Demonstrates encrypting sensitive data in a table while maintaining format.
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to deidentify.
* @param string $outputCsvFile The oupt file path to save deidentify content.
* @param string $encryptedFieldNames The field to be encrypted.
* @param string $kmsKeyName The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key.
* Example: key_name = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'
* @param string $wrappedAesKey The encrypted ('wrapped') AES-256 key to use.
* */
function deidentify_table_fpe(
string $callingProjectId,
string $inputCsvFile,
string $outputCsvFile,
string $encryptedFieldNames,
string $kmsKeyName,
string $wrappedAesKey
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
$parent = "projects/$callingProjectId/locations/global";
// Read a CSV file.
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects.
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object.
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify the content to be de-identify.
$content = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify an encrypted AES-256 key and the name of the Cloud KMS key that encrypted it.
$kmsWrappedCryptoKey = (new KmsWrappedCryptoKey())
->setWrappedKey(base64_decode($wrappedAesKey))
->setCryptoKeyName($kmsKeyName);
$cryptoKey = (new CryptoKey())
->setKmsWrapped($kmsWrappedCryptoKey);
// Specify how the content should be encrypted.
$cryptoReplaceFfxFpeConfig = (new CryptoReplaceFfxFpeConfig())
->setCryptoKey($cryptoKey)
->setCommonAlphabet(FfxCommonNativeAlphabet::NUMERIC);
$primitiveTransformation = (new PrimitiveTransformation())
->setCryptoReplaceFfxFpeConfig($cryptoReplaceFfxFpeConfig);
// Specify field to be encrypted.
$encryptedFields = array_map(function ($encryptedFieldName) {
return (new FieldId())
->setName($encryptedFieldName);
}, explode(',', $encryptedFieldNames));
// Associate the encryption with the specified field.
$fieldTransformation = (new FieldTransformation())
->setPrimitiveTransformation($primitiveTransformation)
->setFields($encryptedFields);
$recordtransformations = (new RecordTransformations())
->setFieldTransformations([$fieldTransformation]);
$deidentifyConfig = (new DeidentifyConfig())
->setRecordTransformations($recordtransformations);
// Run request.
$deidentifyContentRequest = (new DeidentifyContentRequest())
->setParent($parent)
->setDeidentifyConfig($deidentifyConfig)
->setItem($content);
$response = $dlp->deidentifyContent($deidentifyContentRequest);
// Print the results.
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf('Table after format-preserving encryption (File Location): %s', $outputCsvFile);
}
from typing import List
import google.cloud.dlp
def deidentify_table_with_fpe(
project: str,
table_header: List[str],
table_rows: List[List[str]],
deid_field_names: List[str],
key_name: str = None,
wrapped_key: bytes = None,
alphabet: str = None,
) -> None:
"""Uses the Data Loss Prevention API to de-identify sensitive data in a
table while maintaining format.
Args:
project: The Google Cloud project id to use as a parent resource.
table_header: List of strings representing table field names.
table_rows: List of rows representing table data.
deid_field_names: A list of fields in table to de-identify.
key_name: The name of the Cloud KMS key used to encrypt ('wrap') the
AES-256 key. Example:
key_name = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/
keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'
wrapped_key: The decrypted ('wrapped', in bytes) AES-256 key to use. This key
should be encrypted using the Cloud KMS key specified by key_name.
alphabet: The set of characters to replace sensitive ones with. For
more information, see https://cloud.google.com/dlp/docs/reference/
rest/v2/projects.deidentifyTemplates#ffxcommonnativealphabet
"""
# Instantiate a client.
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_header]
rows = []
for row in table_rows:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Construct the `item` for table.
item = {"table": table}
# Specify fields to be de-identified.
deid_field_names = [{"name": _i} for _i in deid_field_names]
# Construct FPE configuration dictionary
crypto_replace_ffx_fpe_config = {
"crypto_key": {
"kms_wrapped": {"wrapped_key": wrapped_key, "crypto_key_name": key_name},
},
"common_alphabet": alphabet,
}
# Construct deidentify configuration dictionary
deidentify_config = {
"record_transformations": {
"field_transformations": [
{
"primitive_transformation": {
"crypto_replace_ffx_fpe_config": crypto_replace_ffx_fpe_config
},
"fields": deid_field_names,
}
]
}
}
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Call the API.
response = dlp.deidentify_content(
request={"parent": parent, "deidentify_config": deidentify_config, "item": item}
)
# Print out results.
print(f"Table after de-identification: {response.item.table}")
Re-identify findings de-identified using format-preserving encryption
This example demonstrates how to use
Sensitive Data Protection to re-identify sensitive data in tables that were
de-identified through the
CryptoReplaceFfxFpeConfig
transformation method. For more information, see Format-preserving
encryption.
using System;
using Google.Api.Gax.ResourceNames;
using Google.Cloud.Dlp.V2;
using Google.Protobuf;
using static Google.Cloud.Dlp.V2.CryptoReplaceFfxFpeConfig.Types;
public class ReidentifyTableDataWithFpe
{
public static Table ReidentifyTableData(
string projectId,
string keyName,
string wrappedKey,
FfxCommonNativeAlphabet alphabet = FfxCommonNativeAlphabet.Numeric,
Table tableToInspect = null)
{
// Instantiate a client.
var dlp = DlpServiceClient.Create();
// Construct the table if null.
var table = tableToInspect;
if (table == null)
{
var row1 = new Value[]
{
new Value { StringValue = "28777" },
new Value { StringValue = "Justin" }
};
var row2 = new Value[]
{
new Value { StringValue = "28778" },
new Value { StringValue = "Gary" }
};
table = new Table
{
Headers =
{
new FieldId { Name = "Employee ID" },
new FieldId { Name = "Employee Name" }
},
Rows =
{
new Table.Types.Row { Values = { row1 } },
new Table.Types.Row { Values = { row2 } }
}
};
}
// Construct the content item by providing the table.
var contentItem = new ContentItem { Table = table };
// Specify how to decrypt the previously de-identified information.
var cryptoReplaceFfxFpeConfig = new CryptoReplaceFfxFpeConfig
{
CryptoKey = new CryptoKey
{
KmsWrapped = new KmsWrappedCryptoKey
{
CryptoKeyName = keyName,
WrappedKey = ByteString.FromBase64(wrappedKey)
}
},
CommonAlphabet = alphabet
};
// Specify the field to be decrypted.
var fields = new FieldId[] { new FieldId { Name = "Employee ID" } };
// Construct the re-identify config and specify the transformation.
var reidentifyConfig = new DeidentifyConfig
{
RecordTransformations = new RecordTransformations
{
FieldTransformations =
{
new FieldTransformation
{
PrimitiveTransformation = new PrimitiveTransformation
{
CryptoReplaceFfxFpeConfig = cryptoReplaceFfxFpeConfig,
},
Fields = { fields }
}
}
}
};
// Construct the request.
var request = new ReidentifyContentRequest
{
Parent = new LocationName(projectId, "global").ToString(),
Item = contentItem,
ReidentifyConfig = reidentifyConfig
};
// Call the API.
ReidentifyContentResponse response = dlp.ReidentifyContent(request);
// Inspect the response.
Console.WriteLine($"Table after re-identification: {response.Item.Table}");
return response.Item.Table;
}
}
import com.google.cloud.dlp.v2.DlpServiceClient;
import com.google.common.io.BaseEncoding;
import com.google.privacy.dlp.v2.ContentItem;
import com.google.privacy.dlp.v2.CryptoKey;
import com.google.privacy.dlp.v2.CryptoReplaceFfxFpeConfig;
import com.google.privacy.dlp.v2.CryptoReplaceFfxFpeConfig.FfxCommonNativeAlphabet;
import com.google.privacy.dlp.v2.DeidentifyConfig;
import com.google.privacy.dlp.v2.FieldId;
import com.google.privacy.dlp.v2.FieldTransformation;
import com.google.privacy.dlp.v2.KmsWrappedCryptoKey;
import com.google.privacy.dlp.v2.LocationName;
import com.google.privacy.dlp.v2.PrimitiveTransformation;
import com.google.privacy.dlp.v2.RecordTransformations;
import com.google.privacy.dlp.v2.ReidentifyContentRequest;
import com.google.privacy.dlp.v2.ReidentifyContentResponse;
import com.google.privacy.dlp.v2.Table;
import com.google.privacy.dlp.v2.Table.Row;
import com.google.privacy.dlp.v2.Value;
import com.google.protobuf.ByteString;
import java.io.IOException;
public class ReIdentifyTableWithFpe {
public static void main(String[] args) throws Exception {
// TODO(developer): Replace these variables before running the sample.
String projectId = "your-project-id";
String kmsKeyName =
"projects/YOUR_PROJECT/"
+ "locations/YOUR_KEYRING_REGION/"
+ "keyRings/YOUR_KEYRING_NAME/"
+ "cryptoKeys/YOUR_KEY_NAME";
String wrappedAesKey = "YOUR_ENCRYPTED_AES_256_KEY";
Table tableToReIdentify =
Table.newBuilder()
.addHeaders(FieldId.newBuilder().setName("Employee ID").build())
.addRows(
Row.newBuilder()
.addValues(Value.newBuilder().setStringValue("28777").build())
.build())
.build();
reIdentifyTableWithFpe(projectId, tableToReIdentify, kmsKeyName, wrappedAesKey);
}
public static void reIdentifyTableWithFpe(
String projectId, Table tableToReIdentify, String kmsKeyName, String wrappedAesKey)
throws IOException {
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests. After completing all of your requests, call
// the "close" method on the client to safely clean up any remaining background resources.
try (DlpServiceClient dlp = DlpServiceClient.create()) {
// Specify what content you want the service to re-identify.
ContentItem contentItem = ContentItem.newBuilder().setTable(tableToReIdentify).build();
// Specify an encrypted AES-256 key and the name of the Cloud KMS key that encrypted it.
KmsWrappedCryptoKey kmsWrappedCryptoKey =
KmsWrappedCryptoKey.newBuilder()
.setWrappedKey(ByteString.copyFrom(BaseEncoding.base64().decode(wrappedAesKey)))
.setCryptoKeyName(kmsKeyName)
.build();
CryptoKey cryptoKey = CryptoKey.newBuilder().setKmsWrapped(kmsWrappedCryptoKey).build();
// Specify how to un-encrypt the previously de-identified information.
CryptoReplaceFfxFpeConfig cryptoReplaceFfxFpeConfig =
CryptoReplaceFfxFpeConfig.newBuilder()
.setCryptoKey(cryptoKey)
// Set of characters in the input text. For more info, see
// https://cloud.google.com/dlp/docs/reference/rest/v2/organizations.deidentifyTemplates#DeidentifyTemplate.FfxCommonNativeAlphabet
.setCommonAlphabet(FfxCommonNativeAlphabet.NUMERIC)
.build();
PrimitiveTransformation primitiveTransformation =
PrimitiveTransformation.newBuilder()
.setCryptoReplaceFfxFpeConfig(cryptoReplaceFfxFpeConfig)
.build();
// Specify field to be decrypted.
FieldId fieldId = FieldId.newBuilder().setName("Employee ID").build();
// Associate the decryption with the specified field.
FieldTransformation fieldTransformation =
FieldTransformation.newBuilder()
.setPrimitiveTransformation(primitiveTransformation)
.addFields(fieldId)
.build();
RecordTransformations transformations =
RecordTransformations.newBuilder().addFieldTransformations(fieldTransformation).build();
DeidentifyConfig reidentifyConfig =
DeidentifyConfig.newBuilder().setRecordTransformations(transformations).build();
// Combine configurations into a request for the service.
ReidentifyContentRequest request =
ReidentifyContentRequest.newBuilder()
.setParent(LocationName.of(projectId, "global").toString())
.setItem(contentItem)
.setReidentifyConfig(reidentifyConfig)
.build();
// Send the request and receive response from the service
ReidentifyContentResponse response = dlp.reidentifyContent(request);
// Print the results
System.out.println("Table after re-identification: " + response.getItem().getValue());
}
}
}
// Imports the Google Cloud Data Loss Prevention library
const DLP = require('@google-cloud/dlp');
// Instantiates a client
const dlp = new DLP.DlpServiceClient();
// The project ID to run the API call under
// const projectId = 'my-project';
// The set of characters to replace sensitive ones with
// For more information, see https://cloud.google.com/dlp/docs/reference/rest/v2/organizations.deidentifyTemplates#ffxcommonnativealphabet
// const alphabet = 'ALPHA_NUMERIC';
// The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key
// const keyName = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME';
// The encrypted ('wrapped') AES-256 key to use
// This key should be encrypted using the Cloud KMS key specified above
// const wrappedKey = 'YOUR_ENCRYPTED_AES_256_KEY'
// The name of the surrogate custom info type to use when reidentifying data
// const surrogateType = 'SOME_INFO_TYPE_DEID';
// Table to re-identify
const tablularData = {
headers: [{name: 'Employee ID'}],
rows: [{values: [{stringValue: '90511'}]}],
};
async function reidentifyTableWithFpe() {
// Specify field to be re-identified.
const fieldIds = [{name: 'Employee ID'}];
// Specify an encrypted AES-256 key and the name of the Cloud KMS key that encrypted it
const cryptoKeyConfig = {
kmsWrapped: {
wrappedKey: wrappedKey,
cryptoKeyName: keyName,
},
};
// Associate transformation with crypto key congurations.
const primitiveTransformation = {
cryptoReplaceFfxFpeConfig: {
cryptoKey: cryptoKeyConfig,
commonAlphabet: alphabet,
},
};
// Combine configurations into a request for the service.
const request = {
parent: `projects/${projectId}/locations/global`,
reidentifyConfig: {
recordTransformations: {
fieldTransformations: [
{
fields: fieldIds,
primitiveTransformation: primitiveTransformation,
},
],
},
},
item: {
table: tablularData,
},
};
// Send the request and receive response from the service.
const [response] = await dlp.reidentifyContent(request);
// Print the results.
console.log(
`Table after re-identification: ${JSON.stringify(response.item.table)}`
);
}
await reidentifyTableWithFpe();
use Google\Cloud\Dlp\V2\Client\DlpServiceClient;
use Google\Cloud\Dlp\V2\ContentItem;
use Google\Cloud\Dlp\V2\CryptoKey;
use Google\Cloud\Dlp\V2\CryptoReplaceFfxFpeConfig;
use Google\Cloud\Dlp\V2\CryptoReplaceFfxFpeConfig\FfxCommonNativeAlphabet;
use Google\Cloud\Dlp\V2\DeidentifyConfig;
use Google\Cloud\Dlp\V2\FieldId;
use Google\Cloud\Dlp\V2\FieldTransformation;
use Google\Cloud\Dlp\V2\KmsWrappedCryptoKey;
use Google\Cloud\Dlp\V2\PrimitiveTransformation;
use Google\Cloud\Dlp\V2\RecordTransformations;
use Google\Cloud\Dlp\V2\ReidentifyContentRequest;
use Google\Cloud\Dlp\V2\Table;
use Google\Cloud\Dlp\V2\Table\Row;
use Google\Cloud\Dlp\V2\Value;
/**
* Re-identify table data with FPE.
*
* @param string $callingProjectId The Google Cloud project id to use as a parent resource.
* @param string $inputCsvFile The input file(csv) path to reidentify.
* @param string $outputCsvFile The oupt file path to save reidentify content.
* @param string $encryptedFieldNames The field to be encrypted.
* @param string $kmsKeyName The name of the Cloud KMS key used to encrypt ('wrap') the AES-256 key.
* Example: key_name = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'
* @param string $wrappedAesKey The encrypted ('wrapped') AES-256 key to use.
*
* */
function reidentify_table_fpe(
string $callingProjectId,
string $inputCsvFile,
string $outputCsvFile,
string $encryptedFieldNames,
string $kmsKeyName,
string $wrappedAesKey
): void {
// Instantiate a client.
$dlp = new DlpServiceClient();
$parent = "projects/$callingProjectId/locations/global";
// Read a CSV file.
$csvLines = file($inputCsvFile, FILE_IGNORE_NEW_LINES);
$csvHeaders = explode(',', $csvLines[0]);
$csvRows = array_slice($csvLines, 1);
// Convert CSV file into protobuf objects.
$tableHeaders = array_map(function ($csvHeader) {
return (new FieldId)
->setName($csvHeader);
}, $csvHeaders);
$tableRows = array_map(function ($csvRow) {
$rowValues = array_map(function ($csvValue) {
return (new Value())
->setStringValue($csvValue);
}, explode(',', $csvRow));
return (new Row())
->setValues($rowValues);
}, $csvRows);
// Construct the table object.
$tableToDeIdentify = (new Table())
->setHeaders($tableHeaders)
->setRows($tableRows);
// Specify the content to be reidentify.
$content = (new ContentItem())
->setTable($tableToDeIdentify);
// Specify an encrypted AES-256 key and the name of the Cloud KMS key that encrypted it.
$kmsWrappedCryptoKey = (new KmsWrappedCryptoKey())
->setWrappedKey(base64_decode($wrappedAesKey))
->setCryptoKeyName($kmsKeyName);
$cryptoKey = (new CryptoKey())
->setKmsWrapped($kmsWrappedCryptoKey);
// Specify how to un-encrypt the previously de-identified information.
$cryptoReplaceFfxFpeConfig = (new CryptoReplaceFfxFpeConfig())
->setCryptoKey($cryptoKey)
->setCommonAlphabet(FfxCommonNativeAlphabet::NUMERIC);
$primitiveTransformation = (new PrimitiveTransformation())
->setCryptoReplaceFfxFpeConfig($cryptoReplaceFfxFpeConfig);
// Specify field to be decrypted.
$encryptedFields = array_map(function ($encryptedFieldName) {
return (new FieldId())
->setName($encryptedFieldName);
}, explode(',', $encryptedFieldNames));
// Associate the decryption with the specified field.
$fieldTransformation = (new FieldTransformation())
->setPrimitiveTransformation($primitiveTransformation)
->setFields($encryptedFields);
$recordtransformations = (new RecordTransformations())
->setFieldTransformations([$fieldTransformation]);
$reidentifyConfig = (new DeidentifyConfig())
->setRecordTransformations($recordtransformations);
// Run request.
$reidentifyContentRequest = (new ReidentifyContentRequest())
->setParent($parent)
->setReidentifyConfig($reidentifyConfig)
->setItem($content);
$response = $dlp->reidentifyContent($reidentifyContentRequest);
// Print the results.
$csvRef = fopen($outputCsvFile, 'w');
fputcsv($csvRef, $csvHeaders);
foreach ($response->getItem()->getTable()->getRows() as $tableRow) {
$values = array_map(function ($tableValue) {
return $tableValue->getStringValue();
}, iterator_to_array($tableRow->getValues()));
fputcsv($csvRef, $values);
};
printf('Table after re-identification (File Location): %s', $outputCsvFile);
}
import base64
from typing import List
import google.cloud.dlp
def reidentify_table_with_fpe(
project: str,
table_header: List[str],
table_rows: List[List[str]],
reid_field_names: List[str],
key_name: str = None,
wrapped_key: bytes = None,
alphabet: str = None,
) -> None:
"""Uses the Data Loss Prevention API to re-identify sensitive data in a
table that was encrypted by Format Preserving Encryption (FPE).
Args:
project: The Google Cloud project id to use as a parent resource.
table_header: List of strings representing table field names.
table_rows: List of rows representing table data.
reid_field_names: A list of fields in table to re-identify.
key_name: The name of the Cloud KMS key used to encrypt ('wrap') the
AES-256 key. Example:
key_name = 'projects/YOUR_GCLOUD_PROJECT/locations/YOUR_LOCATION/
keyRings/YOUR_KEYRING_NAME/cryptoKeys/YOUR_KEY_NAME'
wrapped_key: The decrypted ('wrapped', in bytes) AES-256 key to use. This key
should be encrypted using the Cloud KMS key specified by key_name.
alphabet: The set of characters to replace sensitive ones with. For
more information, see https://cloud.google.com/dlp/docs/reference/
rest/v2/projects.deidentifyTemplates#ffxcommonnativealphabet
"""
# Instantiate a client.
dlp = google.cloud.dlp_v2.DlpServiceClient()
# Construct the `table`. For more details on the table schema, please see
# https://cloud.google.com/dlp/docs/reference/rest/v2/ContentItem#Table
headers = [{"name": val} for val in table_header]
rows = []
for row in table_rows:
rows.append({"values": [{"string_value": cell_val} for cell_val in row]})
table = {"headers": headers, "rows": rows}
# Convert table to `item`
item = {"table": table}
# Specify fields to be re-identified/decrypted.
reid_field_names = [{"name": _i} for _i in reid_field_names]
# Construct FPE configuration dictionary
crypto_replace_ffx_fpe_config = {
"crypto_key": {
"kms_wrapped": {"wrapped_key": wrapped_key, "crypto_key_name": key_name}
},
"common_alphabet": alphabet,
}
# Construct reidentify configuration dictionary
reidentify_config = {
"record_transformations": {
"field_transformations": [
{
"primitive_transformation": {
"crypto_replace_ffx_fpe_config": crypto_replace_ffx_fpe_config,
},
"fields": reid_field_names,
}
]
}
}
# Convert the project id into a full resource id.
parent = f"projects/{project}/locations/global"
# Call the API.
response = dlp.reidentify_content(
request={
"parent": parent,
"reidentify_config": reidentify_config,
"item": item,
}
)
# Print out results.
print(f"Table after re-identification: {response.item.table}")
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-11-19 UTC."],[],[]]