Skip to content

Commit 18bcc74

Browse files
committed
CCM-10048: add functionality to simulate a guarduty scan
1 parent 25de238 commit 18bcc74

17 files changed

+414
-7
lines changed

infrastructure/terraform/components/sandbox/module_backend_api.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ module "backend_api" {
2222

2323
kms_key_arn = data.aws_kms_key.sandbox.arn
2424
dynamodb_kms_key_arn = data.aws_kms_key.sandbox.arn
25+
26+
test_environment_mock_guardduty_event_source = "test.guardduty"
2527
}

infrastructure/terraform/modules/backend-api/cloudwatch_event_rule_guardduty_quarantine_scan_failed_for_proof.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resource "aws_cloudwatch_event_rule" "guardduty_quarantine_scan_failed_for_proof
33
description = "Matches quarantine 'GuardDuty Malware Protection Object Scan Result' events where the scan result is not NO_THREATS_FOUND"
44

55
event_pattern = jsonencode({
6-
source = ["aws.guardduty"]
6+
source = compact(["aws.guardduty", var.test_environment_mock_guardduty_event_source])
77
detail-type = ["GuardDuty Malware Protection Object Scan Result"]
88
resources = [aws_guardduty_malware_protection_plan.quarantine.arn]
99
detail = {

infrastructure/terraform/modules/backend-api/cloudwatch_event_rule_guardduty_quarantine_scan_failed_for_upload.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resource "aws_cloudwatch_event_rule" "guardduty_quarantine_scan_failed_for_uploa
33
description = "Matches quarantine 'GuardDuty Malware Protection Object Scan Result' events where the scan result is not NO_THREATS_FOUND"
44

55
event_pattern = jsonencode({
6-
source = ["aws.guardduty"]
6+
source = compact(["aws.guardduty", var.test_environment_mock_guardduty_event_source])
77
detail-type = ["GuardDuty Malware Protection Object Scan Result"]
88
resources = [aws_guardduty_malware_protection_plan.quarantine.arn]
99
detail = {

infrastructure/terraform/modules/backend-api/cloudwatch_event_rule_guardduty_quarantine_scan_passed_for_proof.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resource "aws_cloudwatch_event_rule" "guardduty_quarantine_scan_passed_for_proof
33
description = "Matches quarantine 'GuardDuty Malware Protection Object Scan Result' events where the scan result is NO_THREATS_FOUND"
44

55
event_pattern = jsonencode({
6-
source = ["aws.guardduty"]
6+
source = compact(["aws.guardduty", var.test_environment_mock_guardduty_event_source])
77
detail-type = ["GuardDuty Malware Protection Object Scan Result"]
88
resources = [aws_guardduty_malware_protection_plan.quarantine.arn]
99
detail = {

infrastructure/terraform/modules/backend-api/cloudwatch_event_rule_guardduty_quarantine_scan_passed_for_upload.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resource "aws_cloudwatch_event_rule" "guardduty_quarantine_scan_passed_for_uploa
33
description = "Matches quarantine 'GuardDuty Malware Protection Object Scan Result' events where the scan result is NO_THREATS_FOUND"
44

55
event_pattern = jsonencode({
6-
source = ["aws.guardduty"]
6+
source = compact(["aws.guardduty", var.test_environment_mock_guardduty_event_source])
77
detail-type = ["GuardDuty Malware Protection Object Scan Result"]
88
resources = [aws_guardduty_malware_protection_plan.quarantine.arn]
99
detail = {

infrastructure/terraform/modules/backend-api/outputs.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ output "download_bucket_regional_domain_name" {
1010
value = module.s3bucket_download.bucket_regional_domain_name
1111
}
1212

13+
output "guardduty_quarantine_arn" {
14+
value = aws_guardduty_malware_protection_plan.quarantine.arn
15+
}
16+
1317
output "internal_bucket_name" {
1418
value = module.s3bucket_internal.id
1519
}

infrastructure/terraform/modules/backend-api/variables.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,9 @@ variable "log_subscription_role_arn" {
122122
description = "The ARN of the IAM role to use for the log subscription filter"
123123
default = ""
124124
}
125+
126+
variable "test_environment_mock_guardduty_event_source" {
127+
type = string
128+
description = "Adds a new source to the EventBridge Guard Duty filter rules"
129+
default = ""
130+
}

package-lock.json

Lines changed: 52 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/test-team/global.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ declare global {
1313
TEMPLATES_INTERNAL_BUCKET_NAME: string;
1414
TEMPLATES_QUARANTINE_BUCKET_NAME: string;
1515
TEMPLATES_DOWNLOAD_BUCKET_NAME: string;
16+
TEMPLATES_GUARDDUTY_RESOURCE_ARN: string;
1617
}
1718
}
1819

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import {
2+
EventBridgeClient,
3+
PutEventsCommand,
4+
} from '@aws-sdk/client-eventbridge';
5+
6+
export class EventBridgeHelper {
7+
readonly #client: EventBridgeClient;
8+
9+
constructor() {
10+
this.#client = new EventBridgeClient({ region: 'eu-west-2' });
11+
}
12+
13+
async publishGuardDutyEvent(
14+
s3ObjectKey: string,
15+
s3VersionId: string,
16+
guardDutyScanResultStatus:
17+
| 'NO_THREATS_FOUND'
18+
| 'THREATS_FOUND'
19+
| 'UNSUPPORTED'
20+
) {
21+
const resp = await this.#client.send(
22+
new PutEventsCommand({
23+
Entries: [
24+
this.createGuardDutyEvent(
25+
s3ObjectKey,
26+
guardDutyScanResultStatus,
27+
s3VersionId
28+
),
29+
],
30+
})
31+
);
32+
33+
if (resp.FailedEntryCount && resp.FailedEntryCount > 0) {
34+
throw new Error(
35+
`Failed to publish ${guardDutyScanResultStatus} event for ${s3ObjectKey}`,
36+
{
37+
cause: resp,
38+
}
39+
);
40+
}
41+
}
42+
43+
private createGuardDutyEvent(
44+
s3ObjectKey: string,
45+
scanResultStatus: 'NO_THREATS_FOUND' | 'THREATS_FOUND' | 'UNSUPPORTED',
46+
versionId: string
47+
) {
48+
const SOURCE = 'test.guardduty';
49+
const DETAIL_TYPE = 'GuardDuty Malware Protection Object Scan Result';
50+
51+
return {
52+
Source: SOURCE,
53+
DetailType: DETAIL_TYPE,
54+
Detail: JSON.stringify({
55+
schemaVersion: '1.0',
56+
scanResultDetails: {
57+
scanResultStatus: scanResultStatus,
58+
},
59+
s3ObjectDetails: {
60+
bucketName: process.env.TEMPLATES_QUARANTINE_BUCKET_NAME,
61+
objectKey: s3ObjectKey,
62+
eTag: `test-etag-${Date.now()}`,
63+
versionId: versionId,
64+
},
65+
}),
66+
Resources: [process.env.TEMPLATES_GUARDDUTY_RESOURCE_ARN],
67+
};
68+
}
69+
}

0 commit comments

Comments
 (0)