PCI-DSS 4.0 Req 11.5 requires that a change-detection mechanism is deployed to alert personnel to unauthorized modifications of critical files; Req 10.7 requires failures of critical security controls to be detected and reported promptly. Without IDS/IPS or network flow monitoring on the CDE network, an attacker who has established a foothold can exfiltrate cardholder data over days or weeks without generating any alert. ISO 27001:2022 A.8.16 and NIST SI-4 both require continuous network monitoring. VPC Flow Logs and GuardDuty together provide the minimum signal set required by Req 11.5 for cloud-hosted CDEs.
Medium because without network monitoring an active intrusion or data exfiltration event produces no alert, extending mean-time-to-detection and turning a recoverable incident into a reportable breach.
Enable VPC Flow Logs for every VPC that contains CDE resources and activate GuardDuty in the same AWS account. Create a CloudWatch Logs Insights query to alert on anomalous egress volume from the CDE subnet. Both controls together satisfy PCI-DSS 4.0 Req 11.5.
# VPC Flow Logs → CloudWatch
resource "aws_flow_log" "cde" {
vpc_id = aws_vpc.cde.id
traffic_type = "ALL"
log_destination = aws_cloudwatch_log_group.flow_logs.arn
iam_role_arn = aws_iam_role.flow_logs.arn
}
# GuardDuty IDS
resource "aws_guardduty_detector" "main" {
enable = true
}
Set a CloudWatch Alarm on the Logs Insights metric for bytes > 10MB from CDE subnets in a 5-minute window and route it to an SNS topic that pages the on-call team. Document which monitoring tools cover the CDE in docs/pci-compliance.md.
ID: ecommerce-pci.monitoring-compliance.ids-ips-configured
Severity: medium
What to look for: Count all network monitoring and IDS/IPS tools configured in the project. Check for at least 1 of: GuardDuty detector, VPC Flow Logs, Snort/Suricata rules, Datadog network monitoring, CloudWatch Logs Insights queries for network traffic. Enumerate all monitoring configurations in infrastructure code and check whether they cover CDE network zones. Count the number of alerting rules or anomaly detection configs.
Pass criteria: At least 1 IDS/IPS or network monitoring tool is configured and covers CDE traffic. At least 1 of: VPC Flow Logs enabled for CDE VPC, GuardDuty detector enabled, or network monitoring agent configured for CDE network. At least 1 alerting rule or anomaly detection query exists. Report: "X monitoring tools configured, Y alerting rules, covering Z network zones."
Fail criteria: No network monitoring configured (0 IDS/IPS tools in infrastructure code), or monitoring exists but does not cover CDE traffic (monitoring only on application VPC, not CDE VPC).
Skip (N/A) when: Payment processing fully delegated to third-party (no CDE network in infrastructure, no VPCs, no security groups).
Detail on fail: Specify the monitoring gap. Example: "0 IDS/IPS tools configured for CDE network. VPC Flow Logs not enabled. GuardDuty not configured." or "Datadog RUM configured for frontend but 0 network monitoring tools cover CDE VPC."
Remediation: Enable network monitoring. For AWS:
# VPC Flow Logs to CloudWatch
resource "aws_flow_log" "cde" {
iam_role_arn = aws_iam_role.flow_logs.arn
log_destination = aws_cloudwatch_log_group.flow_logs.arn
traffic_type = "ALL"
vpc_id = aws_vpc.cde.id
tags = { Name = "cde-flow-logs" }
}
# CloudWatch Logs Insights queries
resource "aws_logs_insight_query_definition" "suspicious_ips" {
name = "Suspicious CDE IPs"
query_string = <<-EOT
fields srcaddr, dstaddr, protocol, bytes, packets
| stats sum(bytes) as total_bytes by srcaddr
| filter total_bytes > 1000000
| sort total_bytes desc
EOT
}
# GuardDuty for IDS/IPS
resource "aws_guardduty_detector" "main" {
enable = true
}
For Datadog:
// src/middleware/monitoring.ts
import { datadogRum } from '@datadog/browser-rum';
datadogRum.init({
applicationId: process.env.DATADOG_APP_ID,
clientToken: process.env.DATADOG_CLIENT_TOKEN,
service: 'payment-api',
env: process.env.NODE_ENV,
sessionSampleRate: 100,
sessionReplaySampleRate: 100,
trackUserInteractions: true,
trackResources: true,
trackLongTasks: true,
});
// Log suspicious events
datadogRum.addRumGlobalContext('event_type', 'suspicious_activity');