git-ecosystem / git-ecosystem/git-credential-manager
Azure Repos: Automatically fall back to OAuth tokens when PAT creation is blocked by org policy
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 9.3k
- Forks
- 2.9k
- Avg merge
- 7d 1h
- Merged PRs (30d)
- 14
Description
Problem:-
When an Azure DevOps organization has a policy that disables PAT creation (disablePatCreationPolicy), GCM fails with an error during
GeneratePersonalAccessTokenAsync() with no recovery path. The user must manually discover and set:
git config --global credential.azreposCredentialType oauth
This is a poor experience because:-
- The error message doesn't suggest the workaround
- The user has already successfully authenticated via AAD/Entra ID (the OAuth token was obtained), but the subsequent PAT creation step fails
- The fix is simple - use the OAuth token directly - but users don't know this
Current Behaviour:-
- GCM detects Azure DevOps host
- UsePersonalAccessTokens() returns true (default on non-DevBox platforms)
- GeneratePersonalAccessTokenAsync() successfully obtains an AAD access token
- CreatePersonalAccessTokenAsync() calls _apis/token/sessiontokens → fails due to org policy
- Trace2Exception propagates to the user — no fallback, no helpful guidance
Expected Behavior:-
When PAT creation fails due to an organization policy block, GCM should:
- Detect the specific policy-block failure (via HTTP status code and/or error message)
- Log a warning: "PAT creation blocked by organization policy, falling back to OAuth tokens"
- Fall back to returning the OAuth/AAD access token directly (same path as credential.azreposCredentialType=oauth)
Environment
- OS: macOS (but affects all non-DevBox platforms)
- GCM version: latest
- Azure DevOps org: Has disablePatCreationPolicy enabled
- Auth method: az login via Entra ID
Proposed Fix:-
In AzureReposHostProvider.cs → GetCredentialAsync(), wrap the GeneratePersonalAccessTokenAsync() call in a try/catch that detects the policy-block error and falls
back to GetAzureAccessTokenAsync().
_
I'm happy to submit a PR for this. Before I do, could you confirm:
_
- What HTTP status code / error message does _apis/token/sessiontokens return when blocked by org policy? (I can capture this with GCM_TRACE=1 if needed)
- Is this the right approach, or would you prefer a different fallback strategy?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in AzureReposHostProvider.cs and trace GetCredentialAsync() through GeneratePersonalAccessTokenAsync(), CreatePersonalAccessTokenAsync(), and GetAzureAccessTokenAsync(). Use GCM_TRACE=1 to identify the policy-block response from _apis/token/sessiontokens. Done means policy-block failures are recognized, a warning explains the fallback, and OAuth credentials are returned without affecting other PAT errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, csharp, git
- Domain
- api, authentication
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100