Skip to content

Commit a4412ae

Browse files
committed
feat: add option to alert for stale gh sec alerts
1 parent 137ae3a commit a4412ae

22 files changed

+1355
-137
lines changed

.env.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,19 @@ APP_OKTA_GITHUB_USER_FIELD=githubUsername
2727
APP_OKTA_SYNC_RULES=[{"name":"sync-eng","enabled":true,"okta_group_pattern":"^github-eng-.*","github_team_prefix":"eng-","strip_prefix":"github-eng-","sync_members":true,"create_team_if_missing":true}]
2828
# APP_OKTA_SYNC_SAFETY_THRESHOLD=0.5 # Prevent mass removal if more than 50% would be removed (default: 0.5)
2929

30+
# security alerts monitoring (optional)
31+
# APP_SECURITY_ALERTS_ENABLED=true
32+
# APP_SECURITY_ALERTS_MIN_AGE_DAYS=30 # only report alerts older than N days (default: 30)
33+
# APP_SECURITY_ALERTS_MIN_SEVERITY=high # minimum severity: critical, high, medium, low (default: high)
34+
3035
# slack configuration (optional)
3136
APP_SLACK_TOKEN=xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3237
APP_SLACK_CHANNEL=C01234ABCDE
3338
# optional: per-notification-type channels (fall back to APP_SLACK_CHANNEL)
3439
# APP_SLACK_CHANNEL_PR_BYPASS=C01234ABCDE
3540
# APP_SLACK_CHANNEL_OKTA_SYNC=C01234ABCDE
3641
# APP_SLACK_CHANNEL_ORPHANED_USERS=C01234ABCDE
42+
# APP_SLACK_CHANNEL_SECURITY_ALERTS=C01234ABCDE
3743
# optional: custom footer note for PR bypass notifications (supports Slack mrkdwn)
3844
# APP_SLACK_FOOTER_NOTE_PR_BYPASS=_Please review the <https://example.com/policy|security policy>._
3945

README.md

Lines changed: 72 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,25 @@ notifications. Deploy as AWS Lambda, standard HTTP server, or container.
55

66
## Features
77

8-
* **Okta group sync** - Automatically sync Okta groups to GitHub teams
9-
* **Orphaned user detection** - Identify org members not in any synced teams
10-
* **PR compliance monitoring** - Detect and notify when PRs bypass branch
8+
- **Okta group sync** - Automatically sync Okta groups to GitHub teams
9+
- **Orphaned user detection** - Identify org members not in any synced teams
10+
- **PR compliance monitoring** - Detect and notify when PRs bypass branch
1111
protection
12-
* **Automatic reconciliation** - Detects external team changes and triggers
13-
sync
14-
* **Flexible configuration** - Enable only what you need via environment
12+
- **Security alerts monitoring** - Report stale Dependabot, code scanning, and
13+
secret scanning alerts across the org
14+
- **Automatic reconciliation** - Detects external team changes and triggers sync
15+
- **Flexible configuration** - Enable only what you need via environment
1516
variables
16-
* **Slack notifications** - Rich messages for violations and sync reports
17+
- **Slack notifications** - Rich messages for violations and sync reports
1718

1819
## Quick Start
1920

2021
### Prerequisites
2122

22-
* Go ≥ 1.24
23-
* GitHub App ([setup guide](docs/github-app-setup.md))
24-
* **Optional**: Okta API Service app ([setup guide](docs/okta-setup.md))
25-
* **Optional**: Slack app ([setup guide](docs/slack-setup.md))
23+
- Go ≥ 1.24
24+
- GitHub App ([setup guide](docs/github-app-setup.md))
25+
- **Optional**: Okta API Service app ([setup guide](docs/okta-setup.md))
26+
- **Optional**: Slack app ([setup guide](docs/slack-setup.md))
2627

2728
### Deployment Options
2829

@@ -42,8 +43,9 @@ make build-server
4243
# server listens on APP_PORT (default: 8080)
4344
# endpoints:
4445
# POST /webhooks - GitHub webhook receiver
45-
# POST /scheduled/okta-sync - Trigger Okta sync (call via cron)
46-
# POST /scheduled/slack-test - Send test notification to Slack
46+
# POST /scheduled/okta-sync - Trigger Okta sync (call via cron)
47+
# POST /scheduled/security-alerts - Trigger security alerts check
48+
# POST /scheduled/slack-test - Send test notification to Slack
4749
# GET /server/status - Health check
4850
# GET /server/config - Config (secrets redacted)
4951
```
@@ -80,26 +82,27 @@ APP_GITHUB_WEBHOOK_SECRET=arn:aws:ssm:us-east-1:123456789012:parameter/github-bo
8082
```
8183

