Description
GitHubAppAuthClient (apps/backend/src/lib/github/app-auth.ts) manages installation-token caching, near-expiry refresh (isNearExpiry()/tokenSkewMs), and a single automatic retry-on-401 with forced cache invalidation (requestWithInstallationAuth()), but contains no logging anywhere in the class — cache hits, forced refreshes, 401-triggered re-authentication, and every GitHubAppAuthError code path (RATE_LIMITED, UPSTREAM_ERROR, AUTHENTICATION_ERROR, NETWORK_ERROR) are all silent. This is the same auth boundary the webhook middleware in github-webhook.ts already instruments with createLogger({ service: 'github-webhook-auth' }), but the token-issuing side of the same integration has no equivalent visibility, making installation-token incidents (e.g. a misconfigured GITHUB_APP_PRIVATE_KEY or an expired installation) hard to diagnose from logs alone.
Requirements and Context
- Add a
createLogger({ service: 'github-app-auth' }) instance and log: cache hit vs. forced/expiry-triggered refresh in getInstallationAuthContext(), the 401-triggered retry path in requestWithInstallationAuth() (including that the cached token was invalidated), and every GitHubAppAuthError thrown from fetchInstallationToken()/buildHttpError() with its code and retryable fields.
- Do not log the raw token value or the signed JWT anywhere — only metadata (installation ID, expiry, error code).
- Preserve all existing thrown-error contracts (
GitHubAppAuthError code/message/retryable) so github-app-auth.service.ts and its tests are unaffected.
- Validate against
apps/backend/src/lib/github/app-auth.test.ts, which exercises the cache/refresh/401-retry paths this change instruments.
Suggested Execution
Branch: feat/github-app-auth-client-logging
Implement Changes
- Add
createLogger({ service: 'github-app-auth' }) to apps/backend/src/lib/github/app-auth.ts and inject log calls into getInstallationAuthContext(), requestWithInstallationAuth(), and buildHttpError().
- Log
installationId and computed isNearExpiry outcome on every cache check.
- Log the 401 →
invalidateCachedToken() → forced-refresh sequence in requestWithInstallationAuth() as a single correlated warn-level event.
Test and Commit
Run pnpm test -- app-auth with the existing suite unmodified to confirm behavior parity, and add an assertion (via a mocked logger) that a 401 response triggers exactly one "token invalidated and refreshed" log entry.
Example Commit Message
feat(github-app-auth): add structured logging for token lifecycle
Co-authored-by: <your-name>
Guidelines
- Branch off
main, keep PRs focused on one issue
- All new code must include unit or integration tests
- Ensure
pnpm lint and pnpm typecheck pass before review
- Link this issue in your PR description
- Request review from at least one maintainer before merging
Description
GitHubAppAuthClient(apps/backend/src/lib/github/app-auth.ts) manages installation-token caching, near-expiry refresh (isNearExpiry()/tokenSkewMs), and a single automatic retry-on-401 with forced cache invalidation (requestWithInstallationAuth()), but contains no logging anywhere in the class — cache hits, forced refreshes, 401-triggered re-authentication, and everyGitHubAppAuthErrorcode path (RATE_LIMITED,UPSTREAM_ERROR,AUTHENTICATION_ERROR,NETWORK_ERROR) are all silent. This is the same auth boundary the webhook middleware ingithub-webhook.tsalready instruments withcreateLogger({ service: 'github-webhook-auth' }), but the token-issuing side of the same integration has no equivalent visibility, making installation-token incidents (e.g. a misconfiguredGITHUB_APP_PRIVATE_KEYor an expired installation) hard to diagnose from logs alone.Requirements and Context
createLogger({ service: 'github-app-auth' })instance and log: cache hit vs. forced/expiry-triggered refresh ingetInstallationAuthContext(), the 401-triggered retry path inrequestWithInstallationAuth()(including that the cached token was invalidated), and everyGitHubAppAuthErrorthrown fromfetchInstallationToken()/buildHttpError()with itscodeandretryablefields.GitHubAppAuthErrorcode/message/retryable) sogithub-app-auth.service.tsand its tests are unaffected.apps/backend/src/lib/github/app-auth.test.ts, which exercises the cache/refresh/401-retry paths this change instruments.Suggested Execution
Branch:
feat/github-app-auth-client-loggingImplement Changes
createLogger({ service: 'github-app-auth' })toapps/backend/src/lib/github/app-auth.tsand inject log calls intogetInstallationAuthContext(),requestWithInstallationAuth(), andbuildHttpError().installationIdand computedisNearExpiryoutcome on every cache check.invalidateCachedToken()→ forced-refresh sequence inrequestWithInstallationAuth()as a single correlated warn-level event.Test and Commit
Run
pnpm test -- app-authwith the existing suite unmodified to confirm behavior parity, and add an assertion (via a mocked logger) that a 401 response triggers exactly one "token invalidated and refreshed" log entry.Example Commit Message
Guidelines
main, keep PRs focused on one issuepnpm lintandpnpm typecheckpass before review