Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
88cc045
build(deps): bump actions/setup-dotnet from 5.2.0 to 5.3.0
dependabot[bot] May 28, 2026
5e80db1
globals.json: specify the SDK version precisely
dscho Jun 4, 2026
3a559b8
VERSION: bump to 2.9.0
mjcheetham Jun 18, 2026
ea84a25
oauth: support non-query response modes
mjcheetham Jun 17, 2026
6cefbd9
generic-oauth: add response mode setting
mjcheetham Jun 18, 2026
16e9c7f
msal: update to latest MSAL 4.82.2
mjcheetham Jun 18, 2026
29e2f82
msauth: resolve auth flow before selecting redirect URI
mjcheetham Jun 18, 2026
913b89a
build(deps): bump actions/setup-dotnet from 5.2.0 to 5.3.0 (#2352)
dscho Jun 19, 2026
825f14f
build(deps): bump actions/checkout from 6 to 7
dependabot[bot] Jun 19, 2026
78f669f
build(deps): bump actions/checkout from 6 to 7 (#2358)
dscho Jun 19, 2026
a4743f9
Merge pull request #15 from git-ecosystem/msal-update
mjcheetham Jun 19, 2026
2774321
Merge pull request #17 from git-ecosystem/msal-redirecturi
mjcheetham Jun 19, 2026
194ba29
Merge pull request #16 from git-ecosystem/oauth-form-post
mjcheetham Jun 19, 2026
7bb63e8
build(deps): bump actions/setup-dotnet from 5.3.0 to 5.4.0
dependabot[bot] Jun 26, 2026
16a5741
build(deps): bump actions/setup-dotnet from 5.3.0 to 5.4.0 (#2361)
dscho Jun 28, 2026
69fc517
docs: fix broken links identified by linting
mjcheetham Jun 29, 2026
2377102
docs: fix broken links identified by linting (#2364)
mjcheetham Jun 30, 2026
dcb5fd1
linux: use the appropriate PGP key to sign the Debian packages
dscho Jul 7, 2026
73696fa
browser: open AbsoluteUri to avoid double-escaping
mjcheetham Jul 6, 2026
ac43912
linux: adjust the instructions how to verify the signatures
dscho Jul 7, 2026
cd57ef8
linux: fix instructions where to download the latest archive
dscho Jul 7, 2026
e3e079e
esrp: use new Linux signing key (#2373)
mjcheetham Jul 7, 2026
90884de
Merge pull request #21 from git-ecosystem/url-escape-fix
mjcheetham Jul 7, 2026
4f4d572
VERSION: bump to 2.9.1
mjcheetham Jul 7, 2026
6760f0e
release: manually force CFS on release builds
mjcheetham Jul 7, 2026
2fe99b8
Merge branch 'sec-release_2.9.0'
mjcheetham Jul 14, 2026
2a2231c
build(deps): bump actions/setup-dotnet from 5.4.0 to 6.0.0
dependabot[bot] Jul 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .azure-pipelines/nuget.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This Nuget config file is only used in release builds to redirect all
NuGet package sources to the Central Feed Services (CFS) feed.
-->
<configuration>
<packageSources>
<clear />
<add key="CFS" value="https://pkgs.dev.azure.com/mseng/1ES/_packaging/1ES_PublicPackages/nuget/v3/index.json" />
</packageSources>
</configuration>
38 changes: 37 additions & 1 deletion .azure-pipelines/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,15 @@ extends:
artifactName: '${{ dim.runtime }}'
steps:
- checkout: self
- task: CopyFiles@2
displayName: 'Use Central Feed Services (CFS)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)\.azure-pipelines'
Contents: 'nuget.config'
TargetFolder: '$(Build.SourcesDirectory)'
Overwrite: true
- task: NuGetAuthenticate@1
displayName: 'Authenticate to NuGet feeds'
- task: PowerShell@2
displayName: 'Read version file'
inputs:
Expand Down Expand Up @@ -295,6 +304,15 @@ extends:
artifactName: '${{ dim.runtime }}'
steps:
- checkout: self
- task: CopyFiles@2
displayName: 'Use Central Feed Services (CFS)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)/.azure-pipelines'
Contents: 'nuget.config'
TargetFolder: '$(Build.SourcesDirectory)'
Overwrite: true
- task: NuGetAuthenticate@1
displayName: 'Authenticate to NuGet feeds'
- task: Bash@3
displayName: 'Read version file'
inputs:
Expand Down Expand Up @@ -570,6 +588,15 @@ extends:
artifactName: '${{ dim.runtime }}'
steps:
- checkout: self
- task: CopyFiles@2
displayName: 'Use Central Feed Services (CFS)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)/.azure-pipelines'
Contents: 'nuget.config'
TargetFolder: '$(Build.SourcesDirectory)'
Overwrite: true
- task: NuGetAuthenticate@1
displayName: 'Authenticate to NuGet feeds'
- task: Bash@3
displayName: 'Read version file'
inputs:
Expand Down Expand Up @@ -639,7 +666,7 @@ extends:
inlineOperation: |
[
{
"KeyCode": "CP-453387-Pgp",
"KeyCode": "CP-500207-Pgp",
"OperationCode": "LinuxSign",
"ToolName": "sign",
"ToolVersion": "1.0",
Expand Down Expand Up @@ -673,6 +700,15 @@ extends:
artifactName: 'dotnet-tool'
steps:
- checkout: self
- task: CopyFiles@2
displayName: 'Use Central Feed Services (CFS)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)\.azure-pipelines'
Contents: 'nuget.config'
TargetFolder: '$(Build.SourcesDirectory)'
Overwrite: true
- task: NuGetAuthenticate@1
displayName: 'Authenticate to NuGet feeds'
- task: PowerShell@2
displayName: 'Read version file'
inputs:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
language: [ 'csharp' ]

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v5.2.0
uses: actions/setup-dotnet@v6.0.0
with:
dotnet-version: 10.0.x

Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ jobs:
os: windows-11-arm

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v5.2.0
uses: actions/setup-dotnet@v6.0.0
with:
dotnet-version: 10.0.x

Expand Down Expand Up @@ -82,10 +82,10 @@ jobs:
runtime: [ linux-x64, linux-arm64, linux-arm ]

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v5.2.0
uses: actions/setup-dotnet@v6.0.0
with:
dotnet-version: 10.0.x

Expand Down Expand Up @@ -126,10 +126,10 @@ jobs:
runtime: [ osx-x64, osx-arm64 ]

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v5.2.0
uses: actions/setup-dotnet@v6.0.0
with:
dotnet-version: 10.0.x

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
name: Lint markdown files
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- uses: DavidAnson/markdownlint-cli2-action@ce4853d43830c74c1753b39f3cf40f71c2031eb9
with:
Expand All @@ -30,7 +30,7 @@ jobs:
name: Check for broken links
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- name: Run link checker
# For any troubleshooting, see:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/validate-install-from-source.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
GNUPGHOME=/root/.gnupg tdnf install tar -y # needed for `actions/checkout`
fi

- uses: actions/checkout@v6
- uses: actions/checkout@v7

- run: |
sh "${GITHUB_WORKSPACE}/src/linux/Packaging.Linux/install-from-source.sh" -y
Expand Down
6 changes: 3 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
<PackageVersion Include="Avalonia.Win32" Version="11.1.3" />

<!-- Microsoft Identity -->
<PackageVersion Include="Microsoft.Identity.Client" Version="4.65.0" />
<PackageVersion Include="Microsoft.Identity.Client.Broker" Version="4.65.0" />
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.65.0" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.84.2" />
<PackageVersion Include="Microsoft.Identity.Client.Broker" Version="4.84.2" />
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.84.2" />

<!-- MSBuild -->
<PackageVersion Include="Microsoft.Build.Framework" Version="16.0.461" />
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.8.0.0
2.9.1.0
2 changes: 1 addition & 1 deletion docs/credstores.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ Note that you'll want to ensure that another credential helper is placed before
GCM in the `credential.helper` Git configuration or else you will be prompted to
enter your credentials every time you interact with a remote repository.

[access-windows-credential-manager]: https://support.microsoft.com/en-us/windows/accessing-credential-manager-1b5c916a-6a16-889f-8581-fc16e8165ac0
[access-windows-credential-manager]: https://support.microsoft.com/en-US/Windows/Security/credential-manager-in-windows
[aws-cloudshell]: https://aws.amazon.com/cloudshell/
[azure-cloudshell]: https://docs.microsoft.com/azure/cloud-shell/overview
[cmdkey]: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/cmdkey
Expand Down
24 changes: 24 additions & 0 deletions docs/generic-oauth.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ following values in your Git configuration:
- Client Secret (optional)
- Redirect URL (optional, defaults to `http://127.0.0.1`)
- Scopes (optional)
- Response Mode (optional, defaults to `query`)
- OAuth Endpoints
- Authorization Endpoint
- Token Endpoint
Expand All @@ -62,6 +63,7 @@ git config --global credential.<HOST>.oauthAuthorizeEndpoint <AuthEndpoint>
git config --global credential.<HOST>.oauthTokenEndpoint <TokenEndpoint>
git config --global credential.<HOST>.oauthScopes <Scopes>
git config --global credential.<HOST>.oauthDeviceEndpoint <DeviceEndpoint>
git config --global credential.<HOST>.oauthResponseMode <ResponseMode>
```

**Example commands:**
Expand All @@ -83,13 +85,35 @@ git config --global credential.<HOST>.oauthDeviceEndpoint <DeviceEndpoint>
oauthScopes = "code:write profile:read"
oauthDefaultUserName = "OAUTH"
oauthUseClientAuthHeader = false
oauthResponseMode = "query"
```

### Additional configuration

Depending on the specific implementation of OAuth with your Git host you may
also need to specify additional behavior.

#### Response mode

The response mode controls how the authorization server returns the response to
the loopback redirect URI once the user has authenticated. GCM supports the
following values:

- `query` (default) - parameters are returned in the redirect URI query string.
- `fragment` - parameters are returned in the redirect URI fragment.
- `form_post` - parameters are returned as an auto-submitting HTML form that is
POSTed to the redirect URI, as described by the
[OAuth 2.0 Form Post Response Mode][form-post-spec] specification.

Most hosts use the default `query` mode. Only set this if your host requires a
specific response mode:

```shell
git config --global credential.<HOST>.oauthResponseMode <query|fragment|form_post>
```

[form-post-spec]: https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html

#### Token user name

If your Git host requires that you specify a username to use with OAuth tokens
Expand Down
2 changes: 1 addition & 1 deletion docs/github-apideprecation.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,6 @@ the new token-based authentication requirements **DO NOT** apply to GHES:
[windows-cli-save-pat-image]: img/windows-cli-save-pat.png
[vs-2019]: https://docs.microsoft.com/en-us/visualstudio/install/update-visual-studio?view=vs-2019
[vs-2017]: https://docs.microsoft.com/en-us/visualstudio/install/update-visual-studio?view=vs-2017
[windows-credential-manager]: https://support.microsoft.com/en-us/windows/accessing-credential-manager-1b5c916a-6a16-889f-8581-fc16e8165ac0
[windows-credential-manager]: https://support.microsoft.com/en-US/Windows/Security/credential-manager-in-windows
[windows-gui-add-pat-image]: img/windows-gui-add-pat.png
[windows-gui-credentials-image]: img/windows-gui-credentials.png
42 changes: 17 additions & 25 deletions docs/linux-validate-gpg.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,42 @@ the latest Debian package and/or tarball signature.
apt-get install -y curl debsig-verify

# Download public key signature file
curl -s https://api.github.com/repos/git-ecosystem/git-credential-manager/releases/latest \
| grep -E 'browser_download_url.*gcm-public.asc' \
| cut -d : -f 2,3 \
| tr -d \" \
| xargs -I 'url' curl -L -o gcm-public.asc 'url'
curl -Os https://packages.microsoft.com/keys/microsoft-2025.asc

# De-armor public key signature file
gpg --output gcm-public.gpg --dearmor gcm-public.asc
gpg --output microsoft-2025.gpg --dearmor microsoft-2025.asc

# Note that the fingerprint of this key is "3C853823978B07FA", which you can
# Note that the fingerprint of this key is "EE4D7792F748182B", which you can
# determine by running:
gpg --show-keys gcm-public.asc | head -n 2 | tail -n 1 | tail -c 17
gpg --show-keys microsoft-2025.asc | head -n 2 | tail -n 1 | tail -c 17

# Copy de-armored public key to debsig keyring folder
mkdir /usr/share/debsig/keyrings/3C853823978B07FA
mv gcm-public.gpg /usr/share/debsig/keyrings/3C853823978B07FA/
mkdir /usr/share/debsig/keyrings/EE4D7792F748182B
mv microsoft-2025.gpg /usr/share/debsig/keyrings/EE4D7792F748182B/

# Create an appropriate policy file
mkdir /etc/debsig/policies/3C853823978B07FA
cat > /etc/debsig/policies/3C853823978B07FA/generic.pol << EOL
mkdir /etc/debsig/policies/EE4D7792F748182B
cat > /etc/debsig/policies/EE4D7792F748182B/generic.pol << EOL
<?xml version="1.0"?>
<!DOCTYPE Policy SYSTEM "https://www.debian.org/debsig/1.0/policy.dtd">
<Policy xmlns="https://www.debian.org/debsig/1.0/">

<Origin Name="Git Credential Manager" id="3C853823978B07FA" Description="Git Credential Manager public key"/>
<Origin Name="Git Credential Manager" id="EE4D7792F748182B" Description="Git Credential Manager public key"/>

<Selection>
<Required Type="origin" File="gcm-public.gpg" id="3C853823978B07FA"/>
<Required Type="origin" File="microsoft-2025.gpg" id="EE4D7792F748182B"/>
</Selection>

<Verification MinOptional="0">
<Required Type="origin" File="gcm-public.gpg" id="3C853823978B07FA"/>
<Required Type="origin" File="microsoft-2025.gpg" id="EE4D7792F748182B"/>
</Verification>

</Policy>
EOL

# Download Debian package
# Download Debian package (substitute `x64` with `arm64` on ARM machines)
curl -s https://api.github.com/repos/git-ecosystem/git-credential-manager/releases/latest \
| grep "browser_download_url.*deb" \
| grep "browser_download_url.*-x64-.*deb" \
| cut -d : -f 2,3 \
| tr -d \" \
| xargs -I 'url' curl -L -o gcm.deb 'url'
Expand All @@ -61,24 +57,20 @@ debsig-verify gcm.deb
## Tarball
```shell
# Download the public key signature file
curl -s https://api.github.com/repos/git-ecosystem/git-credential-manager/releases/latest \
| grep -E 'browser_download_url.*gcm-public.asc' \
| cut -d : -f 2,3 \
| tr -d \" \
| xargs -I 'url' curl -L -o gcm-public.asc 'url'
curl -Os https://packages.microsoft.com/keys/microsoft-2025.asc

# Import the public key
gpg --import gcm-public.asc
gpg --import microsoft-2025.asc

# Download the tarball and its signature file
curl -s https://api.github.com/repos/ldennington/git-credential-manager/releases/latest \
curl -s https://api.github.com/repos/git-ecosystem/git-credential-manager/releases/latest \
| grep -E 'browser_download_url.*gcm-linux.*[0-9].[0-9].[0-9].tar.gz' \
| cut -d : -f 2,3 \
| tr -d \" \
| xargs -I 'url' curl -LO 'url'

# Trust the public key
echo -e "5\ny\n" | gpg --command-fd 0 --expert --edit-key 3C853823978B07FA trust
echo -e "5\ny\n" | gpg --command-fd 0 --expert --edit-key EE4D7792F748182B trust

# Verify the signature
gpg --verify gcm-linux_amd64*.tar.gz.asc gcm-linux*.tar.gz
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"sdk": {
"rollForward": "latestMajor",
"version": "8.0"
"version": "8.0.100"
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public async Task BitbucketOAuth2Client_GetAuthorizationCodeAsync_ReturnsCode()

Bitbucket.Cloud.BitbucketOAuth2Client client = GetBitbucketOAuth2Client();

MockGetAuthenticationCodeAsync(finalCallbackUri, null, client.Scopes);
MockGetAuthenticationResponseAsync(finalCallbackUri, null, client.Scopes);

MockCodeGenerator();

Expand All @@ -56,7 +56,7 @@ public async Task BitbucketOAuth2Client_GetAuthorizationCodeAsync_RespectsClient

Bitbucket.Cloud.BitbucketOAuth2Client client = GetBitbucketOAuth2Client();

MockGetAuthenticationCodeAsync(finalCallbackUri, clientId, client.Scopes);
MockGetAuthenticationResponseAsync(finalCallbackUri, clientId, client.Scopes);

MockCodeGenerator();

Expand Down Expand Up @@ -115,7 +115,7 @@ private void MockCodeGenerator()
codeGenerator.Setup(c => c.CreatePkceCodeChallenge(OAuth2PkceChallengeMethod.Sha256, pkceCodeVerifier)).Returns(pkceCodeChallenge);
}

private void MockGetAuthenticationCodeAsync(Uri finalCallbackUri, string overrideClientId, IEnumerable<string> scopes)
private void MockGetAuthenticationResponseAsync(Uri finalCallbackUri, string overrideClientId, IEnumerable<string> scopes)
{
var authorizationUri = new UriBuilder(CloudConstants.OAuth2AuthorizationEndpoint)
{
Expand All @@ -128,7 +128,8 @@ private void MockGetAuthenticationCodeAsync(Uri finalCallbackUri, string overrid
+ "&scope=" + WebUtility.UrlEncode(string.Join(" ", scopes)).ToLower()
}.Uri;

browser.Setup(b => b.GetAuthenticationCodeAsync(authorizationUri, rootCallbackUri, ct)).Returns(Task.FromResult(finalCallbackUri));
browser.Setup(b => b.GetAuthenticationResponseAsync(authorizationUri, rootCallbackUri, OAuth2ResponseMode.Default, ct))
.Returns(Task.FromResult(finalCallbackUri.GetQueryParameters()));
}

private Uri MockFinalCallbackUri()
Expand Down
Loading
Loading