8284
**Requirements for SSM parameters**:
85+
8386
- Valid AWS credentials with `ssm:GetParameter` permission
8487
- Full SSM parameter ARN in format:
8588
`arn:aws:ssm:REGION:ACCOUNT:parameter/path/to/param`
8689
- SecureString parameters are automatically decrypted
8790

8891
### Required: GitHub
8992

90-
| Variable | Description |
91-
|-------------------------------------|---------------------------------|
92-
| `APP_GITHUB_APP_ID` | GitHub App ID |
93-
| `APP_GITHUB_APP_PRIVATE_KEY` | Private key (PEM) |
94-
| `APP_GITHUB_APP_PRIVATE_KEY_PATH` | Path to private key file |
95-
| `APP_GITHUB_INSTALLATION_ID` | Installation ID |
96-
| `APP_GITHUB_ORG` | Organization name |
97-
| `APP_GITHUB_WEBHOOK_SECRET` | Webhook signature secret |
93+
| Variable | Description |
94+
| --------------------------------- | ------------------------ |
95+
| `APP_GITHUB_APP_ID` | GitHub App ID |
96+
| `APP_GITHUB_APP_PRIVATE_KEY` | Private key (PEM) |
97+
| `APP_GITHUB_APP_PRIVATE_KEY_PATH` | Path to private key file |
98+
| `APP_GITHUB_INSTALLATION_ID` | Installation ID |
99+
| `APP_GITHUB_ORG` | Organization name |
100+
| `APP_GITHUB_WEBHOOK_SECRET` | Webhook signature secret |
98101

99102
### Optional: Okta Sync
100103

101104
| Variable | Description |
102-
|----------------------------------------|-----------------------------------------------|
105+
| -------------------------------------- | --------------------------------------------- |
103106
| `APP_OKTA_DOMAIN` | Okta domain |
104107
| `APP_OKTA_CLIENT_ID` | OAuth 2.0 client ID |
105108
| `APP_OKTA_PRIVATE_KEY` | Private key (PEM) or use |
@@ -111,28 +114,39 @@ APP_GITHUB_WEBHOOK_SECRET=arn:aws:ssm:us-east-1:123456789012:parameter/github-bo
111114

112115
### Optional: PR Compliance
113116

114-
| Variable | Description |
115-
|----------------------------------|-------------------------------------------|
116-
| `APP_PR_COMPLIANCE_ENABLED` | Enable monitoring (`true`) |
117-
| `APP_PR_MONITORED_BRANCHES` | Branches to monitor (e.g., `main,master`) |
117+
| Variable | Description |
118+
| --------------------------- | ----------------------------------------- |
119+
| `APP_PR_COMPLIANCE_ENABLED` | Enable monitoring (`true`) |
120+
| `APP_PR_MONITORED_BRANCHES` | Branches to monitor (e.g., `main,master`) |
121+
122+
### Optional: Security Alerts
123+
124+
| Variable | Description |
125+
| ---------------------------------- | ---------------------------------------- |
126+
| `APP_SECURITY_ALERTS_ENABLED` | Enable monitoring (`true`) |
127+
| `APP_SECURITY_ALERTS_MIN_AGE_DAYS` | Min alert age in days (default: `30`) |
128+
| `APP_SECURITY_ALERTS_MIN_SEVERITY` | Min severity threshold (default: `high`) |
129+
130+
Severity options: `critical`, `high`, `medium`, `low`.
118131

119132
### Optional: Slack
120133

