Skip to content

Commit 2dc32b5

Browse files
committed
dev: improve dx
1 parent 4fa3862 commit 2dc32b5

File tree

7 files changed

+176
-90
lines changed

7 files changed

+176
-90
lines changed

.dockerignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.local/
2+
.env
3+
dist/
4+
tmp/
5+
.git/

Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM golang:1.24 AS builder
2+
3+
WORKDIR /src
4+
COPY go.mod go.sum ./
5+
RUN go mod download
6+
COPY . .
7+
RUN CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o /server ./cmd/server
8+
9+
FROM gcr.io/distroless/static-debian12
10+
COPY --from=builder /server /server
11+
ENTRYPOINT ["/server"]

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,15 @@ test-verify:
4343
test-verify-verbose:
4444
go run ./cmd/verify -verbose
4545

46+
.PHONY: server-up
47+
server-up:
48+
docker compose up -d --build
49+
50+
.PHONY: server-logs
51+
server-logs:
52+
docker compose logs -f server
53+
54+
.PHONY: server-stop
55+
server-stop:
56+
docker compose down --rmi local --remove-orphans
57+

compose.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
server:
3+
build: .
4+
container_name: github-ops-server
5+
env_file: .env
6+
ports:
7+
- "${APP_PORT:-8080}:${APP_PORT:-8080}"
8+
volumes:
9+
- ./.local:/.local:ro
10+
restart: unless-stopped

docs/github-app-setup.md

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# GitHub App Setup
22

3-
This guide walks through creating and installing a GitHub App for github-ops-app.
3+
This guide walks through creating and installing a GitHub App for
4+
github-ops-app.
45

56
## Prerequisites
67

@@ -9,39 +10,50 @@ This guide walks through creating and installing a GitHub App for github-ops-app
910
## Step 1: Create the GitHub App
1011

1112
1. Navigate to your organization's settings:
13+
1214
- Go to `https://github.com/organizations/YOUR_ORG/settings/apps`
13-
- Or: **Organization****Settings****Developer settings****GitHub Apps**
15+
- Or: **Organization****Settings****Developer settings****GitHub
16+
Apps**
1417

1518
2. Click **New GitHub App**
1619

1720
3. Fill in the basic information:
1821

