Skip to main content
The Lambda function handles two GuardDuty event types, detected by the detail-type field in the EventBridge event.

GuardDuty findings

Detected when detail-type == "GuardDuty Finding".

Severity mapping

The numeric severity score from the finding maps to a label and Slack color via the GuardDutyFindingSeverity enum:
Severity scoreLabelSlack colorAppearance
< 4.0Low#777777Gray
4.0 – 6.9MediumwarningYellow
≥ 7.0HighdangerRed

Fields in the Slack message

FieldSource in event
Descriptiondetail.description
Finding Typedetail.type
First Seendetail.service.eventFirstSeen
Last Seendetail.service.eventLastSeen
SeverityDerived from detail.severity score
Account IDdetail.accountId
Countdetail.service.count
Link to FindingDirect link to the finding in the GuardDuty console

Example event payload

{
  "detail-type": "GuardDuty Finding",
  "region": "us-east-1",
  "detail": {
    "id": "sample-id-2",
    "title": "SAMPLE Unprotected port on EC2 instance i-123123123 is being probed",
    "severity": 9,
    "accountId": "123456789",
    "description": "EC2 instance has an unprotected port which is being probed by a known malicious host.",
    "type": "Recon:EC2 PortProbeUnprotectedPort",
    "service": {
      "eventFirstSeen": "2020-01-02T01:02:03Z",
      "eventLastSeen": "2020-01-03T01:02:03Z",
      "count": 1234
    }
  }
}

GuardDuty Malware Protection object scan results

Detected when detail-type == "GuardDuty Malware Protection Object Scan Result". These events are generated when GuardDuty scans an S3 object for malware.

Scan result status and severity

scanResultStatusSeveritySlack color
NO_THREATS_FOUNDLow#777777
THREATS_FOUNDHighdanger
UNSUPPORTEDMediumwarning
ACCESS_DENIEDMediumwarning
FAILEDMediumwarning

Fields in the Slack message

FieldSource in event
S3 Bucketdetail.s3ObjectDetails.bucketName
S3 Objectdetail.s3ObjectDetails.objectKey
Link to S3 objectDirect link to the object in the S3 console

Setting up EventBridge to forward findings

Create an EventBridge rule that matches GuardDuty events and delivers them to the SNS topic.
resource "aws_cloudwatch_event_rule" "guardduty_findings" {
  name        = "forward-guardduty-findings"
  description = "Forward GuardDuty findings to Slack"

  event_pattern = jsonencode({
    source      = ["aws.guardduty"]
    detail-type = [
      "GuardDuty Finding",
      "GuardDuty Malware Protection Object Scan Result"
    ]
  })
}

resource "aws_cloudwatch_event_target" "guardduty_findings_sns" {
  rule      = aws_cloudwatch_event_rule.guardduty_findings.name
  target_id = "SendToSNS"
  arn       = module.notify_slack.slack_topic_arn
}

resource "aws_sns_topic_policy" "allow_eventbridge" {
  arn = module.notify_slack.slack_topic_arn

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "events.amazonaws.com" }
      Action    = "SNS:Publish"
      Resource  = module.notify_slack.slack_topic_arn
    }]
  })
}
You must grant EventBridge permission to publish to the SNS topic. The aws_sns_topic_policy resource above adds that permission.

Build docs developers (and LLMs) love