Skip to content

Commit

Permalink
feat(logs): support data protection custom data identifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Chiang committed Jan 3, 2024
1 parent 999c01a commit 59054de
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 32 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
"name": "policy-name",
"description": "policy description",
"version": "2021-06-01",
"configuration": {
"customDataIdentifier": [
{
"name": "EmployeeId",
"regex": "EmployeeId-\\d{9}"
}
]
},
"statement": [
{
"sid": "audit-statement-cdk",
Expand Down Expand Up @@ -47,7 +55,8 @@
":dataprotection::aws:data-identifier/EmailAddress"
]
]
}
},
"EmployeeId"
],
"operation": {
"audit": {
Expand Down Expand Up @@ -92,7 +101,8 @@
":dataprotection::aws:data-identifier/EmailAddress"
]
]
}
},
"EmployeeId"
],
"operation": {
"deidentify": {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class LogGroupIntegStack extends Stack {
const dataProtectionPolicy = new DataProtectionPolicy({
name: 'policy-name',
description: 'policy description',
identifiers: [DataIdentifier.DRIVERSLICENSE_US, new DataIdentifier('EmailAddress')],
identifiers: [DataIdentifier.DRIVERSLICENSE_US, new DataIdentifier('EmailAddress'), new DataIdentifier('EmployeeId', 'EmployeeId-\\d{9}')],
logGroupAuditDestination: audit,
s3BucketAuditDestination: bucket,
});
Expand Down
11 changes: 8 additions & 3 deletions packages/aws-cdk-lib/aws-logs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,11 @@ Creates a data protection policy and assigns it to the log group. A data protect

For more information, see [Protect sensitive log data with masking](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/mask-sensitive-log-data.html).

For a list of types of identifiers that can be audited and masked, see [Types of data that you can protect](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/protect-sensitive-log-data-types.html)
For a list of types of managed identifiers that can be audited and masked, see [Types of data that you can protect](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/protect-sensitive-log-data-types.html).

If a new identifier is supported but not yet in the `DataIdentifiers` enum, the full ARN of the identifier can be supplied in `identifierArnStrings` instead.
If a new identifier is supported but not yet in the `DataIdentifiers` enum, the name of the identifier can be supplied as `name` in the constructor instead.

To add a custom data identifier, supply a custom `name` and `regex` to the `DataIdentifiers` constructor. For more information on custom data identifiers, see [Custom data identifiers](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL-custom-data-identifiers.html).

Each policy may consist of a log group, S3 bucket, and/or Firehose delivery stream audit destination.

Expand All @@ -368,7 +370,10 @@ const deliveryStream = new kinesisfirehose.DeliveryStream(this, 'Delivery Stream
const dataProtectionPolicy = new logs.DataProtectionPolicy({
name: 'data protection policy',
description: 'policy description',
identifiers: [logs.DataIdentifier.DRIVERSLICENSE_US, new logs.DataIdentifier('EmailAddress')],
identifiers: [
logs.DataIdentifier.DRIVERSLICENSE_US, // managed data identifier
new logs.DataIdentifier('EmailAddress'), // forward compatibility for new managed data identifiers
new logs.DataIdentifier('EmployeeId', 'EmployeeId-\\d{9}')], // custom data identifier
logGroupAuditDestination: logGroupDestination,
s3BucketAuditDestination: bucket,
deliveryStreamNameAuditDestination: deliveryStream.deliveryStreamName,
Expand Down
53 changes: 39 additions & 14 deletions packages/aws-cdk-lib/aws-logs/lib/data-protection-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,30 @@ export class DataProtectionPolicy {
};
}

const identifierArns: string[] = [];
const identifiers: string[] = [];
const customDataIdentifiers: CustomDataIdentifier[] = [];
for (let identifier of this.dataProtectionPolicyProps.identifiers) {
identifierArns.push(Stack.of(_scope).formatArn({
resource: 'data-identifier',
region: '',
account: 'aws',
service: 'dataprotection',
resourceName: identifier.toString(),
}));
if (identifier.regex) {
identifiers.push(identifier.name);
customDataIdentifiers.push({
name: identifier.name,
regex: identifier.regex,
});
} else {
identifiers.push(Stack.of(_scope).formatArn({
resource: 'data-identifier',
region: '',
account: 'aws',
service: 'dataprotection',
resourceName: identifier.name,
}));
}
};

const statement = [
{
sid: 'audit-statement-cdk',
dataIdentifier: identifierArns,
dataIdentifier: identifiers,
operation: {
audit: {
findingsDestination: findingsDestination,
Expand All @@ -66,18 +75,26 @@ export class DataProtectionPolicy {
},
{
sid: 'redact-statement-cdk',
dataIdentifier: identifierArns,
dataIdentifier: identifiers,
operation: {
deidentify: {
maskConfig: {},
},
},
},
];
return { name, description, version, statement };

const configuration = {
customDataIdentifier: customDataIdentifiers,
};
return { name, description, version, configuration, statement };
}
}

interface CustomDataIdentifier {
name: string;
regex: string;
}
interface FindingsDestination {
cloudWatchLogs?: CloudWatchLogsDestination;
firehose?: FirehoseDestination;
Expand Down Expand Up @@ -119,6 +136,11 @@ export interface DataProtectionPolicyConfig {
*/
readonly version: string;

/**
* Configuration of the data protection policy. Currently supports custom data identifiers
*/
readonly configuration: any;

/**
* Statements within the data protection policy. Must contain one Audit and one Redact statement
*/
Expand All @@ -144,7 +166,9 @@ export interface DataProtectionPolicyProps {
readonly description?: string;

/**
* List of data protection identifiers. Must be in the following list: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/protect-sensitive-log-data-types.html
* List of data protection identifiers, containing managed or custom data identfiers.
* Managed data identiers must be in the following list: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL-managed-data-identifiers.html
* Custom data identfiers must have a valid regex defined: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL-custom-data-identifiers.html
*
*/
readonly identifiers: DataIdentifier[];
Expand Down Expand Up @@ -173,6 +197,7 @@ export interface DataProtectionPolicyProps {

/**
* A data protection identifier. If an identifier is supported but not in this class, it can be passed in the constructor instead.
* To create a custom data identifier, pass in a custom name and regex.
*/
export class DataIdentifier {
public static readonly ADDRESS = new DataIdentifier('Address');
Expand Down Expand Up @@ -274,9 +299,9 @@ export class DataIdentifier {
public static readonly VEHICLEIDENTIFICATIONNUMBER = new DataIdentifier('VehicleIdentificationNumber');
public static readonly ZIPCODE_US = new DataIdentifier('ZipCode-US');

constructor(private readonly identifier: string) { }
constructor(public readonly name: string, public readonly regex?: string) { }

public toString(): string {
return this.identifier;
return this.name;
}
}
Loading

0 comments on commit 59054de

Please sign in to comment.