19-
| Field | Value |
20-
|-----------------------|-------------------------------------------------|
21-
| GitHub App name | `github-ops-app` (must be unique across GitHub) |
22-
| Homepage URL | Your organization's URL or repo URL |
23-
| Webhook > Webhook URL | Leave blank for now |
24-
| Webhook > Secret | Generate a strong secret (save this for later) |
25-
| Webhook > Active | **Uncheck** to disable webhooks initially |
26-
27-
> **Note**: Disable webhooks during creation since you may not know your
28-
> endpoint URL until after deployment. You'll configure webhooks and
29-
> subscribe to events in [Step 7](#step-7-configure-webhook-and-events).
30-
31-
4. Under **Permissions**, set the following:
32-
- Repository Permissions
33-
- Contents: Read
34-
- Read branch protection rules
35-
- Pull requests: Read
36-
- Access PR details for compliance
37-
- Organization Permissions
38-
- Administration: Read
39-
- Read organization settings
40-
- Members: Read/Write
41-
- Manage team membership
42-
43-
4. Under Set installation scope:
44-
- Where can this GitHub App be installed?: Only on this account
22+
| Field | Value |
23+
| --------------------- | ----------------------------------------------- |
24+
| GitHub App name | `github-ops-app` (must be unique across GitHub) |
25+
| Homepage URL | Your organization's URL or repo URL |
26+
| Webhook > Webhook URL | Leave blank for now |
27+
| Webhook > Secret | Generate a strong secret (save this for later) |
28+
| Webhook > Active | **Uncheck** to disable webhooks initially |
29+
30+
> **Note**: Disable webhooks during creation since you may not know your
31+
> endpoint URL until after deployment. You'll configure webhooks and
32+
> subscribe to events in [Step 7](#step-7-configure-webhook-and-events).
33+
34+
### Configure Permissions
35+
36+
Under **Permissions**, set the following:
37+
38+
### Repository Permissions
39+
40+
| Permission | Access | Purpose |
41+
| ------------- | ------ | -------------------------------- |
42+
| Contents | Read | Read branch protection rules |
43+
| Pull requests | Read | Access PR details for compliance |
44+
45+
#### Organization Permissions
46+
47+
| Permission | Access | Purpose |
48+
| -------------- | ---------- | -------------------------- |
49+
| Members | Read/Write | Manage team membership |
50+
| Administration | Read | Read organization settings |
51+
52+
4. Set installation scope:
53+
54+
| Setting | Value |
55+
| --------------------------------------- | -------------------- |
56+
| Where can this GitHub App be installed? | Only on this account |
4557

4658
5. Click **Create GitHub App**
4759

@@ -73,13 +85,15 @@ On the app's settings page, find and save:
7385
## Step 5: Get Installation ID
7486

7587
After installation, you'll be redirected to a URL like:
88+
7689
```
7790
https://github.com/organizations/YOUR_ORG/settings/installations/12345678
7891
```
7992

8093
The number at the end (`12345678`) is your **Installation ID**.
8194

8295
Alternatively, use the GitHub API:
96+
8397
```bash
8498
# List installations (requires app JWT authentication)
8599
curl -H "Authorization: Bearer YOUR_JWT" \
@@ -115,25 +129,40 @@ After deploying your server, configure and enable webhooks:
115129

116130
1. Go to your GitHub App settings:
117131
`https://github.com/organizations/YOUR_ORG/settings/apps/YOUR_APP`
118-
2. On the **General** tab, under **Webhook**:
119-
- Set **Webhook URL** to your endpoint:
120-
- Lambda: `https://xxx.execute-api.region.amazonaws.com/webhooks`
121-
- Server: `https://your-domain.com/webhooks`
122-
- Check **Active** to enable webhooks
123-
- Click **Save changes**
124-
3. Go to the **Permissions & events** tab
125-
4. Scroll to **Subscribe to events** and check:
132+
133+
2. Set **Webhook URL** to your endpoint:
134+
135+
- Lambda: `https://xxx.execute-api.region.amazonaws.com/webhooks`
136+
- Server: `https://your-domain.com/webhooks`
137+
138+
3. Check **Active** to enable webhooks
139+
140+
4. Click **Save changes**
141+
142+
5. Under **Subscribe to events**, check:
143+
126144
- [x] **Pull request** - PR open, close, merge events
127145
- [x] **Team** - Team creation, deletion, changes
128146
- [x] **Membership** - Team membership changes
129-
5. Click **Save changes**
147+
148+
6. Click **Save changes**
149+
150+
## Using the App Manifest (Alternative)
151+
152+
For automated setup, use the manifest at `assets/github/manifest.json`:
153+
154+
1. Go to `https://github.com/settings/apps/new`
155+
2. Append `?manifest=` with URL-encoded manifest JSON
156+
3. Or use the manifest creation API
157+
158+
The manifest pre-configures all required permissions and events.
130159

131160
## Verification
132161

133162
Test your setup:
134163

135-
1. **Webhook delivery**: Check **Settings****Developer settings**
136-
**GitHub Apps** → your app → **Advanced****Recent Deliveries**
164+
1. **Webhook delivery**: Check **Settings****Developer settings** **GitHub
165+
Apps** → your app → **Advanced****Recent Deliveries**
137166

138167
2. **Create a test PR**: Open and merge a PR to a monitored branch to verify
139168
webhook reception

docs/okta-setup.md

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@ github-ops-app to sync Okta groups with GitHub teams.
1111
## Step 1: Create API Services Application
1212

1313
1. Log in to your **Okta Admin Console**
14+
1415
2. Navigate to **Applications****Applications**
16+
1517
3. Click **Create App Integration**
18+
1619
4. Select **API Services** and click **Next**
1720

1821
> API Services apps use OAuth 2.0 client credentials flow with no user
1922
> context, ideal for server-to-server integrations.
2023
2124
5. Enter application name: `github-ops-app` (or similar)
25+
2226
6. Click **Save**
2327

2428
## Step 2: Configure Client Authentication
@@ -64,12 +68,13 @@ On the **General** tab, find and save:
6468
## Step 5: Grant API Scopes
6569

6670
1. Go to the **Okta API Scopes** tab
71+
6772
2. Grant the following scopes:
6873

69-
| Scope | Purpose |
70-
|--------------------|-------------------------------|
71-
| `okta.groups.read` | Read group names and members |
72-
| `okta.users.read` | Read user profiles |
74+
| Scope | Purpose |
75+
| ------------------ | ---------------------------- |
76+
| `okta.groups.read` | Read group names and members |
77+
| `okta.users.read` | Read user profiles |
7378

7479
3. Click **Grant** for each scope
7580

@@ -82,22 +87,26 @@ API Services applications require an admin role to access Okta APIs. Without
8287
this, API calls will fail with permission errors even if scopes are granted.
8388

8489
1. Go to the **Admin roles** tab for your application
90+
8591
2. Click **Edit assignments**
92+
8693
3. Select one of the following roles:
8794

88-
| Role | Access Level |
89-
|---------------------|-----------------------------------------------|
90-
| **Read Only Admin** | Read access to all resources (recommended) |
91-
| **Group Admin** | Full access to groups only |
95+
| Role | Access Level |
96+
| ------------------- | ------------------------------------------ |
97+
| **Read Only Admin** | Read access to all resources (recommended) |
98+
| **Group Admin** | Full access to groups only |
9299

93100
4. If using **Group Admin**, optionally restrict to specific groups:
94-
- Under **Edit constraints for Group Administrator**, select specific
95-
groups or group types the app can access
101+
102+
- Under **Edit constraints for Group Administrator**, select specific groups
103+
or group types the app can access
104+
96105
5. Click **Save changes**
97106

98-
> **Note**: Read Only Admin is recommended for sync operations since it
99-
> provides sufficient access without write permissions. Group Admin is an
100-
> alternative if you need to limit the app's scope to group resources only.
107+
> **Note**: Read Only Admin is recommended for sync operations since it provides
108+
> sufficient access without write permissions. Group Admin is an alternative if
109+
> you need to limit the app's scope to group resources only.
101110
102111
## Step 7: Identify Your Okta Domain
103112

@@ -113,12 +122,12 @@ Use the domain without `https://` prefix for `APP_OKTA_DOMAIN`.
113122
The app needs to map Okta users to GitHub usernames. Determine which Okta user
114123
profile field contains GitHub usernames:
115124

116-
| Common Fields | Description |
117-
|--------------------|------------------------------------------|
118-
| `login` | Okta username (often email) |
119-
| `email` | User's email address |
120-
| `githubUsername` | Custom field (recommended) |
121-
| `nickName` | Sometimes used for GitHub username |
125+
| Common Fields | Description |
126+
| ---------------- | ---------------------------------- |
127+
| `login` | Okta username (often email) |
128+
| `email` | User's email address |
129+
| `githubUsername` | Custom field (recommended) |
130+
| `nickName` | Sometimes used for GitHub username |
122131

123132
### Adding a Custom GitHub Username Field (Recommended)
124133

@@ -141,13 +150,14 @@ rules:
141150

142151
**Example naming conventions:**
143152

144-
| Pattern | Example Groups |
145-
|----------------------|----------------------------------------------|
146-
| `github-{team}` | `github-engineering`, `github-platform` |
147-
| `gh-eng-{team}` | `gh-eng-frontend`, `gh-eng-backend` |
148-
| `Team - {name}` | `Team - Platform`, `Team - Security` |
153+
| Pattern | Example Groups |
154+
| --------------- | --------------------------------------- |
155+
| `github-{team}` | `github-engineering`, `github-platform` |
156+
| `gh-eng-{team}` | `gh-eng-frontend`, `gh-eng-backend` |
157+
| `Team - {name}` | `Team - Platform`, `Team - Security` |
149158

150159
Groups can be:
160+
151161
- Okta groups (manually managed)
152162
- Groups synced from Active Directory
153163
- Groups from other identity providers
@@ -192,18 +202,18 @@ APP_OKTA_SYNC_RULES='[
192202

193203
### Rule Fields
194204

195-
| Field | Description |
196-
|-------------------------|------------------------------------------------------|
197-
| `name` | Rule identifier (for logging) |
198-
| `enabled` | Enable/disable rule (default: `true`) |
199-
| `okta_group_pattern` | Regex to match Okta groups |
200-
| `okta_group_name` | Exact Okta group name (alternative to pattern) |
201-
| `github_team_prefix` | Prefix for generated GitHub team names |
202-
| `github_team_name` | Exact GitHub team name (overrides pattern) |
203-
| `strip_prefix` | Remove this prefix from Okta group name |
204-
| `sync_members` | Sync members between Okta and GitHub (default: `true`)|
205-
| `create_team_if_missing`| Auto-create GitHub teams if they don't exist |
206-
| `team_privacy` | GitHub team visibility: `secret` or `closed` |
205+
| Field | Description |
206+
| ------------------------ | ------------------------------------------------------ |
207+
| `name` | Rule identifier (for logging) |
208+
| `enabled` | Enable/disable rule (default: `true`) |
209+
| `okta_group_pattern` | Regex to match Okta groups |
210+
| `okta_group_name` | Exact Okta group name (alternative to pattern) |
211+
| `github_team_prefix` | Prefix for generated GitHub team names |
212+
| `github_team_name` | Exact GitHub team name (overrides pattern) |
213+
| `strip_prefix` | Remove this prefix from Okta group name |
214+
| `sync_members` | Sync members between Okta and GitHub (default: `true`) |
215+
| `create_team_if_missing` | Auto-create GitHub teams if they don't exist |
216+
| `team_privacy` | GitHub team visibility: `secret` or `closed` |
207217

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

@@ -221,6 +231,7 @@ Test your Okta configuration:
221231
```
222232

223233
Trigger a sync and verify:
234+
224235
1. POST to `/scheduled/okta-sync` endpoint
225236
2. Check logs for groups discovered and teams synced
226237
3. Verify GitHub team memberships match Okta groups
@@ -249,6 +260,7 @@ Trigger a sync and verify:
249260
### Rate limiting
250261

251262
Okta has API rate limits. If you hit limits:
263+
252264
- Reduce sync frequency
253265
- The app handles rate limit responses gracefully
254266

0 commit comments

Comments
 (0)