Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4fb0f1c
github: add support for OAuth with GHAE
mjcheetham May 12, 2021
c347cee
msauth: add WAM workaround for elevated procs
mjcheetham May 12, 2021
5dc3657
Merge pull request #343 from mjcheetham/ghae
mjcheetham May 13, 2021
b3cbf05
msauth: address some linting issues with braces
mjcheetham May 13, 2021
301f888
Merge pull request #344 from mjcheetham/wam-elevate
mjcheetham May 14, 2021
41feccd
introduce new windows-broker doc
vtbassmatt May 14, 2021
5d4393b
move wam.md contents into broker doc
vtbassmatt May 14, 2021
2900fb7
msauth: bump MSAL library versions
mjcheetham May 14, 2021
27846cf
shrink images
vtbassmatt May 14, 2021
f9fc319
link, spacing
vtbassmatt May 14, 2021
1d524bd
msauth: set MSAL embedded webview window title
mjcheetham May 14, 2021
16a20fd
Merge pull request #345 from microsoft/wam-docs
vtbassmatt May 14, 2021
df16ce4
docs: update configuration docs to fix links
mjcheetham May 14, 2021
22ad894
docs: update environment docs to fix links
mjcheetham May 14, 2021
caac019
Merge pull request #348 from microsoft/docs-fix
mjcheetham May 14, 2021
42eae07
docs: fix more broken links in environment.md
mjcheetham May 14, 2021
3ec3400
docs: fix more broken links in configuration.md
mjcheetham May 14, 2021
4fd5c90
Merge pull request #346 from mjcheetham/msal-vers
May 14, 2021
d9d62c7
Merge pull request #347 from mjcheetham/msal-title
May 14, 2021
82a67fb
main: rename master branch to main, and drop beta
mjcheetham May 17, 2021
e498936
Merge pull request #349 from mjcheetham/main-rename
mjcheetham May 17, 2021
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
2 changes: 1 addition & 1 deletion .azure-pipelines/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
trigger:
- master
- main

variables:
configuration: Release
Expand Down
2 changes: 1 addition & 1 deletion .azure-pipelines/pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pr:
- master
- main
- release

variables:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-installers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: Build-Installers
on:
workflow_dispatch:
push:
branches: [ master, release ]
branches: [ main, release ]
pull_request:
branches: [ master ]
branches: [ main ]

jobs:
linux:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: GCM-Core
on:
workflow_dispatch:
push:
branches: [ master, linux ]
branches: [ main, linux ]
pull_request:
branches: [ master, linux ]
branches: [ main, linux ]

jobs:
validate_gcm:
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Git Credential Manager Core

