Skip to content

Conversation

@sreejesh123
Copy link

@sreejesh123 sreejesh123 commented Jul 4, 2025

Resolves #977


Before the change?

After the change?

Pull request checklist

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)

Does this introduce a breaking change?

Please see our docs on breaking changes to help!

  • Yes
  • No

…ations#977)

This commit addresses issue integrations#977 by introducing an automatic token refresh mechanism for GitHub App-based authentication. When using short-lived GitHub App tokens (JWT + installation token), the provider now refreshes the token transparently before expiry, avoiding auth failures during long-lived Terraform runs or plan/apply cycles.

Key enhancements:
- Added `NewRefreshingTokenSource()` to wrap token acquisition and refresh.
- Refactored `Config.AuthenticatedHTTPClient()` to detect GitHub App env vars (`GITHUB_APP_ID`, `GITHUB_APP_INSTALLATION_ID`, `GITHUB_APP_PEM` or `GITHUB_APP_PEM_FILE`) and enable refreshable OAuth2 token source.
- Fallbacks gracefully to using a Personal Access Token (PAT) when `GITHUB_TOKEN` is set.
- Environment-based discovery of GitHub App credentials avoids Terraform schema changes.
- Added unit tests covering:
  - Refreshing logic (initial, expired, and error conditions)
  - Config behavior (anonymous and authenticated client behavior)
  - Error cases for missing App ID, installation ID, or PEM
- No change to existing configuration schema or behavior for current users using PAT-based authentication.

This upgrade enables more resilient GitHub App usage and prepares the provider for robust automation scenarios.
…ations#977)

This commit addresses issue integrations#977 by introducing an automatic token refresh mechanism for GitHub App-based authentication. When using short-lived GitHub App tokens (JWT + installation token), the provider now refreshes the token transparently before expiry, avoiding auth failures during long-lived Terraform runs or plan/apply cycles.

Key enhancements:
- Added `NewRefreshingTokenSource()` to wrap token acquisition and refresh.
- Refactored `Config.AuthenticatedHTTPClient()` to detect GitHub App env vars (`GITHUB_APP_ID`, `GITHUB_APP_INSTALLATION_ID`, `GITHUB_APP_PEM` or `GITHUB_APP_PEM_FILE`) and enable refreshable OAuth2 token source.
- Fallbacks gracefully to using a Personal Access Token (PAT) when `GITHUB_TOKEN` is set.
- Environment-based discovery of GitHub App credentials avoids Terraform schema changes.
- Added unit tests covering:
  - Refreshing logic (initial, expired, and error conditions)
  - Config behavior (anonymous and authenticated client behavior)
  - Error cases for missing App ID, installation ID, or PEM
- No change to existing configuration schema or behavior for current users using PAT-based authentication.

This upgrade enables more resilient GitHub App usage and prepares the provider for robust automation scenarios.
@kishaningithub
Copy link

@nickfloyd Would be great if this PR can be reviewed!

Copy link
Contributor

@deiga deiga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @sreejesh123 👋

Thank you for your contribution!

There are a few details I'd need your help with to understand your proposal :)

  • You seem to be relying on ENV variables for the App identification, that won't work. You would need to use the parameters given to the provider
  • You built a whole custom token refreshingSource, did you try using https://pkg.go.dev/golang.org/x/oauth2#Config.Client which looks like it would already include a lot of the logic you needed to create
  • I don't think there should be a need to add a new library for doing the token refresh, but I might be wrong

@github-project-automation github-project-automation bot moved this from 🆕 Triage to 🏗 In progress in 🧰 Octokit Active Nov 26, 2025
@sreejesh123
Copy link
Author

Thanks a lot for the reply, appreciate taking time to review , please see answers inline

  • You seem to be relying on ENV variables for the App identification, that won't work. You would need to use the parameters given to the provider

Been a while after I did this , I will take a look why I used os.env , not sure if it was for local
Setup, might be I did overlook the actual runtime requirement . I will
Cross check and update the pr.

I did explore oauth2.Config.Client, but GitHub App installation tokens do not follow standard OAuth2 refresh token mechanics.

GitHub Apps require this flow:
1. Create a short-lived JWT signed with the app’s private key
2. Exchange that JWT for an installation access token
3. Refresh by repeating steps 1–2 (no long-lived refresh token exists)

Since this flow isn’t compatible with oauth2.Config, I implemented a custom TokenSource that performs the GitHub-specific JWT → installation-token exchange. If this is my misunderstanding please let me know. Happy to adjust the structure if there’s a preferred pattern within the provider.

  • I don't think there should be a need to add a new library for doing the token refresh, but I might be wrong

The additional library is used only for securely generating the required JWT for GitHub App authentication.

If you prefer not to introduce this dependency, I can alternatively use the built-in Go crypto packages and re-implement the minimal signing logic.
However, the dedicated library reduces code size and avoids re-implementing JWT logic, so I’d appreciate guidance on which direction you prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

app_auth credentials expire after an hour

3 participants