|
| 1 | +# aws-securityhub-integration-slack-go |
| 2 | + |
| 3 | +AWS Lambda function that sends **AWS Security Hub v2** findings to Slack via EventBridge. **Security Hub v2** uses OCSF (Open Cybersecurity Schema Framework) format and centralizes findings from GuardDuty, Inspector, Macie, IAM Access Analyzer, and Security Hub CSPM. |
| 4 | + |
| 5 | +> **Note:** This is for Security Hub v2 only. Not compatible with the original AWS Security Hub (now called Security Hub CSPM). |
| 6 | +
|
| 7 | +## Features |
| 8 | + |
| 9 | +* **multi-service support** – handles findings from GuardDuty, Inspector, Macie, IAM Access Analyzer, and Security Hub CSPM |
| 10 | +* **ocsf format** – native support for Security Hub v2 OCSF schema |
| 11 | +* **eventbridge trigger** – findings invoke the Lambda function directly |
| 12 | +* **rich messages** – displays source service, severity, category, region, account, resource details, and remediation links |
| 13 | +* **config-driven** – all behavior controlled by environment variables |
| 14 | +* **severity filtering** – EventBridge rules can filter by severity (Critical/High only) |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## Deployment |
| 19 | + |
| 20 | +### Prerequisites |
| 21 | + |
| 22 | +* AWS account with **AWS Security Hub v2** enabled in at least one region |
| 23 | + * **Important:** This must be Security Hub v2, not the original Security Hub (now Security Hub CSPM) |
| 24 | + * Security Hub v2 uses OCSF format and has product ARNs like `arn:aws:securityhub:region::productv2/aws/guardduty` |
| 25 | +* At least one integrated security service enabled (GuardDuty, Inspector, Macie, IAM Access Analyzer, or Security Hub CSPM) |
| 26 | +* Slack App with a Bot Token (`chat:write` scope) installed in your workspace |
| 27 | +* Go ≥ 1.24 |
| 28 | +* AWS CLI configured for the deployment account |
| 29 | + |
| 30 | +### Steps |
| 31 | + |
| 32 | +```bash |
| 33 | +git clone https://github.com/cruxstack/aws-securityhub-integration-slack-go.git |
| 34 | +cd aws-securityhub-integration-slack-go |
| 35 | + |
| 36 | +# build static Linux binary for lambda |
| 37 | +mkdir -p dist |
| 38 | +GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -C cmd/lambda -o ../../dist/bootstrap |
| 39 | + |
| 40 | +# package |
| 41 | +cd dist && zip deployment.zip bootstrap && cd .. |
| 42 | +``` |
| 43 | + |
| 44 | +## Required Environment Variables |
| 45 | + |
| 46 | +| name | example | purpose | |
| 47 | +| --------------------------- | ------------------------------------------ | ------------------------------------------------------------ | |
| 48 | +| `APP_SLACK_TOKEN` | `xoxb-…` | slack bot token (store in secrets manager) | |
| 49 | +| `APP_SLACK_CHANNEL` | `C000XXXXXXX` | channel id to post findings | |
| 50 | + |
| 51 | +## Optional Environment Variables |
| 52 | + |
| 53 | +| name | example | purpose | default | |
| 54 | +| --------------------------- | ------------------------------------------ | ------------------------------------------------------------ | --------------------------------- | |
| 55 | +| `APP_DEBUG_ENABLED` | `true` | verbose logging & event dump | `false` | |
| 56 | +| `APP_AWS_CONSOLE_URL` | `https://console.aws.amazon.com` | base AWS console URL | `https://console.aws.amazon.com` | |
| 57 | +| `APP_AWS_ACCESS_PORTAL_URL` | `https://myorg.awsapps.com/start` | AWS access portal URL (for federated access) | _(none - direct console links)_ | |
| 58 | +| `APP_AWS_ACCESS_ROLE_NAME` | `SecurityAuditor` | IAM role name for access portal | _(none - direct console links)_ | |
| 59 | + |
| 60 | +## Create Lambda Function |
| 61 | + |
| 62 | +1. **IAM role** |
| 63 | + * `AWSLambdaBasicExecutionRole` managed policy |
| 64 | + * no additional AWS API permissions are required |
| 65 | +2. **Lambda config** |
| 66 | + * Runtime: `al2023provided.al2023` (provided.al2 also works) |
| 67 | + * Handler: `bootstrap` |
| 68 | + * Architecture: `x86_64` or `arm64` |
| 69 | + * Upload `deployment.zip` |
| 70 | + * Set environment variables above |
| 71 | +3. **EventBridge rule** |
| 72 | + ```json |
| 73 | + { |
| 74 | + "source": ["aws.securityhub"], |
| 75 | + "detail-type": ["Security Hub Findings - Imported"] |
| 76 | + } |
| 77 | + ``` |
| 78 | + Optional: Filter by severity (recommended for high-volume environments): |
| 79 | + ```json |
| 80 | + { |
| 81 | + "source": ["aws.securityhub"], |
| 82 | + "detail-type": ["Security Hub Findings - Imported"], |
| 83 | + "detail": { |
| 84 | + "severity": ["Critical", "High"] |
| 85 | + } |
| 86 | + } |
| 87 | + ``` |
| 88 | + Or filter by specific source services: |
| 89 | + ```json |
| 90 | + { |
| 91 | + "source": ["aws.securityhub"], |
| 92 | + "detail-type": ["Security Hub Findings - Imported"], |
| 93 | + "detail": { |
| 94 | + "metadata": { |
| 95 | + "product": { |
| 96 | + "name": ["GuardDuty", "Inspector"] |
| 97 | + } |
| 98 | + } |
| 99 | + } |
| 100 | + } |
| 101 | + ``` |
| 102 | + Target: the Lambda function. |
| 103 | +4. **Slack App** |
| 104 | + * Add `chat:write` and `chat:write.public` |
| 105 | + * Custom bot avatar: upload AWS Security Hub logo in the Slack App *App Icon* |
| 106 | + section. |
| 107 | + |
| 108 | + |
| 109 | +## Local Development |
| 110 | + |
| 111 | +### Test with Samples |
| 112 | + |
| 113 | +```bash |
| 114 | +cp .env.example .env # edit the values |
| 115 | +go run -C cmd/sample . |
| 116 | +``` |
| 117 | + |
| 118 | +The sample runner reads OCSF-formatted Security Hub v2 findings from `fixtures/samples.json`, wraps them in EventBridge events, and posts to Slack exactly as the live Lambda would. |
| 119 | + |
0 commit comments