121-
| Variable | Description |
122-
|-----------------------------------|------------------------------------------|
123-
| `APP_SLACK_TOKEN` | Bot token (`xoxb-...`) |
124-
| `APP_SLACK_CHANNEL` | Default channel ID |
125-
| `APP_SLACK_CHANNEL_PR_BYPASS` | Channel for PR bypass alerts (optional) |
126-
| `APP_SLACK_CHANNEL_OKTA_SYNC` | Channel for sync reports (optional) |
127-
| `APP_SLACK_CHANNEL_ORPHANED_USERS`| Channel for orphan alerts (optional) |
134+
| Variable | Description |
135+
| ----------------------------------- | --------------------------------------- |
136+
| `APP_SLACK_TOKEN` | Bot token (`xoxb-...`) |
137+
| `APP_SLACK_CHANNEL` | Default channel ID |
138+
| `APP_SLACK_CHANNEL_PR_BYPASS` | Channel for PR bypass alerts (optional) |
139+
| `APP_SLACK_CHANNEL_OKTA_SYNC` | Channel for sync reports (optional) |
140+
| `APP_SLACK_CHANNEL_ORPHANED_USERS` | Channel for orphan alerts (optional) |
141+
| `APP_SLACK_CHANNEL_SECURITY_ALERTS` | Channel for security alerts (optional) |
128142

129143
### Other
130144

131-
| Variable | Description |
132-
|--------------------------|------------------------------------------------|
133-
| `APP_PORT` | Server port (default: `8080`) |
134-
| `APP_DEBUG_ENABLED` | Verbose logging (default: `false`) |
135-
| `APP_BASE_PATH` | URL prefix to strip (e.g., `/api/v1`) |
145+
| Variable | Description |
146+
| ------------------- | ------------------------------------- |
147+
| `APP_PORT` | Server port (default: `8080`) |
148+
| `APP_DEBUG_ENABLED` | Verbose logging (default: `false`) |
149+
| `APP_BASE_PATH` | URL prefix to strip (e.g., `/api/v1`) |
136150

137151
### Okta Sync Rules
138152

@@ -164,6 +178,7 @@ See [Okta Setup - Sync Rules](docs/okta-setup.md#step-10-configure-sync-rules)
164178
for detailed rule field documentation.
165179

166180
**Sync Safety Features**:
181+
167182
- Only syncs `ACTIVE` Okta users; never removes outside collaborators
168183
- Safety threshold (default 50%) aborts sync if too many removals detected
169184
- Orphaned user detection alerts when org members aren't in any synced teams
@@ -228,6 +243,13 @@ CMD ["/server"]
228243
| | - map groups to teams | |
229244
| | - sync membership | |
230245
| +------------------------------+ |
246+
| |
247+
| +------------------------------+ |
248+
| | Security Alerts Monitor | |
249+
| | - dependabot alerts | |
250+
| | - code scanning alerts | |
251+
| | - secret scanning alerts | |
252+
| +------------------------------+ |
231253
+------------------------------------+
232254
```
233255

@@ -245,12 +267,23 @@ CMD ["/server"]
245267
1. **Receive**: GitHub webhook on PR merge to monitored branch
246268
2. **Verify**: Validate webhook signature (HMAC-SHA256)
247269
3. **Check**: Query branch protection rules and required status checks
248-
4. **Detect**: Identify bypasses (admin override, missing reviews, failed checks)
270+
4. **Detect**: Identify bypasses (admin override, missing reviews, failed
271+
checks)
249272
5. **Notify**: Send Slack alert with violation details
250273

274+
### Security Alerts Flow
275+
276+
1. **Trigger**: Scheduled cron/EventBridge (`POST /scheduled/security-alerts`)
277+
2. **Fetch**: Query Dependabot, code scanning, and secret scanning alerts across
278+
the org
279+
3. **Filter**: Keep open alerts older than threshold (default 30 days) at or
280+
above minimum severity (default high)
281+
4. **Report**: Send Slack notification summarizing stale alerts by repo
282+
251283
## Troubleshooting
252284

253285
**Common issues**:
286+
254287
- Unauthorized from GitHub: Check app installation and permissions
255288
- Group not found from Okta: Verify domain and scopes
256289
- Webhook signature fails: Verify `APP_GITHUB_WEBHOOK_SECRET` matches
@@ -259,4 +292,3 @@ CMD ["/server"]
259292
## License
260293

261294
MIT
262-

assets/github/manifest.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
"organization_administration": "read",
1313
"members": "write",
1414
"contents": "read",
15-
"pull_requests": "read"
15+
"pull_requests": "read",
16+
"checks": "read",
17+
"dependabot_alerts": "read",
18+
"code_scanning_alerts": "read",
19+
"secret_scanning_alerts": "read"
1620
},
1721
"default_events": [
1822
"pull_request",

0 commit comments

Comments
 (0)