aws-securityhubv2-bot

module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 2, 2025 License: MIT

README

aws-securityhubv2-bot

AWS Lambda bot that processes AWS Security Hub v2 findings with configurable auto-close rules and optional Slack notifications.

Important: Security Hub v2 only (OCSF format). Not directly compatible with original Security Hub CSPM (ASFF format).

Features

  • auto-close rules - suppress/resolve findings via JSON filters (type, severity, tags, accounts, regions)
  • optional slack - rich notifications with context and remediation links
  • flexible config - environment variables or S3 for rule storage
  • multi-service - GuardDuty, Inspector, Macie, IAM Access Analyzer, Security Hub CSPM

Quick Start

Build
mkdir -p dist
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -C cmd/lambda -o ../../dist/bootstrap
cd dist && zip deployment.zip bootstrap && cd ..
Deploy Lambda
  1. IAM role with AWSLambdaBasicExecutionRole + securityhub:BatchUpdateFindingsV2
  2. Create function using deployment.zip (runtime: provided.al2023, handler: bootstrap)
  3. EventBridge rule targeting the Lambda:
    {
      "source": ["aws.securityhub"],
      "detail-type": ["Findings Imported V2"]
    }
    
  4. Configure using environment variables below

Configuration

Auto-Close Rules
Name Description
APP_AUTO_CLOSE_RULES JSON array of auto-close rules (see examples)
APP_AUTO_CLOSE_RULES_S3_BUCKET S3 bucket for rules (for large rule sets)
APP_AUTO_CLOSE_RULES_S3_PREFIX S3 prefix for rules (default: rules/)

Use environment variables, S3, or both. Environment rules evaluated first.

Slack (Optional)
Name Description
APP_SLACK_TOKEN Bot token with chat:write scope
APP_SLACK_CHANNEL Channel ID (e.g., C000XXXXXXX)
Additional
Name Description
APP_DEBUG_ENABLED Verbose logging (default: false)
APP_AWS_CONSOLE_URL Base console URL
APP_AWS_ACCESS_PORTAL_URL Federated access portal URL
APP_AWS_ACCESS_ROLE_NAME IAM role for portal
APP_AWS_SECURITYHUBV2_REGION Centralized SecurityHub region

Examples

Basic Rule: Suppress GitHub Runner Findings
[
  {
    "name": "auto-close-github-runners",
    "enabled": true,
    "filters": {
      "finding_types": ["Execution:Runtime/NewBinaryExecuted"],
      "resource_tags": [{"name": "component-type", "value": "github-action-runners"}]
    },
    "action": {
      "status_id": 5,
      "comment": "Auto-archived: Expected CI/CD behavior"
    },
    "skip_notification": true
  }
]

See examples/github-actions-runner-example.md for detailed walkthrough.

Multiple Rules
[
  {
    "name": "suppress-inspector-low-dev",
    "filters": {
      "product_name": ["Inspector"],
      "severity": ["Low"],
      "accounts": ["123456789012"]
    },
    "action": {"status_id": 3, "comment": "Auto-suppressed: Low severity in dev"},
    "skip_notification": false
  },
  {
    "name": "resolve-approved-scans",
    "filters": {
      "finding_types": ["Recon:EC2/PortProbeUnprotectedPort"],
      "resource_tags": [{"name": "ScannerApproved", "value": "true"}]
    },
    "action": {"status_id": 4, "comment": "Auto-resolved: Approved scanner"},
    "skip_notification": true
  }
]
Filter Reference

All filters use AND logic. First matching rule wins.

Field Type Example
finding_types []string ["Execution:Runtime/NewBinaryExecuted"]
severity []string ["Critical", "High"]
product_name []string ["GuardDuty", "Inspector"]
resource_types []string ["AWS::EC2::Instance"]
resource_tags []object [{"name": "Environment", "value": "dev"}]
accounts []string ["123456789012"]
regions []string ["us-east-1"]
Status IDs

Based on OCSF 1.6.0 specification:

ID Status Description
0 Unknown The status is unknown
1 New The finding is new and yet to be reviewed
2 In Progress The finding is under review
3 Suppressed The finding was reviewed, determined to be benign or false positive, suppressed
4 Resolved The finding was reviewed, remediated and is now considered resolved
5 Archived The finding was archived
6 Deleted The finding was deleted (e.g., created in error)
99 Other The status is not mapped (see status attribute for source-specific value)

Common usage: status_id: 5 (Archived) for accepted behavior, status_id: 4 (Resolved) for remediated issues, status_id: 3 (Suppressed) for false positives.

S3 Rule Storage

For large rule sets (>4KB), store rules in S3. Supports single rule per file, arrays of rules, or mixed approach:

s3://my-rules-bucket/rules/
├── guardduty/
│   └── suppress-dev.json
├── inspector/
│   └── all-rules.json
└── auto-close-runners.json

Requirements: Lambda needs s3:GetObject and s3:ListBucket on the bucket. Only .json files processed.


EventBridge Filters (Optional)

Filter by severity for high-volume environments:

{
  "source": ["aws.securityhub"],
  "detail-type": ["Findings Imported V2"],
  "detail": {
    "findings": {
      "severity": ["Critical", "High"]
    }
  }
}

Or by source service:

{
  "detail": {
    "findings": {
      "metadata": {
        "product": {
          "name": ["GuardDuty", "Inspector"]
        }
      }
    }
  }
}

IAM Permissions

Lambda role needs AWSLambdaBasicExecutionRole plus:

{
  "Effect": "Allow",
  "Action": ["securityhub:BatchUpdateFindingsV2"],
  "Resource": "*"
}

If using S3 rules, add:

{
  "Effect": "Allow",
  "Action": ["s3:GetObject", "s3:ListBucket"],
  "Resource": [
    "arn:aws:s3:::my-rules-bucket",
    "arn:aws:s3:::my-rules-bucket/*"
  ]
}

How It Works

  1. EventBridge triggers Lambda on "Findings Imported V2"
  2. Parse OCSF finding from event
  3. Evaluate auto-close rules in order (first match wins)
  4. If matched: call BatchUpdateFindingsV2 with status + comment
  5. Send Slack notification (unless skip_notification: true)
  6. If no match: send to Slack if finding is alertable

Local Development

cp .env.example .env  # edit values
go run -C cmd/sample .

Uses OCSF findings from fixtures/samples.json. Requires AWS credentials for auto-close testing.


License

This project is licensed under the MIT License - see the LICENSE file for details.

Directories

Path Synopsis
cmd
lambda command
sample command
verify command
Package main provides offline integration testing using HTTP mock servers.
Package main provides offline integration testing using HTTP mock servers.
internal
app

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL