Skip to main content
The Lambda function detects Security Hub events when detail-type == "Security Hub Findings - Imported". It handles findings from two product sources: AWS Inspector and Security Hub itself.

Severity and colors

Finding severity maps to a Slack attachment color via the SecurityHubSeverity enum:
Severity labelSlack colorAppearance
CRITICALdangerRed
HIGHdangerRed
MEDIUMwarningYellow
LOW#777777Gray
INFORMATIONAL#439FE0Blue
If compliance_status is PASSED, the color is overridden to #4BB543 (green) regardless of severity label.

Fields in the Slack message

Both Inspector and Security Hub findings include the same set of fields:
FieldSource in finding
Titlefinding.Title
Descriptionfinding.Description
Compliance Statusfinding.Compliance.Status
Severityfinding.Severity.Label
Control IDfinding.ProductFields.ControlId
Account IDfinding.AwsAccountId
First Observedfinding.FirstObservedAt
Last Updatedfinding.UpdatedAt
Affected Resourcefinding.Resources[0].Id
Generatorfinding.GeneratorId
Control URLLink to the control in the Security Hub console
Finding URLDirect link to the finding in the Security Hub console
Remediationfinding.Remediation.Recommendation.Url

Auto-status update to prevent repeated notifications

When a finding has compliance_status == FAILED and workflow_status == NEW, the Lambda automatically calls securityhub:BatchUpdateFindings to set the workflow status to NOTIFIED. This prevents the same finding from triggering repeated Slack messages on subsequent imports. The required securityhub:BatchUpdateFindings permission is automatically included in the IAM role that the module creates for the Lambda function (AllowSecurityHub policy statement). You do not need to add this permission manually.
If the BatchUpdateFindings call fails (for example, due to a permissions issue), the Lambda logs the error and continues — it does not fail the invocation. Check CloudWatch Logs if you suspect findings are not being marked as NOTIFIED.

Setting up EventBridge to forward findings

resource "aws_cloudwatch_event_rule" "security_hub_findings" {
  name        = "forward-security-hub-findings"
  description = "Forward Security Hub findings to Slack"

  event_pattern = jsonencode({
    source      = ["aws.securityhub"]
    detail-type = ["Security Hub Findings - Imported"]
  })
}

resource "aws_cloudwatch_event_target" "security_hub_findings_sns" {
  rule      = aws_cloudwatch_event_rule.security_hub_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 can narrow the EventBridge rule using detail.findings.ProductName to forward only Inspector findings, only Security Hub findings, or both.

Build docs developers (and LLMs) love