Skip to content

GitHub App JWT token expires after 10 minutes, causing 401 on subsequent syncs #115

@abebars

Description

@abebars

Problem

When using GitHub App authentication, the connector fails with 401 Unauthorized errors on subsequent syncs after approximately 10 minutes.

Root Cause

The JWT token used for GitHub App authentication is generated once at connector initialization and stored statically in appTokenRefresher.jwttoken. GitHub App JWTs have a maximum lifetime of 10 minutes.

When the installation token expires (~1 hour) and needs to be refreshed, the appTokenRefresher.Token() method attempts to use the same expired JWT to request a new installation token, resulting in a 401 error from GitHub.

Code Flow

Initialization:
1. getClientToken() generates JWT (expires in 10 min)
2. JWT stored in appTokenRefresher.jwttoken
3. First installation token obtained successfully

After ~1 hour (installation token expires):
4. ReuseTokenSource calls appTokenRefresher.Token()
5. Token() reuses the SAME expired JWT from step 2
6. GitHub returns 401 Unauthorized

Relevant Code

pkg/connector/connector.go lines 291-297:

ts = oauth2.ReuseTokenSource(
    &oauth2.Token{...},
    &appTokenRefresher{
        ctx:            ctx,
        instanceURL:    ghc.InstanceUrl,
        installationID: installation.GetID(),
        jwttoken:       jwttoken,  // Static JWT that expires in 10 min
    },
)

Suggested Fix

Use github.com/bradleyfalzon/ghinstallation/v2 - the officially recommended library by go-github that handles JWT and installation token refresh automatically.

This library:

  • Regenerates JWTs as needed before they expire
  • Automatically refreshes installation tokens
  • Is thread-safe and battle-tested
  • Supports GitHub Enterprise

Impact

  • All GitHub App-based authentication fails after ~10 minutes
  • Affects long-running syncs and scheduled sync jobs
  • PAT-based authentication is not affected

Environment

  • baton-github version: latest
  • Authentication method: GitHub App

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions