fix: credential fill returns garbage token in tokenless CI (gh-aw regression)#356
Merged
danielmeppiel merged 1 commit intomainfrom Mar 18, 2026
Merged
Conversation
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>
Contributor
There was a problem hiding this comment.
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_ASKPASSto an empty string forgit credential filland reject invalid “tokens” (prompt fragments/whitespace/overlong). - Add unit tests covering the new credential token validation and the
GIT_ASKPASSenv behavior. - Add GH-AW compatibility coverage in release-validation script and gate stable releases via a new
gh-aw-compatjob.
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
v0.8.1 introduced
resolve_credential_from_git()withGIT_ASKPASS=echo. In GitHub Actions (whereGITHUB_TOKENis not a default environment variable), this causesgit credential fillto 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 →echooutputs 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_is_valid_credential_token()rejects whitespace, prompt fragments, and >1024-char tokensFuture regression protection:
test-release-validation.sh: newtest_ghaw_compat()— tokenless isolated install + packbuild-release.yml: newgh-aw-compatjob usingmicrosoft/apm-action@v1— gates publish-pypi/homebrewNote
apm-actionhas a contributing issue: it declaresgithub-tokeninput but never passes it to APM subprocess asGITHUB_TOKEN. Separate PR needed there. This PR fixes APM to be resilient regardless.Test Results
test_token_manager.py