Repository navigation
refactor!: adopt github-app-setup-go, update dependencies, and fix security and sync bugs - #28
Merged
Merged
Conversation
CI runs golangci-lint, a go mod tidy check, the tests with the race detector, govulncheck, linux amd64 and arm64 builds of the server and the lambda function, and a container image build, on every pull request instead of only those targeting main. Every action is pinned to a commit of its latest release, the go version comes from go.mod, and checkouts don't persist credentials. Dependabot never ran: its config was at .github/.dependabot.yaml, a path GitHub doesn't read. It moves to .github/dependabot.yaml, groups its updates, and also watches the Dockerfile's base images. The release rules listed feat:minor and refactor:minor. A custom rule that matches a commit's type wins over the commit analyzer's "breaking change -> major" rule, so a feat! or refactor! commit was released as a minor version. Those rules are removed. The release now computes the version first (dry_run), builds the server and lambda binaries for amd64 and arm64 and the container image, and only then creates the tag, so a failed build leaves no tag behind. The semantic check no longer checks out code. It runs on pull_request_target, with a token that can write to the repository, and the action doesn't need the code. The Makefile gains help, lint, fmt, vuln, tidy, check, cover, image, and local-run targets, runs tests with the race detector, and stamps the version into the binaries. build-server is renamed build and writes dist/github-ops-app, and the lambda binary is built with the lambda.norpc tag for the provided.al2023 runtime. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rework the service around github-app-setup-go, update every dependency, and fix the security and correctness problems a full review found. Dependencies: - go 1.24.4 to 1.27.3; go-github v79 to v93, okta-sdk-golang v6 to v8, slack-go v0.17.3 to v0.35.0, and every other module to its latest - adopt github-app-setup-go v0.7.1, and drop cockroachdb/errors for the standard library, which removes sentry-go and its dependencies; govulncheck reported 11 reachable vulnerabilities before and none after Structure: - internal/service runs both entry points on a github-app-setup-go runtime: the server loads at startup and reloads on SIGHUP or when the installer saves credentials, and lambda loads on first use and retries a failed load on the next invocation, instead of failing every invocation until the container is recycled - an optional manifest installer at /setup creates the GitHub App and saves its credentials to an env file or SSM; once an app is registered it refuses new codes - internal/config validates everything at startup and reports every problem at once; any APP_ value may be an SSM ARN, in any partition - the installation is looked up from the org when no id is set - /healthz and /readyz; JSON responses; the scenarios in fixtures/scenarios.json run as go tests in e2e/, replacing cmd/verify - the server waits for running syncs on shutdown; the image runs as a non-root user Security: - webhooks must be signed; the admin endpoints are disabled without APP_ADMIN_TOKEN, which is compared in constant time; EventBridge invocations run scheduled actions without it - the app manifest is private, and events from other orgs are ignored - slack text from GitHub and Okta is escaped, and okta usernames are validated as GitHub logins before they are used in API paths - auth headers are sent only to the GitHub API host, and the installation token cache no longer races Fixes: - the manifest used permission names GitHub doesn't know and lacked administration and statuses read, so branch protection and commit statuses were silently skipped; read errors now fail the check - PR compliance: read every page of reviews, statuses, and check runs; comments don't revoke approvals; neutral and skipped checks pass; maintainers are recognized; every bypass is reported, not only admins' - security alerts: read every page, not only the first 100 of each kind - okta sync: keep PASSWORD_EXPIRED, LOCKED_OUT, and RECOVERY users; honor create_team_if_missing; find teams whose slug differs from their name; don't re-invite pending invitees or remove child-team members, and don't report a 404 as a removal; report groups whose members can't be read; don't sync two groups into one team; retry rate-limited requests - syncs requested while one runs are coalesced and the follow-up always runs; webhook-triggered syncs run only for teams a rule manages, only for renames among edits, and after the response in server mode - orphaned users: reuse the synced member lists, and skip detection rather than report the members of a team that couldn't be found - slack: fit reports to Slack's block and text limits, and time out requests - lambda: pass query strings, cookies, and base64 bodies through from API Gateway; ping and unhandled events no longer return 400 BREAKING CHANGE: APP_DEBUG_ENABLED, APP_PORT, and APP_OKTA_KEY_ID are replaced by APP_LOG_LEVEL, APP_LISTEN_ADDR, and APP_OKTA_PRIVATE_KEY_ID, and setting an old name stops the service. The webhook secret is required, the admin API is disabled without a token, invalid or partial configuration stops the service, create_team_if_missing defaults to false, and the GitHub App needs administration and commit statuses read. See docs/upgrading-to-v1.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- README: the endpoints and who may call them, every variable with its default, the sync rule fields, sync safety, and how each feature works - github app setup: the installer, the permissions the app needs and what each is for, and the optional installation id - okta setup: make the github username attribute read only for users, the synced user statuses, rule validation, and create_team_if_missing - slack setup: drop scopes the app doesn't use, and describe escaping, message limits, and the slack-test action - lambda: the events, retried configuration loads, timeouts, and the installer with SSM storage - AGENTS.md: the current packages, make targets, standard library errors, slog key-value pairs, configuration rules, and security rules Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is a full review of the app with every finding fixed. It also updates all Go modules and GitHub Actions, adopts github-app-setup-go v0.7.1, and brings CI, the Makefile, and releases in line with the other cruxstack Go repos. It contains breaking changes and will release as v1.0.0. docs/upgrading-to-v1.md lists every one.
The PR has three commits, and each builds and passes its tests on its own:
ci:pinned actions, lint, govulncheck, a tidy check, amd64 and arm64 builds, and an image build. It also fixes dependabot, which never ran because its config was at.github/.dependabot.yaml, and a release rule that turned breaking changes into minor versions. Releases now build binaries before tagging.refactor!:the code, dependencies, and fixes below.docs:README, setup guides, the Lambda guide, and AGENTS.md.Dependencies
cockroachdb/errorsis replaced by the standard library, which also removes sentry-go and its dependencies.github-app-setup-go
Both entry points now run on its runtime:
SIGHUPor when the installer saves credentials./setupcreates the GitHub App from a manifest and saves its credentials to an env file or SSM. Once an app is registered, it refuses new codes.Security
public: true, so any account could install the app and send it signed events. It is now private, and events from other orgs are ignored.Fixes
create_team_if_missingis honored.Testing
make checkpasses: golangci-lint reports 0 issues, the tests pass with the race detector, govulncheck is clean, andgo mod tidyis clean.e2e/runs the 22 scenarios infixtures/scenarios.jsonagainst the real service and mock GitHub, Okta, and Slack APIs, replacingcmd/verify.Follow-ups
./cmd/lambdawithgolang:1.24-alpine, which can't build a Go 1.27 module. It also setsAPP_OKTA_KEY_ID, which the app never read; the correct name isAPP_OKTA_PRIVATE_KEY_ID. Its 30-second default timeout is too short for a sync.githubUsernameattribute should be read-only for users. Otherwise a user can point it at another GitHub account and give that account their team access.🤖 Generated with Claude Code