Skip to content

github-app-oauth: userCredentials lost after successful installation #7474

Description

@ryannle1

Problem

On Nango Cloud, a fresh github-app-oauth connection completes successfully but exposes only an installation token. The expiring GitHub App user credential is absent from connection_config.userCredentials. A consumer that requires the connecting user's current repository authority must reject this connection.

Reproduction

  1. Configure a GitHub App with Issues and Metadata read-only, selected repositories, user authorization during installation, expiring user authorization tokens, and callback https://api.nango.dev/oauth/callback.
  2. Create a github-app-oauth integration with the App ID, public link, signing key, OAuth client ID and client secret.
  3. Initiate Nango Connect from the product using a server-created session restricted to this integration and private user/workspace tags.
  4. Install and authorize the App on one disposable private repository, completing GitHub reauthentication.
  5. After Nango reports success, call GET /connections/{id}?provider_config_key=github-app-oauth&refresh_token=true with environment:connections:read_credentials scope.
  6. Observe the same missing user credential on subsequent reads. A single additional read with force_refresh=true changes the installation-token fingerprint but does not add a user credential.

Observed response shape

No credential values, connection IDs or customer information are included here.

{
  "provider": "github-app-oauth",
  "errors": [],
  "credentials": {
    "type": "APP",
    "access_token": "REDACTED",
    "expires_at": "REDACTED",
    "jwtToken": "REDACTED",
    "raw": {
      "token": "REDACTED",
      "expires_at": "REDACTED",
      "permissions": {"issues": "read", "metadata": "read"},
      "repository_selection": "selected"
    }
  },
  "connection_config": {
    "appPublicLink": "REDACTED",
    "installation_id": "REDACTED",
    "jwtToken": "REDACTED"
  }
}

Cloud log sequence

Observed September 9, 2026, UTC. Both authentication operations were marked successful.

Time Event
17:17:30.478 Token response received
17:17:30.512 OAuth connection successful
17:17:30.526 Post-connection operation started
17:17:30.759 Post-connection-creation script succeeded
17:17:30.816 App connection approved and credentials saved

At 17:36 UTC, the user credential remained absent before and after the forced refresh. The consumer’s server-side verification refused the connection; no provider proxy request or source import occurred.

Source investigation — likely overwrite, not a confirmed Cloud build diagnosis

Public source examined at 752cd127dfced933954a34c1cdc357570f95844c; the deployed Cloud revision is unknown.

  • The OAuth callback launches the post-connection hook without awaiting it, then finishes the installation using the earlier connectionConfig object.
  • The GitHub post-connection hook saves the OAuth2 credential under userCredentials after reading /user.
  • Installation completion passes its configuration to upsertConnection, whose existing-row update replaces connection_config instead of merging the newly stored hook fields.

The observed hook-success-before-installation-save ordering is consistent with overwriting userCredentials and handle. The public response formatter passes through the configuration, so serialization does not explain the missing field in the examined revision.

Expected: preserve the current authorizing user's credential through installation completion and reconnect, independently of callback timing, while retaining the installation credential. A fix should cover the hook finishing both before and after the installation write, and repeated user-token refreshes.

This initial-authorization failure precedes the repeated-refresh scenario in #6136; this report does not claim to reproduce that issue.

Can you confirm whether this overwrite exists in Cloud and provide a supported fix or connection flow that reliably preserves the expiring user credential?

No activity

Activity on this issue will appear here.

Activity

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

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