-
Notifications
You must be signed in to change notification settings - Fork 2
fix: use ghinstallation for GitHub App token refresh #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughReplaces manual GitHub App JWT handling with ghinstallation-based App/Installation transports and an oauth2 TokenSource; adds indirect GitHub/JWT deps and comprehensive tests for App and PAT authentication, token refresh/expiry, and misconfiguration handling. Changes
Sequence Diagram(s)sequenceDiagram
participant App as Application
participant GHT as ghinstallation<br/>Transport
participant TS as ghinstallationTokenSource
participant GH as GitHub API
participant GQL as GraphQL Client
App->>GHT: Initialize transport (AppID, AppKey[, EnterpriseURL])
App->>TS: Wrap GHT as oauth2 TokenSource
App->>GQL: Create GraphQL client using TS
GQL->>TS: Request token
TS->>GHT: Ask for installation token
GHT->>GH: Use JWT to request installation token
GH-->>GHT: Return installation token (with expiry)
GHT-->>TS: Supply oauth2 token
TS->>TS: Cache token (expiry)
TS-->>GQL: Return oauth2.Token
note over GHT,TS: On expiry, GHT regenerates JWT and refreshes installation token automatically
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
7248766 to
2d4bfae
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@pkg/connector/connector.go`:
- Around line 267-309: The REST clients appClient and ghClient are not
configured for GitHub Enterprise because only appTransport.BaseURL and
installTransport.BaseURL are set; call client.WithEnterpriseURLs(instanceURL) on
both github.Client instances (appClient and ghClient) when instanceURL is
non-empty and not equal to githubDotCom so their BaseURL fields point at the
enterprise API; locate where appClient is created after
ghinstallation.NewAppsTransport and where ghClient is created after
ghinstallation.New and invoke WithEnterpriseURLs using the same instanceURL
logic as used for appTransport/installTransport, matching the pattern used by
newGitHubClient for PAT auth.
- Around line 394-406: The Token() implementation on ghinstallationTokenSource
returns an oauth2.Token with no Expiry so oauth2.ReuseTokenSource treats it as
non-expiring; update Token() to set the token Expiry (e.g., Expiry: time.Now())
so the oauth2 client will re-evaluate and allow ghinstallation.Transport to
refresh tokens. Modify ghinstallationTokenSource.Token to import time, call
g.transport.Token(context.Background()), and return &oauth2.Token{AccessToken:
token, Expiry: time.Now()} (ensuring use of the ghinstallationTokenSource,
Token(), ghinstallation.Transport and oauth2.Token symbols referenced).
🧹 Nitpick comments (1)
pkg/connector/connector_test.go (1)
90-95: Optional: track the skipped GitHub App test.
Consider linking this to an issue or moving it under an integration test tag so it doesn’t stay skipped indefinitely.
Replace manual JWT handling with ghinstallation/v2 library to fix token expiration issues on long-running syncs. Problem: JWT tokens (10-min expiry) were generated once at startup and reused, causing 401 errors when installation tokens expired. Solution: Use ghinstallation which automatically regenerates JWTs and refreshes installation tokens as needed. Changes: - Add ghinstallation/v2 dependency - Replace appTokenRefresher with ghinstallationTokenSource - Add tests for token refresh behavior - Remove dead code (getClientToken, loadPrivateKeyFromString) Fixes ConductorOne#115 Co-Authored-By: Claude <[email protected]>
- Handle Enterprise SAML error in hasSAML() to prevent sync failures when org-level SAML is disabled in favor of Enterprise SAML - Configure Enterprise URLs on appClient and ghClient for GitHub Enterprise instances (addresses CodeRabbit feedback) - Set token Expiry from ghinstallation transport for proper oauth2 token refresh behavior (addresses CodeRabbit feedback) Co-Authored-By: Claude <[email protected]>
ac67be8 to
1b71e4b
Compare
- Fix errcheck: handle w.Write return values in tests - Fix goconst: extract repeated test URL path to constant - Fix gocritic ifElseChain: add nolint directive (switch inappropriate) - Fix nilerr: rename variable and add nolint for intentional fallback - Fix unused: remove unused getInstallationToken function - Fix gosec G101: add nolint for test constant (not credentials) - Remove unused io import Co-Authored-By: Claude <[email protected]>
|
We are actively reviewing this and investigating alternative solutions. |
Note
🤖 Generated with Claude Code
Fixes #115
Summary
Replace manual JWT handling with
ghinstallation/v2library to fix token expiration issues on long-running syncs. Also fixes Enterprise SAML handling and GitHub Enterprise URL configuration.Problem
When using GitHub App authentication, the connector fails with 401 Unauthorized errors after ~10 minutes because:
appTokenRefresher.jwttokenAdditional issues found in production:
4. REST clients not configured with Enterprise URLs for GitHub Enterprise instances
5. Token expiry not set, causing oauth2 to cache tokens indefinitely
6. Enterprise SAML error crashes sync when org-level SAML is disabled in favor of Enterprise SAML
Solution
Use
github.com/bradleyfalzon/ghinstallation/v2- the officially recommended library by go-github that:Plus additional fixes:
WithEnterpriseURLs()on REST clients for GitHub EnterprisehasSAML()gracefully (return false instead of failing)Changes
ghinstallation/v2dependencyappTokenRefresherwithghinstallationTokenSourcewrapperappClientandghClient(addresses CodeRabbit feedback)Expiryfrom transport for oauth2 refresh (addresses CodeRabbit feedback)hasSAML()to prevent sync failuresgetClientToken,loadPrivateKeyFromString,appTokenRefresher)Testing
Production Validation
This fix has been deployed and validated in production:
Rollback Plan
Revert PR - PAT authentication is unchanged, only GitHub App auth is affected.
Summary by CodeRabbit
New Features
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.