Branch|Status
-|-
master|[![Build Status](https://mseng.visualstudio.com/AzureDevOps/_apis/build/status/Teams/VCDesktop/Git-Credential-Manager-Core/GCM-CI?branchName=master)](https://mseng.visualstudio.com/AzureDevOps/_build/latest?definitionId=7861&branchName=master)
[![Build Status](https://github.com/microsoft/Git-Credential-Manager-Core/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/microsoft/Git-Credential-Manager-Core/actions/workflows/continuous-integration.yml)

---

Expand Down
4 changes: 2 additions & 2 deletions docs/azrepos-users-and-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ The Azure Repos host provider supports creating multiple types of credential:
- Microsoft identity OAuth tokens (experimental)

To select which type of credential the Azure Repos host provider will create
and use, you can set the [`credential.azreposCredentialType`](https://github.com/microsoft/Git-Credential-Manager-Core/blob/master/docs/configuration.md#credentialazreposcredentialtype-experimental)
configuration entry (or [`GCM_AZREPOS_CREDENTIALTYPE`](https://github.com/microsoft/Git-Credential-Manager-Core/blob/master/docs/environment.md#GCM_AZREPOS_CREDENTIALTYPE-experimental)
and use, you can set the [`credential.azreposCredentialType`](configuration.md#credentialazreposcredentialtype-experimental)
configuration entry (or [`GCM_AZREPOS_CREDENTIALTYPE`](environment.md#GCM_AZREPOS_CREDENTIALTYPE-experimental)
environment variable).

### Azure DevOps personal access tokens
Expand Down
8 changes: 5 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ Specify which authentication flow should be used when performing Microsoft authe

Defaults to `auto`.

**Note:** If [`credential.msauthUseBroker`](#credentialmsauthusebroker) is set
**Note:** If [`credential.msauthUseBroker`](#credentialmsauthusebroker-experimental) is set
to `true` and the operating system authentication broker is available, all flows
will be delegated to the broker. If both of those things are true, then the
value of `credential.msauthFlow` has no effect.
Expand All @@ -280,12 +280,14 @@ git config --global credential.msauthFlow devicecode

---

### credential.msauthUseBroker
### credential.msauthUseBroker _(experimental)_

Use the operating system account manager where available.

Defaults to `false`. This default is subject to change in the future.

_**Note:** before you enable this option on Windows, please [review the details](windows-broker.md) about what this means to your local Windows user account._

Value|Description
-|-
`true`|Use the operating system account manager as an authentication broker.
Expand All @@ -297,7 +299,7 @@ Value|Description
git config --global credential.msauthUseBroker true
```

**Also see: [GCM_MSAUTH_USEBROKER](environment.md#GCM_MSAUTH_USEBROKER)**
**Also see: [GCM_MSAUTH_USEBROKER](environment.md#GCM_MSAUTH_USEBROKER-experimental)**

---

Expand Down
8 changes: 5 additions & 3 deletions docs/environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ Specify which authentication flow should be used when performing Microsoft authe

Defaults to `auto`.

**Note:** If [`GCM_MSAUTH_USEBROKER`](#gcm_msauth_usebroker) is set to `true`
**Note:** If [`GCM_MSAUTH_USEBROKER`](#gcm_msauth_usebroker-experimental) is set to `true`
and the operating system authentication broker is available, all flows will be
delegated to the broker. If both of those things are true, then the value of
`GCM_MSAUTH_FLOW` has no effect.
Expand Down Expand Up @@ -432,12 +432,14 @@ export GCM_MSAUTH_FLOW="devicecode"

---

### GCM_MSAUTH_USEBROKER
### GCM_MSAUTH_USEBROKER _(experimental)_

Use the operating system account manager where available.

Defaults to `false`. This default is subject to change in the future.

_**Note:** before you enable this option on Windows, please [review the details](windows-broker.md) about what this means to your local Windows user account._

Value|Description
-|-
`true`|Use the operating system account manager as an authentication broker.
Expand All @@ -455,7 +457,7 @@ SET GCM_MSAUTH_USEBROKER="true"
export GCM_MSAUTH_USEBROKER="false"
```

**Also see: [credential.msauthUseBroker](configuration.md#credentialmsauthusebroker)**
**Also see: [credential.msauthUseBroker](configuration.md#credentialmsauthusebroker-experimental)**

---

Expand Down
Binary file added docs/img/aad-bitlocker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/aad-disconnect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/aad-questions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/aad-work-school.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/all-microsoft.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/apps-must-ask.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/get-signed-in.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 101 additions & 0 deletions docs/windows-broker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Web Account Manager integration

Git Credential Manager (GCM) Core knows how to integrate with the [Web Account Manager (WAM)](https://docs.microsoft.com/azure/active-directory/devices/concept-primary-refresh-token#key-terminology-and-components) feature of Windows to store credentials for Azure DevOps.
Authentication requests are said to be "brokered" to the operating system.
Currently, GCM will share authentication state with a few other Microsoft developer tools like Visual Studio and the Azure CLI, meaning fewer authentication prompts.
Integration with the WAM broker comes with several additional benefits, but it also has some potential drawbacks that you should be aware of before enabling it.

Note that this only affects [Azure DevOps](https://dev.azure.com).
It doesn't impact authentication with GitHub, Bitbucket, or any other Git host.

## Features

When you turn on WAM support, GCM Core can cooperate with Windows and with other WAM-enabled software on your machine.
This means a more seamless experience, fewer multi-factor authentication prompts, and the ability to use additional authentication technologies like smart cards and Windows Hello.
These convenience and security features make a good case for enabling WAM.

## Potential drawbacks

The WAM and Windows identity systems are complex, addressing a very broad range of customer use cases.
What works for a solo home user may not be adequate for a corporate-managed fleet of 100,000 devices and vice versa.
The GCM Core team isn't responsible for the user experience or choices made by WAM, but by integrating with WAM, we inherit some of those choices.
Therefore, we want you to be aware of some defaults and experiences if you choose to use WAM integration.

### For work or school accounts (Azure AD-backend identities)
When you sign into an Azure DevOps organization backed by Azure AD (often your company or school email), if your machine is already managed by Intune or enrolled in Azure AD matching that Azure DevOps organization, you'll get a seamless and easy-to-use experience.

If your machine isn't Intune/Azure AD-joined, or is Intune/Azure AD-joined to a different tenant, WAM will present you with the following dialog box:

![Consent dialog](img/aad-questions.png)

Depending on what you click, one of three things can happen:

- If you leave "allow my organization to manage my device" checked and click "OK", your computer will be registered with the Azure AD tenant backing the organization.
It may also be Intune-enrolled, meaning an administrator can deploy policies to your machine: requiring certain kinds of sign-in, turning on antivirus and firewall software, and enabling BitLocker.
Your identity will also be available to other apps on the computer for signing in, some of which may do so automatically.
![Example of policies pushed to an Intune-enrolled device](img/aad-bitlocker.png)
- If you uncheck "allow my organization to manage my device" and click "OK", your computer won't be registered with Azure AD or Intune-enrolled.
Your identity will be available to other apps on the computer for signing in.
Other apps may log you in automatically or prompt you again to allow your organization to manage your device.
- If you instead click "No, sign in to this app only", your machine will not be Intune-enrolled, so no policies can be enforced, and your identity won't be made available to other apps on the computer.

#### Removing device management
If you've allowed your computer to be managed and want to undo it, you can go into **Settings**, **Accounts**, **Access work or school**.
In the section where you see your email address and organization name, click **Disconnect**.

![Finding your work or school account](img/aad-work-school.png)

![Disconnecting from Azure AD](img/aad-disconnect.png)

### For Microsoft accounts
When you sign into an Azure DevOps organization backed by Microsoft account (MSA) identities (email addresses like `@outlook.com` or `@gmail.com` fall into this category), you may be prompted to select an existing "work or school account" or use a different one.

In order to sign in with an MSA you should continue and select "Use a different [work or school] account", but enter your MSA credentials when prompted.
This is due to a configuration outside of our control.
We expect this experience to improve over time and a "personal account" option to be presented in the future.

![Initial dialog to choose an existing or different account](img/get-signed-in.png)

If you've connected your MSA to Windows or signed-in to other Microsoft applications such as Office, then you may see this account listed in the authentication prompts when using GCM.
For any connected MSA, you can control whether or not the account is available to other Microsoft applications in **Settings**, **Accounts**, **Emails & accounts**:

![Allow all Microsoft apps to access your identity](img/all-microsoft.png)

![Microsoft apps must ask to access your identity](img/apps-must-ask.png)

Two very important things to note:
* If you haven't connected any Microsoft accounts to Windows before, the first account you connect will cause the local Windows user account to be converted to a connected account.
* In addition, you can't change the usage preference for the first Microsoft account connected to Windows: all Microsoft apps will be able to sign you in with that account.

As far as we can tell, there are no workarounds for either of these behaviors (other than to not use the WAM broker).

## Running as administrator

The Windows broker ("WAM") makes heavy use of [COM](https://docs.microsoft.com/en-us/windows/win32/com/the-component-object-model), a remote procedure call (RPC) technology built into Windows.
In order to integrate with WAM, Git Credential Manager and the underlying [Microsoft Authentication Library (MSAL)](https://aka.ms/msal-net) must use COM interfaces and RPCs.
When you run Git Credential Manager as an elevated process, some of the calls made between GCM and WAM may fail due to differing process security levels.
This can happen when you run `git` from an Administrator command-prompt or perform Git operations from Visual Studio running as Administrator.

If you've enabled using the broker, GCM will check whether it's running in an
elevated process.
If it is, GCM will automatically attempt to modify the COM security settings for the running process so that GCM and WAM can work together.
However, this automatic process security change is not guaranteed to succeed.
Various external factors like registry or system-wide COM settings may cause it to fail.
If GCM can't modify the process's COM security settings, GCM prints a warning message and won't be able to use the broker.

```text
warning: broker initialization failed
Failed to set COM process security to allow Windows broker from an elevated process (0x80010119).
See https://aka.ms/gcmcore-wamadmin for more information.
```

### Possible solutions

In order to fix the problem, there are a few options:

1. Run Git or Git Credential Manager from non-elevated processes.
2. Disable the broker by setting the
[`GCM_MSAUTH_USEBROKER`](environment.md#gcm_msauth_usebroker)
environment variable or the
[`credential.msauthUseBroker`](configuration.md#credentialmsauthusebroker)
Git configuration setting to `false`.
18 changes: 17 additions & 1 deletion src/shared/Git-Credential-Manager/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using Atlassian.Bitbucket;
using GitHub;
using Microsoft.AzureRepos;
using Microsoft.Git.CredentialManager.Authentication;

namespace Microsoft.Git.CredentialManager
{
Expand All @@ -18,6 +18,22 @@ public static void Main(string[] args)
using (var context = new CommandContext(appPath))
using (var app = new Application(context))
{
// Workaround for https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/2560
if (MicrosoftAuthentication.CanUseBroker(context))
{
try
{
MicrosoftAuthentication.InitializeBroker();
}
catch (Exception ex)
{
context.Streams.Error.WriteLine(
"warning: broker initialization failed{0}{1}",
Environment.NewLine, ex.Message
);
}
}

// Register all supported host providers at the normal priority.
// The generic provider should never win against a more specific one, so register it with low priority.
app.RegisterProvider(new AzureReposHostProvider(context), HostProviderPriority.Normal);
Expand Down
5 changes: 5 additions & 0 deletions src/shared/GitHub/GitHubConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public static class GitHubConstants
// TODO: update this with a real version number once the GCM OAuth application has been deployed to GHE
public static readonly Version MinimumEnterpriseOAuthVersion = new Version("99.99.99");

/// <summary>
/// The version string returned from the meta API endpoint for GitHub AE instances.
/// </summary>
public const string GitHubAeVersionString = "GitHub AE";

/// <summary>
/// Supported authentication modes for GitHub.com.
/// </summary>
Expand Down
9 changes: 8 additions & 1 deletion src/shared/GitHub/GitHubHostProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,15 @@ internal async Task<AuthenticationModes> GetSupportedAuthenticationModesAsync(Ur
{
modes |= AuthenticationModes.Basic;
}
if (Version.TryParse(metaInfo.InstalledVersion, out var version) && version >= GitHubConstants.MinimumEnterpriseOAuthVersion)

if (StringComparer.OrdinalIgnoreCase.Equals(metaInfo.InstalledVersion, GitHubConstants.GitHubAeVersionString))
{
// Assume all GHAE instances have the GCM OAuth application deployed
modes |= AuthenticationModes.OAuth;
}
else if (Version.TryParse(metaInfo.InstalledVersion, out var version) && version >= GitHubConstants.MinimumEnterpriseOAuthVersion)
{
// Only GHES versions beyond the minimum version have the GCM OAuth application deployed
modes |= AuthenticationModes.OAuth;
}

Expand Down
Loading