Skip to content

fix: credential fill returns garbage token in tokenless CI (gh-aw regression)#356

Merged
danielmeppiel merged 1 commit intomainfrom
fix/credential-fill-ghaw-regression
Mar 18, 2026
Merged

fix: credential fill returns garbage token in tokenless CI (gh-aw regression)#356
danielmeppiel merged 1 commit intomainfrom
fix/credential-fill-ghaw-regression

Conversation

@danielmeppiel
Copy link
Collaborator

Problem

v0.8.1 introduced resolve_credential_from_git() with GIT_ASKPASS=echo. In GitHub Actions (where GITHUB_TOKEN is not a default environment variable), this causes git credential fill to echo the prompt text as the password value — a garbage token that corrupts the clone URL and breaks all clone methods, even for public repos.

Impact: gh-aw CI broken on v0.8.1 — failing run

Root Cause

GIT_ASKPASS=echo + no credential helper configured → git asks for password → echo outputs the prompt → password=Password for 'https://github.com': → token manager accepts garbage → has_token=True → locked-down git env → all clone methods fail.

Fix

Credential fill (defense in depth):

  • GIT_ASKPASS='' (empty string) — credential fill fails cleanly when no helper configured
  • New _is_valid_credential_token() rejects whitespace, prompt fragments, and >1024-char tokens

Future regression protection:

  • test-release-validation.sh: new test_ghaw_compat() — tokenless isolated install + pack
  • build-release.yml: new gh-aw-compat job using microsoft/apm-action@v1 — gates publish-pypi/homebrew

Note

apm-action has a contributing issue: it declares github-token input but never passes it to APM subprocess as GITHUB_TOKEN. Separate PR needed there. This PR fixes APM to be resilient regardless.

Test Results

  • 22 new tests added to test_token_manager.py
  • Full suite: 2484 passed, 0 failed

GIT_ASKPASS=echo caused git credential fill to echo prompt text as the
password value. In GH Actions (where GITHUB_TOKEN is not a default env
var), this garbage token triggered locked-down git env, breaking all
clone methods — even for public repos.

Fixes:
- GIT_ASKPASS='' (empty) instead of 'echo' — credential fill fails
  cleanly when no helper is configured
- Token validation rejects whitespace, prompt fragments, >1024 chars

Protection against future regressions:
- Release validation: tokenless install+pack test (test_ghaw_compat)
- CI workflow: gh-aw-compat job gates publish-pypi/homebrew using
  microsoft/apm-action@v1 with the just-released binary

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 18, 2026 16:07
@danielmeppiel danielmeppiel merged commit 146fa50 into main Mar 18, 2026
14 checks passed
@danielmeppiel danielmeppiel deleted the fix/credential-fill-ghaw-regression branch March 18, 2026 16:09
Copy link
Contributor

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 a regression in tokenless CI where git credential fill could return prompt text as a “token”, breaking public repo cloning; adds validation + CI gates to prevent recurrence.

Changes:

  • Set GIT_ASKPASS to an empty string for git credential fill and reject invalid “tokens” (prompt fragments/whitespace/overlong).
  • Add unit tests covering the new credential token validation and the GIT_ASKPASS env behavior.
  • Add GH-AW compatibility coverage in release-validation script and gate stable releases via a new gh-aw-compat job.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/apm_cli/core/token_manager.py Hardens git-credential fallback by preventing prompt echo and validating returned “password” values before accepting as tokens.
tests/test_token_manager.py Adds test coverage for GIT_ASKPASS handling and credential token validation edge cases.
scripts/test-release-validation.sh Adds a tokenless “isolated install + pack” scenario to catch GH-AW regressions in binary isolation testing.
.github/workflows/build-release.yml Introduces a gh-aw-compat gate to block publishing when the GH-AW flow fails.

Comment on lines +214 to +217
def test_none_coerced_invalid(self):
"""None would fail the truthiness check (caller already guards this)."""
assert not GitHubTokenManager._is_valid_credential_token('')

Comment on lines +557 to +588
# GH-AW Compatibility Gate — validates the released binary works in the
# exact flow GitHub Agentic Workflows uses (isolated install + pack, no token).
# Gates publish-pypi and update-homebrew so broken versions don't reach stable distribution.
gh-aw-compat:
name: GH-AW Compatibility
needs: [create-release]
if: github.ref_type == 'tag'
runs-on: ubuntu-24.04
steps:
- name: Install and pack with apm-action
uses: microsoft/apm-action@v1
id: pack
with:
dependencies: |
- microsoft/apm-sample-package
isolated: 'true'
pack: 'true'
archive: 'true'
target: claude
apm-version: ${{ github.ref_name }}
working-directory: /tmp/gh-aw-compat-test

- name: Verify bundle
run: |
test -f "${{ steps.pack.outputs.bundle-path }}"
echo "✅ GH-AW compatibility test passed"

# Publish to PyPI (only stable releases from public repo)
publish-pypi:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: [test, build, integration-tests, release-validation, create-release]
needs: [test, build, integration-tests, release-validation, create-release, gh-aw-compat]
danielmeppiel added a commit to microsoft/apm-action that referenced this pull request Mar 19, 2026
The action declares a github-token input (defaulting to github.token)
but never reads it or exports it to the subprocess environment. GitHub
Actions does not auto-export input values as env vars, so APM runs
unauthenticated — hitting rate limits (60/hr) and failing on private
repo dependencies.

Fix: read the input with core.getInput, mask it with core.setSecret,
and set process.env.GITHUB_TOKEN before any APM subprocess calls.

Ref: microsoft/apm#356

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

2 participants