Skip to content

feat: add GitHub App installation token authentication for push/sync#177

Merged
philip-gai merged 6 commits into
actions:mainfrom
philip-gai:pgai/github-app-auth
Jun 23, 2026
Merged

feat: add GitHub App installation token authentication for push/sync#177
philip-gai merged 6 commits into
actions:mainfrom
philip-gai:pgai/github-app-auth

Conversation

@philip-gai

Copy link
Copy Markdown
Member

Add GitHub App installation token authentication for push/sync

Motivation

It is currently not possible to authenticate actions-sync with a GitHub App installation token (ghs_*); the push/sync flow calls GET /user, which App installation tokens cannot use (they have no user context and receive 403 Resource not accessible by integration). Users who want to avoid long-lived personal access tokens are therefore blocked. This revives the GitHub App authentication portion of #158.

What this does

  • Adds a --github-app-auth flag to push and sync. When set, the GET /user call is skipped and the destination repository is created under the owner taken from the destination repo name via POST /orgs/{owner}/repos.
  • Falls back to the repository response header to detect GitHub AE when creating a new repo, since the version can no longer be read from the user response under App auth.
  • Uses x-access-token as the git basic-auth username for the push, matching GitHub's documented convention for App installation tokens.
  • Adds unit tests covering both the new App-auth path and the existing PAT path (regression), plus an integration test in script/test-build that pushes with a ghs_* token; the test server now returns 403 on /api/v3/user for ghs_* tokens so the test fails if /user is ever hit.
  • Extracts the shared test mocks/fakes into a testutils_test.go helper.
  • Documents the flag and a dedicated "GitHub App authentication" section in the README.

Scope

This intentionally covers only the GitHub App authentication part of #158. The description-syncing and keep-description changes from that PR are out of scope here.

Constraints / behavior notes

  • The destination owner must be a pre-existing organization that the App is installed on. Installation tokens cannot create user-owned repositories (POST /user/repos requires user context that App tokens lack), so a user-account installation will not work. This was verified empirically against a real GHES instance.
  • Organization auto-creation and user impersonation (--actions-admin-user) rely on user/site-admin context and are not used under App auth.
  • The change is fully gated behind --github-app-auth (default false); the existing PAT code path is unchanged.

Required App permissions

Administration: Read & write (create repositories), Contents: Read & write, Metadata: Read-only, and Workflows: Read & write if synced repositories contain workflow files.

Validation

Validated end-to-end against a real GitHub Enterprise Server 3.21.1 instance:

  • A ghs_* installation token returns 403 on /api/v3/user, confirming the need to skip that call.
  • push --github-app-auth created the repository under the target org and pushed all refs; destination branch SHAs matched the source exactly.
  • A second push correctly detected the existing repository and re-synced (idempotent).
  • A user-account installation token was confirmed unable to create repositories (POST /user/repos returns 403), confirming the org-owner requirement.

go build, go vet, go test, and gofmt are clean.

Add a --github-app-auth flag so push/sync can authenticate with a GitHub App installation token (ghs_*). App tokens have no user context, so the GET /user call is skipped and repositories are created under the owner from the destination repo name.

Refs github/actions-persistence#1182
Add unit tests for getOrCreateGitHubRepo (previously untested) covering GitHub App auth and PAT regression paths: existing repo, create-under-user vs org, GHAE internal visibility (from both user and repo responses), create-failure wrapping, repo-get errors, org-already-exists fallback, and nil-login handling.
@philip-gai philip-gai marked this pull request as ready for review June 23, 2026 18:06
@philip-gai philip-gai requested a review from a team as a code owner June 23, 2026 18:06
Copilot AI review requested due to automatic review settings June 23, 2026 18:06
@philip-gai philip-gai requested a review from a team as a code owner June 23, 2026 18:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class support for authenticating push/sync using GitHub App installation tokens (ghs_*) by avoiding /user API calls and adjusting repo-creation behavior accordingly, while keeping the PAT path intact.

Changes:

  • Introduces --github-app-auth to route repo creation through org-owner derived from the destination owner/repo, and skips GET /user under App auth.
  • Refactors repo-creation logic to support AE detection without relying on the user response, and updates git basic-auth username to x-access-token.
  • Expands test coverage with shared test fakes/utilities, plus an integration test path that fails if /user is hit with ghs_* tokens.
Show a summary per file
File Description
test/github.go Test server now returns 403 on /api/v3/user for ghs_* tokens to enforce the “no user API under App auth” contract.
src/testutils_test.go Adds shared mocks/fakes/helpers for GitHub API and git push tests to reduce duplication.
src/push.go Adds --github-app-auth, refactors repo creation to support App tokens, and switches git basic-auth username to x-access-token.
src/push_test.go Adds/updates unit tests covering App-auth and PAT behaviors and moves shared test helpers out.
script/test-build Adds an integration test case exercising push --github-app-auth with a ghs_* token.
README.md Documents --github-app-auth and adds a GitHub App authentication section.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 6/6 changed files
  • Comments generated: 2
Comment thread src/push.go
Comment thread README.md Outdated
danwkennedy
danwkennedy previously approved these changes Jun 23, 2026

@danwkennedy danwkennedy left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM!

Comment thread src/push.go
- Error early when --github-app-auth and --actions-admin-user are both set, since App installation tokens cannot impersonate (no user/site-admin context).

- Correct the README App permission name to 'Metadata: Read-only'.
@philip-gai philip-gai merged commit 3f0f915 into actions:main Jun 23, 2026
4 checks passed
@philip-gai philip-gai deleted the pgai/github-app-auth branch June 23, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants