{"id":34773423,"url":"https://github.com/cruxstack/aws-securityhubv2-bot","last_synced_at":"2025-12-25T08:07:17.220Z","repository":{"id":326227791,"uuid":"1104595333","full_name":"cruxstack/aws-securityhubv2-bot","owner":"cruxstack","description":"Process AWS Security Hub v2 (OCSF) findings with auto-suppression rules, filtering, and optional Slack alerts","archived":false,"fork":false,"pushed_at":"2025-11-26T14:56:34.000Z","size":68,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-29T11:23:35.777Z","etag":null,"topics":["automation","aws","aws-lambda","aws-security","compliance","golang","guardduty","inspector","macie","ocsf","security","security-hub","securityhub","slack"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cruxstack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-26T12:27:25.000Z","updated_at":"2025-11-26T22:48:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cruxstack/aws-securityhubv2-bot","commit_stats":null,"previous_names":["cruxstack/cruxstack-aws-securityhubv2-bot"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/cruxstack/aws-securityhubv2-bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cruxstack%2Faws-securityhubv2-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cruxstack%2Faws-securityhubv2-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cruxstack%2Faws-securityhubv2-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cruxstack%2Faws-securityhubv2-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cruxstack","download_url":"https://codeload.github.com/cruxstack/aws-securityhubv2-bot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cruxstack%2Faws-securityhubv2-bot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28024303,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-25T02:00:05.988Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","aws","aws-lambda","aws-security","compliance","golang","guardduty","inspector","macie","ocsf","security","security-hub","securityhub","slack"],"created_at":"2025-12-25T08:07:12.084Z","updated_at":"2025-12-25T08:07:17.212Z","avatar_url":"https://github.com/cruxstack.png","language":"Go","readme":"# aws-securityhubv2-bot\n\nAWS Lambda bot that processes **AWS Security Hub v2** findings with configurable auto-close rules and optional Slack notifications.\n\n\u003e **Important:** Security Hub v2 only (OCSF format). Not directly compatible with original Security Hub CSPM (ASFF format).\n\n## Features\n\n* **auto-close rules** - suppress/resolve findings via JSON filters (type, severity, tags, accounts, regions)\n* **optional slack** - rich notifications with context and remediation links\n* **flexible config** - environment variables or S3 for rule storage\n* **multi-service** - GuardDuty, Inspector, Macie, IAM Access Analyzer, Security Hub CSPM\n\n---\n\n## Quick Start\n\n### Build\n\n```bash\nmkdir -p dist\nGOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -C cmd/lambda -o ../../dist/bootstrap\ncd dist \u0026\u0026 zip deployment.zip bootstrap \u0026\u0026 cd ..\n```\n\n### Deploy Lambda\n\n1. **IAM role** with `AWSLambdaBasicExecutionRole` + `securityhub:BatchUpdateFindingsV2`\n2. **Create function** using `deployment.zip` (runtime: `provided.al2023`, handler: `bootstrap`)\n3. **EventBridge rule** targeting the Lambda:\n   ```json\n   {\n     \"source\": [\"aws.securityhub\"],\n     \"detail-type\": [\"Findings Imported V2\"]\n   }\n   ```\n4. **Configure** using environment variables below\n\n---\n\n## Configuration\n\n### Auto-Close Rules\n\n| Name                               | Description                                        |\n| ---------------------------------- | -------------------------------------------------- |\n| `APP_AUTO_CLOSE_RULES`             | JSON array of auto-close rules (see examples)      |\n| `APP_AUTO_CLOSE_RULES_S3_BUCKET`   | S3 bucket for rules (for large rule sets)          |\n| `APP_AUTO_CLOSE_RULES_S3_PREFIX`   | S3 prefix for rules (default: `rules/`)            |\n\nUse environment variables, S3, or both. Environment rules evaluated first.\n\n### Slack (Optional)\n\n| Name                 | Description                               |\n| -------------------- | ----------------------------------------- |\n| `APP_SLACK_TOKEN`    | Bot token with `chat:write` scope         |\n| `APP_SLACK_CHANNEL`  | Channel ID (e.g., `C000XXXXXXX`)          |\n\n### Additional\n\n| Name                              | Description                              |\n| --------------------------------- | ---------------------------------------- |\n| `APP_DEBUG_ENABLED`               | Verbose logging (default: `false`)       |\n| `APP_AWS_CONSOLE_URL`             | Base console URL                         |\n| `APP_AWS_ACCESS_PORTAL_URL`       | Federated access portal URL              |\n| `APP_AWS_ACCESS_ROLE_NAME`        | IAM role for portal                      |\n| `APP_AWS_SECURITYHUBV2_REGION`    | Centralized SecurityHub region           |\n\n---\n\n## Examples\n\n### Basic Rule: Suppress GitHub Runner Findings\n\n```json\n[\n  {\n    \"name\": \"auto-close-github-runners\",\n    \"enabled\": true,\n    \"filters\": {\n      \"finding_types\": [\"Execution:Runtime/NewBinaryExecuted\"],\n      \"resource_tags\": [{\"name\": \"component-type\", \"value\": \"github-action-runners\"}]\n    },\n    \"action\": {\n      \"status_id\": 5,\n      \"comment\": \"Auto-archived: Expected CI/CD behavior\"\n    },\n    \"skip_notification\": true\n  }\n]\n```\n\nSee [examples/github-actions-runner-example.md](examples/github-actions-runner-example.md) for detailed walkthrough.\n\n### Multiple Rules\n\n```json\n[\n  {\n    \"name\": \"suppress-inspector-low-dev\",\n    \"filters\": {\n      \"product_name\": [\"Inspector\"],\n      \"severity\": [\"Low\"],\n      \"accounts\": [\"123456789012\"]\n    },\n    \"action\": {\"status_id\": 3, \"comment\": \"Auto-suppressed: Low severity in dev\"},\n    \"skip_notification\": false\n  },\n  {\n    \"name\": \"resolve-approved-scans\",\n    \"filters\": {\n      \"finding_types\": [\"Recon:EC2/PortProbeUnprotectedPort\"],\n      \"resource_tags\": [{\"name\": \"ScannerApproved\", \"value\": \"true\"}]\n    },\n    \"action\": {\"status_id\": 4, \"comment\": \"Auto-resolved: Approved scanner\"},\n    \"skip_notification\": true\n  }\n]\n```\n\n### Filter Reference\n\nAll filters use AND logic. First matching rule wins.\n\n| Field             | Type         | Example                                       |\n| ----------------- | ------------ | --------------------------------------------- |\n| `finding_types`   | `[]string`   | `[\"Execution:Runtime/NewBinaryExecuted\"]`     |\n| `severity`        | `[]string`   | `[\"Critical\", \"High\"]`                        |\n| `product_name`    | `[]string`   | `[\"GuardDuty\", \"Inspector\"]`                  |\n| `resource_types`  | `[]string`   | `[\"AWS::EC2::Instance\"]`                      |\n| `resource_tags`   | `[]object`   | `[{\"name\": \"Environment\", \"value\": \"dev\"}]`   |\n| `accounts`        | `[]string`   | `[\"123456789012\"]`                            |\n| `regions`         | `[]string`   | `[\"us-east-1\"]`                               |\n\n\n### Status IDs\n\nBased on [OCSF 1.6.0 specification](https://schema.ocsf.io/1.6.0/classes/detection_finding):\n\n| ID  | Status        | Description                                                                      |\n| --- | ------------- | -------------------------------------------------------------------------------- |\n| 0   | Unknown       | The status is unknown                                                            |\n| 1   | New           | The finding is new and yet to be reviewed                                        |\n| 2   | In Progress   | The finding is under review                                                      |\n| 3   | Suppressed    | The finding was reviewed, determined to be benign or false positive, suppressed  |\n| 4   | Resolved      | The finding was reviewed, remediated and is now considered resolved              |\n| 5   | Archived      | The finding was archived                                                         |\n| 6   | Deleted       | The finding was deleted (e.g., created in error)                                 |\n| 99  | Other         | The status is not mapped (see status attribute for source-specific value)        |\n\nCommon usage: `status_id: 5` (Archived) for accepted behavior, `status_id: 4` (Resolved) for remediated issues, `status_id: 3` (Suppressed) for false positives.\n\n### S3 Rule Storage\n\nFor large rule sets (\u003e4KB), store rules in S3. Supports single rule per file, arrays of rules, or mixed approach:\n\n```\ns3://my-rules-bucket/rules/\n├── guardduty/\n│   └── suppress-dev.json\n├── inspector/\n│   └── all-rules.json\n└── auto-close-runners.json\n```\n\nRequirements: Lambda needs `s3:GetObject` and `s3:ListBucket` on the bucket. Only `.json` files processed.\n\n---\n\n## EventBridge Filters (Optional)\n\nFilter by severity for high-volume environments:\n\n```json\n{\n  \"source\": [\"aws.securityhub\"],\n  \"detail-type\": [\"Findings Imported V2\"],\n  \"detail\": {\n    \"findings\": {\n      \"severity\": [\"Critical\", \"High\"]\n    }\n  }\n}\n```\n\nOr by source service:\n\n```json\n{\n  \"detail\": {\n    \"findings\": {\n      \"metadata\": {\n        \"product\": {\n          \"name\": [\"GuardDuty\", \"Inspector\"]\n        }\n      }\n    }\n  }\n}\n```\n\n---\n\n## IAM Permissions\n\nLambda role needs `AWSLambdaBasicExecutionRole` plus:\n\n```json\n{\n  \"Effect\": \"Allow\",\n  \"Action\": [\"securityhub:BatchUpdateFindingsV2\"],\n  \"Resource\": \"*\"\n}\n```\n\nIf using S3 rules, add:\n\n```json\n{\n  \"Effect\": \"Allow\",\n  \"Action\": [\"s3:GetObject\", \"s3:ListBucket\"],\n  \"Resource\": [\n    \"arn:aws:s3:::my-rules-bucket\",\n    \"arn:aws:s3:::my-rules-bucket/*\"\n  ]\n}\n```\n\n---\n\n## How It Works\n\n1. EventBridge triggers Lambda on \"Findings Imported V2\"\n2. Parse OCSF finding from event\n3. Evaluate auto-close rules in order (first match wins)\n4. If matched: call `BatchUpdateFindingsV2` with status + comment\n5. Send Slack notification (unless `skip_notification: true`)\n6. If no match: send to Slack if finding is alertable\n\n---\n\n## Local Development\n\n```bash\ncp .env.example .env  # edit values\ngo run -C cmd/sample .\n```\n\nUses OCSF findings from `fixtures/samples.json`. Requires AWS credentials for auto-close testing.\n\n---\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcruxstack%2Faws-securityhubv2-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcruxstack%2Faws-securityhubv2-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcruxstack%2Faws-securityhubv2-bot/lists"}