Skip to content

fix: do not shadow caller GITHUB_TOKEN with GITHUB_APM_PAT#21

Merged
danielmeppiel merged 2 commits intomainfrom
fix/token-shadowing-gh-aw
Mar 26, 2026
Merged

fix: do not shadow caller GITHUB_TOKEN with GITHUB_APM_PAT#21
danielmeppiel merged 2 commits intomainfrom
fix/token-shadowing-gh-aw

Conversation

@danielmeppiel
Copy link
Copy Markdown
Collaborator

Problem

When a caller provides GITHUB_TOKEN via step/job-level env: (e.g., a GitHub App token minted by gh-aw for cross-org private repo access), the action was unconditionally setting GITHUB_APM_PAT to its default github-token input (${{ github.token }}).

APM CLI's token resolution precedence is:

GITHUB_APM_PAT > GITHUB_TOKEN > GH_TOKEN

Since GITHUB_APM_PAT takes priority, APM would use the wrong token (the Actions workflow default, scoped only to the current repo) instead of the caller's intentional GITHUB_TOKEN (the App token with cross-org access). This caused "Repository not found" / "Authentication failed" errors for users installing packages from cross-org private repos.

Root Cause

Commit cc84c04 (v1.4.0) added:

process.env.GITHUB_APM_PAT ??= githubToken;

where githubToken = core.getInput('github-token') defaults to ${{ github.token }} — the Actions runner's automatic token, not any env var.

The ??= operator correctly avoids clobbering an explicitly set GITHUB_APM_PAT, but it does not account for the case where the caller has set GITHUB_TOKEN (not GITHUB_APM_PAT) to a higher-specificity token. The result is a token mismatch:

Variable Value Source
GITHUB_TOKEN GitHub App token (cross-org) Caller via step env:
GITHUB_APM_PAT ${{ github.token }} (workflow-repo only) Auto-set by action
APM uses GITHUB_APM_PAT (wrong!) Precedence rules

Fix

Only forward the github-token input to GITHUB_APM_PAT when GITHUB_TOKEN was not already present in the environment. When a caller has explicitly provided GITHUB_TOKEN, they control auth and we must not inject a lower-specificity token into the higher-precedence variable.

const callerProvidedToken = process.env.GITHUB_TOKEN != null;
process.env.GITHUB_TOKEN ??= githubToken;
if (!callerProvidedToken) {
  process.env.GITHUB_APM_PAT ??= githubToken;
}

Testing

  • Updated existing test to verify GITHUB_APM_PAT is not set when GITHUB_TOKEN is already present
  • Added new test specifically reproducing the gh-aw scenario (App token in env, default token in input)
  • All 47 tests pass, typecheck and lint clean

Affected Users

Any gh-aw user with dependencies.github-app configuration that uses apm-action >= v1.4.0. The user's workflow generates a GitHub App token with cross-org access, sets it as GITHUB_TOKEN, but the action shadows it with the default token via GITHUB_APM_PAT.

Fixes microsoft/apm#425

When a caller provides GITHUB_TOKEN via step/job-level env: (e.g., a
GitHub App token minted by gh-aw for cross-org private repo access),
the action must not set GITHUB_APM_PAT to the default github.token.

APM CLI token precedence is GITHUB_APM_PAT > GITHUB_TOKEN > GH_TOKEN.
Before this fix, GITHUB_APM_PAT was unconditionally set to the action
default (github.token, scoped to the workflow repo only), which
shadowed the caller intentional GITHUB_TOKEN in APM resolution chain.
This caused "Repository not found" / "Authentication failed" errors
when installing packages from cross-org private repos.

Fix: only forward github-token to GITHUB_APM_PAT when GITHUB_TOKEN
was NOT already present in the environment, indicating no caller has
provided a higher-specificity token.

Fixes microsoft/apm#425

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 26, 2026 16:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes token precedence issues when callers provide GITHUB_TOKEN via workflow/step env: by avoiding injecting the action’s default github-token into the higher-precedence GITHUB_APM_PAT, preventing accidental auth shadowing in APM.

Changes:

  • Update token-export logic to only set GITHUB_APM_PAT when GITHUB_TOKEN wasn’t already present.
  • Extend/add tests to ensure caller-provided GITHUB_TOKEN is preserved and not shadowed.
  • Regenerate dist/index.js to reflect the source change.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/runner.ts Adjusts env var forwarding to avoid shadowing caller GITHUB_TOKEN with GITHUB_APM_PAT.
src/tests/runner.test.ts Adds/updates tests covering the shadowing scenario (incl. gh-aw reproduction).
dist/index.js Compiled output reflecting src/runner.ts changes.

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

Addresses Copilot review: an empty-string GITHUB_TOKEN is not nullish,
so ??= would not overwrite it. Use truthiness check (!!) instead of
!= null so both empty-string and undefined are treated as "no caller
token", ensuring the github-token input is forwarded correctly.

Adds regression test for the empty-string edge case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel danielmeppiel merged commit a190b0b into main Mar 26, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: apm pack --target claude produces empty bundle when skills installed to .github/

2 participants