Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 32 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ make build-server
# run (or use systemd, Docker, Kubernetes, etc.)
./dist/server

# server listens on PORT (default: 8080)
# server listens on APP_PORT (default: 8080)
# endpoints:
# POST /webhooks - GitHub webhook receiver
# POST /scheduled/okta-sync - Trigger Okta sync (call via cron)
# POST /scheduled/slack-test - Send test notification to Slack
# GET /server/status - Health check
# GET /server/config - Config (secrets redacted)
```
Expand All @@ -64,6 +65,8 @@ instructions including API Gateway and EventBridge configuration.

## Configuration

See [`.env.example`](.env.example) for a complete configuration reference.

All configuration values support direct values or AWS SSM parameter references.
For sensitive values like secrets and private keys, use SSM parameters with
automatic decryption:
Expand Down Expand Up @@ -115,15 +118,19 @@ APP_GITHUB_WEBHOOK_SECRET=arn:aws:ssm:us-east-1:123456789012:parameter/github-bo

### Optional: Slack

| Variable | Description |
|--------------------------|---------------------------------|
| `APP_SLACK_TOKEN` | Bot token (`xoxb-...`) |
| `APP_SLACK_CHANNEL` | Default channel ID |
| Variable | Description |
|-----------------------------------|------------------------------------------|
| `APP_SLACK_TOKEN` | Bot token (`xoxb-...`) |
| `APP_SLACK_CHANNEL` | Default channel ID |
| `APP_SLACK_CHANNEL_PR_BYPASS` | Channel for PR bypass alerts (optional) |
| `APP_SLACK_CHANNEL_OKTA_SYNC` | Channel for sync reports (optional) |
| `APP_SLACK_CHANNEL_ORPHANED_USERS`| Channel for orphan alerts (optional) |

### Other

| Variable | Description |
|--------------------------|------------------------------------------------|
| `APP_PORT` | Server port (default: `8080`) |
| `APP_DEBUG_ENABLED` | Verbose logging (default: `false`) |
| `APP_BASE_PATH` | URL prefix to strip (e.g., `/api/v1`) |

Expand Down Expand Up @@ -153,29 +160,13 @@ Map Okta groups to GitHub teams using JSON rules:
]
```

**Rule Fields**:
- `name` - Rule identifier
- `enabled` - Enable/disable rule
- `okta_group_pattern` - Regex to match Okta groups
- `okta_group_name` - Exact Okta group name (alternative to pattern)
- `github_team_prefix` - Prefix for GitHub team names
- `github_team_name` - Exact GitHub team name (overrides pattern)
- `strip_prefix` - Remove this prefix from Okta group name
- `sync_members` - Sync members between Okta and GitHub
- `create_team_if_missing` - Auto-create GitHub teams
- `team_privacy` - `secret` or `closed`
See [Okta Setup - Sync Rules](docs/okta-setup.md#step-10-configure-sync-rules)
for detailed rule field documentation.

**Sync Safety Features**:
- **Active users only**: Only syncs users with `ACTIVE` status in Okta,
automatically excluding suspended or deprovisioned accounts
- **External collaborator protection**: Never removes outside collaborators
(non-org members), preserving contractors and partner access
- **Outage protection**: Safety threshold (default 50%) prevents mass removal
if Okta/GitHub is experiencing issues. Sync aborts if removal ratio exceeds
threshold
- **Orphaned user detection**: Identifies organization members not in any
Okta-synced teams and sends Slack notifications. Enabled by default when
sync is enabled.
- Only syncs `ACTIVE` Okta users; never removes outside collaborators
- Safety threshold (default 50%) aborts sync if too many removals detected
- Orphaned user detection alerts when org members aren't in any synced teams

## Integration Setup

Expand Down Expand Up @@ -223,44 +214,21 @@ CMD ["/server"]
## How It Works

```
┌─────────────────────────────────────────────────┐
│ github-ops-app │
│ │
┌──────────────┐ │ ┌───────────────────────────────────────────┐ │
│ GitHub │ webhooks │ │ Webhook Handler │ │
│ │───────────────▶ • PR merge events │ │
│ • PR merge │ │ │ • Team membership changes │ │
│ • Team edit │ │ │ • Signature verification │ │
└──────────────┘ │ └─────────────┬─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ PR Compliance Check │ │
┌──────────────┐ │ │ • Branch protection verification │────────┐
│ Okta │ │ │ • Required checks validation │ │ │
│ │ │ │ • Bypass detection │ │ │
│ • Groups │◀──────────────┴─────────────────────────────────────────┘ │ │
│ • Users │ │ │ │
└──────────────┘ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ Okta Sync Engine │ │ │
│ │ │ • Match groups via rules │ │ │
└─────────────────────────▶ • Create/update GitHub teams │ │ │
│ │ • Sync team membership │ │ │
│ │ • Orphaned user detection │────────┤
│ │ • Safety threshold protection │ │ │
┌──────────────┐ │ └─────────────────────────────────────────┘ │ │
│ GitHub │ │ │ │ │
│ Teams API │◀─────────────────────────────────────────────────────────────┘ │
│ │ │ │ │
│ • Teams │ └─────────────────────────────────────────────────┘ │
│ • Members │ │
└──────────────┘ │
┌──────────────┐ │
│ Slack │◀─────────────────────────────────────┘
│ │ Notifications
│ • Alerts │ • PR violations
│ • Reports │ • Sync reports
└──────────────┘ • Orphaned users
┌────────────┐ ┌─────────────────────────────────────┐ ┌────────────┐
│ GitHub │────▶│ github-ops-app │────▶│ Slack │
│ webhooks │ │ │ │ alerts │
└────────────┘ │ ┌───────────────────────────────┐ │ └────────────┘
│ │ PR Compliance Check │ │
┌────────────┐ │ │ • Verify branch protection │ │ ┌────────────┐
│ Okta │────▶│ │ • Detect bypasses │ │────▶│ GitHub │
│ groups │ │ └───────────────────────────────┘ │ │ Teams API │
└────────────┘ │ │ └────────────┘
│ ┌───────────────────────────────┐ │
│ │ Okta Sync Engine │ │
│ │ • Map groups to teams │ │
│ │ • Sync membership │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
```

### Okta Sync Flow
Expand Down
16 changes: 9 additions & 7 deletions cmd/lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ Upload `dist/bootstrap` to your Lambda function via:

### 3. Configure Environment Variables

Set all required environment variables (see [Configuration](#configuration)
section in main README).
Set all required environment variables (see
[Configuration](../../README.md#configuration) in main README).

### 4. Setup Triggers

Expand Down Expand Up @@ -101,11 +101,13 @@ request type and path.

When invoked via API Gateway:

| Method | Path | Description |
|--------|-----------------------|-----------------------------------|
| POST | `/webhooks` | GitHub webhook receiver |
| GET | `/server/status` | Health check and feature flags |
| GET | `/server/config` | Config inspection (secrets hidden)|
| Method | Path | Description |
|--------|------------------------|-----------------------------------|
| POST | `/webhooks` | GitHub webhook receiver |
| POST | `/scheduled/okta-sync` | Trigger Okta sync |
| POST | `/scheduled/slack-test`| Send test notification to Slack |
| GET | `/server/status` | Health check and feature flags |
| GET | `/server/config` | Config inspection (secrets hidden)|

## Monitoring

Expand Down
17 changes: 16 additions & 1 deletion docs/okta-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,22 @@ APP_OKTA_SYNC_RULES='[
]'
```

See the main README for complete sync rule documentation.
### Rule Fields

| Field | Description |
|-------------------------|------------------------------------------------------|
| `name` | Rule identifier (for logging) |
| `enabled` | Enable/disable rule (default: `true`) |
| `okta_group_pattern` | Regex to match Okta groups |
| `okta_group_name` | Exact Okta group name (alternative to pattern) |
| `github_team_prefix` | Prefix for generated GitHub team names |
| `github_team_name` | Exact GitHub team name (overrides pattern) |
| `strip_prefix` | Remove this prefix from Okta group name |
| `sync_members` | Sync members between Okta and GitHub (default: `true`)|
| `create_team_if_missing`| Auto-create GitHub teams if they don't exist |
| `team_privacy` | GitHub team visibility: `secret` or `closed` |

See the [main README](../README.md#okta-sync-rules) for additional examples.

## Verification

Expand Down
50 changes: 12 additions & 38 deletions docs/slack-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,15 @@ This guide walks through creating a Slack app for github-ops-app notifications.
2. Click **Create New App**
3. Select **From an app manifest**
4. Select your workspace
5. Paste the manifest from `assets/slack/manifest.json`:

```json
{
"display_information": {
"name": "GitHub Bot",
"description": "GitHub automation bot with Okta sync and PR compliance monitoring",
"background_color": "#24292e"
},
"features": {
"bot_user": {
"display_name": "GitHub Bot",
"always_online": false
}
},
"oauth_config": {
"scopes": {
"bot": [
"channels:join",
"channels:read",
"chat:write.public",
"chat:write"
]
}
},
"settings": {
"org_deploy_enabled": false,
"socket_mode_enabled": false,
"token_rotation_enabled": false
}
}
```

5. Copy the contents of [`assets/slack/manifest.json`](../assets/slack/manifest.json)
and paste into the manifest editor
6. Click **Create**

### Option B: Manual Setup

1. Go to [api.slack.com/apps](https://api.slack.com/apps)
2. Click **Create New App** → **From scratch**
3. Enter app name: `GitHub Bot`
3. Enter app name: `GitHub Ops Bot`
4. Select your workspace
5. Click **Create App**

Expand Down Expand Up @@ -128,7 +97,7 @@ curl -H "Authorization: Bearer xoxb-your-token" \
For private channels, you must invite the bot:

1. Open the private channel
2. Type `/invite @GitHub Bot` (or your bot's display name)
2. Type `/invite @GitHub Ops Bot` (or your bot's display name)
3. Or click the channel name → **Integrations** → **Add apps**

Public channels work without invitation when using `chat:write.public`.
Expand All @@ -139,6 +108,11 @@ Public channels work without invitation when using `chat:write.public`.
# Required Slack configuration
APP_SLACK_TOKEN=xoxb-1234567890-...
APP_SLACK_CHANNEL=C01ABC2DEFG

# Optional: per-notification-type channels (override APP_SLACK_CHANNEL)
APP_SLACK_CHANNEL_PR_BYPASS=C01234ABCDE
APP_SLACK_CHANNEL_OKTA_SYNC=C01234ABCDE
APP_SLACK_CHANNEL_ORPHANED_USERS=C01234ABCDE
```

For AWS deployments, use SSM parameters:
Expand All @@ -153,10 +127,10 @@ Make notifications more recognizable:

1. Go to **Basic Information**
2. Under **Display Information**:
- **App name**: `GitHub Bot` (or your preference)
- **App name**: `GitHub Ops Bot` (or your preference)
- **Short description**: Brief description of the bot
- **App icon**: Upload a custom icon (recommended: GitHub logo variant)
- **Background color**: `#24292e` (GitHub dark) or your brand color
- **App icon**: Upload a custom icon (use `assets/slack/icon.png` or your own)
- **Background color**: `#10203B` or your brand color

## Verification

Expand Down