Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
99 changes: 99 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,95 @@ git config --global credential.azreposCredentialType oauth

---

### credential.azreposManagedIdentity

Use a [Managed Identity][managed-identity] to authenticate with Azure Repos.

The value `system` will tell GCM to use the system-assigned Managed Identity.

To specify a user-assigned Managed Identity, use the format `id://{clientId}`
where `{clientId}` is the client ID of the Managed Identity. Alternatively any
GUID-like value will also be interpreted as a user-assigned Managed Identity
client ID.

To specify a Managed Identity associated with an Azure resource, you can use the
format `resource://{resourceId}` where `{resourceId}` is the ID of the resource.

For more information about managed identities, see the Azure DevOps
[documentation][azrepos-sp-mid].

Value|Description
-|-
`system`|System-Assigned Managed Identity
`[guid]`|User-Assigned Managed Identity with the specified client ID
`id://[guid]`|User-Assigned Managed Identity with the specified client ID
`resource://[guid]`|User-Assigned Managed Identity for the associated resource

```shell
git config --global credential.azreposManagedIdentity "id://11111111-1111-1111-1111-111111111111"
```

**Also see: [GCM_AZREPOS_MANAGEDIDENTITY][gcm-azrepos-credentialmanagedidentity]**

---

### credential.azreposServicePrincipal

Specify the client and tenant IDs of a [service principal][service-principal]
to use when performing Microsoft authentication for Azure Repos.

The value of this setting should be in the format: `{tenantId}/{clientId}`.

You must also set at least one authentication mechanism if you set this value:

- [credential.azreposServicePrincipalSecret][credential-azrepos-sp-secret]
- [credential.azreposServicePrincipalCertificateThumbprint][credential-azrepos-sp-cert-thumbprint]

For more information about service principals, see the Azure DevOps
[documentation][azrepos-sp-mid].

#### Example

```shell
git config --global credential.azreposServicePrincipal "11111111-1111-1111-1111-111111111111/22222222-2222-2222-2222-222222222222"
```

**Also see: [GCM_AZREPOS_SERVICE_PRINCIPAL][gcm-azrepos-service-principal]**

---

### credential.azreposServicePrincipalSecret

Specifies the client secret for the [service principal][service-principal] when
performing Microsoft authentication for Azure Repos with
[credential.azreposServicePrincipalSecret][credential-azrepos-sp] set.

#### Example

```shell
git config --global credential.azreposServicePrincipalSecret "da39a3ee5e6b4b0d3255bfef95601890afd80709"
```

**Also see: [GCM_AZREPOS_SP_SECRET][gcm-azrepos-sp-secret]**

---

### credential.azreposServicePrincipalCertificateThumbprint

Specifies the thumbprint of a certificate to use when authenticating as a
[service principal][service-principal] for Azure Repos when
[GCM_AZREPOS_SERVICE_PRINCIPAL][credential-azrepos-sp] is set.

#### Example

```shell
git config --global credential.azreposServicePrincipalCertificateThumbprint "9b6555292e4ea21cbc2ebd23e66e2f91ebbe92dc"
```

**Also see: [GCM_AZREPOS_SP_CERT_THUMBPRINT][gcm-azrepos-sp-cert-thumbprint]**

---

### trace2.normalTarget

Turns on Trace2 Normal Format tracing - see [Git's Trace2 Normal Format
Expand Down Expand Up @@ -878,6 +967,7 @@ Defaults to disabled.
[gcm-authority]: environment.md#GCM_AUTHORITY-deprecated
[gcm-autodetect-timeout]: environment.md#GCM_AUTODETECT_TIMEOUT
[gcm-azrepos-credentialtype]: environment.md#GCM_AZREPOS_CREDENTIALTYPE
[gcm-azrepos-credentialmanagedidentity]: environment.md#GCM_AZREPOS_MANAGEDIDENTITY
[gcm-bitbucket-always-refresh-credentials]: environment.md#GCM_BITBUCKET_ALWAYS_REFRESH_CREDENTIALS
[gcm-bitbucket-authmodes]: environment.md#GCM_BITBUCKET_AUTHMODES
[gcm-credential-cache-options]: environment.md#GCM_CREDENTIAL_CACHE_OPTIONS
Expand Down Expand Up @@ -905,6 +995,7 @@ Defaults to disabled.
[http-proxy]: netconfig.md#http-proxy
[autodetect]: autodetect.md
[libsecret]: https://wiki.gnome.org/Projects/Libsecret
[managed-identity]: https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
[provider-migrate]: migration.md#gcm_authority
[cache-options]: https://git-scm.com/docs/git-credential-cache#_options
[pass]: https://www.passwordstore.org/
Expand All @@ -915,3 +1006,11 @@ Defaults to disabled.
[trace2-performance-docs]: https://git-scm.com/docs/api-trace2#_the_performance_format_target
[trace2-performance-env]: environment.md#GIT_TRACE2_PERF
[wam]: windows-broker.md
[service-principal]: https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals
[azrepos-sp-mid]: https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/service-principal-managed-identity
[credential-azrepos-sp]: #credentialazreposserviceprincipal
[credential-azrepos-sp-secret]: #credentialazreposserviceprincipalsecret
[credential-azrepos-sp-cert-thumbprint]: #credentialazreposserviceprincipalcertificatethumbprint
[gcm-azrepos-service-principal]: environment.md#GCM_AZREPOS_SERVICE_PRINCIPAL
[gcm-azrepos-sp-secret]: environment.md#GCM_AZREPOS_SP_SECRET
[gcm-azrepos-sp-cert-thumbprint]: environment.md#GCM_AZREPOS_SP_CERT_THUMBPRINT
127 changes: 126 additions & 1 deletion docs/environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,121 @@ export GCM_AZREPOS_CREDENTIALTYPE="oauth"

---

### GCM_AZREPOS_MANAGEDIDENTITY

Use a [Managed Identity][managed-identity] to authenticate with Azure Repos.

The value `system` will tell GCM to use the system-assigned Managed Identity.

To specify a user-assigned Managed Identity, use the format `id://{clientId}`
where `{clientId}` is the client ID of the Managed Identity. Alternatively any
GUID-like value will also be interpreted as a user-assigned Managed Identity
client ID.

To specify a Managed Identity associated with an Azure resource, you can use the
format `resource://{resourceId}` where `{resourceId}` is the ID of the resource.

For more information about managed identities, see the Azure DevOps
[documentation][azrepos-sp-mid].

Value|Description
-|-
`system`|System-Assigned Managed Identity
`[guid]`|User-Assigned Managed Identity with the specified client ID
`id://[guid]`|User-Assigned Managed Identity with the specified client ID
`resource://[guid]`|User-Assigned Managed Identity for the associated resource

#### Windows

```batch
SET GCM_AZREPOS_MANAGEDIDENTITY="id://11111111-1111-1111-1111-111111111111"
```

#### macOS/Linux

```bash
export GCM_AZREPOS_MANAGEDIDENTITY="id://11111111-1111-1111-1111-111111111111"
```

**Also see: [credential.azreposManagedIdentity][credential-azrepos-managedidentity]**

---

### GCM_AZREPOS_SERVICE_PRINCIPAL

Specify the client and tenant IDs of a [service principal][service-principal]
to use when performing Microsoft authentication for Azure Repos.

The value of this setting should be in the format: `{tenantId}/{clientId}`.

You must also set at least one authentication mechanism if you set this value:

- [GCM_AZREPOS_SP_SECRET][gcm-azrepos-sp-secret]
- [GCM_AZREPOS_SP_CERT_THUMBPRINT][gcm-azrepos-sp-cert-thumbprint]

For more information about service principals, see the Azure DevOps
[documentation][azrepos-sp-mid].

#### Windows

```batch
SET GCM_AZREPOS_SERVICE_PRINCIPAL="11111111-1111-1111-1111-111111111111/22222222-2222-2222-2222-222222222222"
```

#### macOS/Linux

```bash
export GCM_AZREPOS_SERVICE_PRINCIPAL="11111111-1111-1111-1111-111111111111/22222222-2222-2222-2222-222222222222"
```

**Also see: [credential.azreposServicePrincipal][credential-azrepos-sp]**

---

### GCM_AZREPOS_SP_SECRET

Specifies the client secret for the [service principal][service-principal] when
performing Microsoft authentication for Azure Repos with
[GCM_AZREPOS_SERVICE_PRINCIPAL][gcm-azrepos-sp] set.

#### Windows

```batch
SET GCM_AZREPOS_SP_SECRET="da39a3ee5e6b4b0d3255bfef95601890afd80709"
```

#### macOS/Linux

```bash
export GCM_AZREPOS_SP_SECRET="da39a3ee5e6b4b0d3255bfef95601890afd80709"
```

**Also see: [credential.azreposServicePrincipalSecret][credential-azrepos-sp-secret]**

---

### GCM_AZREPOS_SP_CERT_THUMBPRINT

Specifies the thumbprint of a certificate to use when authenticating as a
[service principal][service-principal] for Azure Repos when
[GCM_AZREPOS_SERVICE_PRINCIPAL][gcm-azrepos-sp] is set.

#### Windows

```batch
SET GCM_AZREPOS_SP_CERT_THUMBPRINT="9b6555292e4ea21cbc2ebd23e66e2f91ebbe92dc"
```

#### macOS/Linux

```bash
export GCM_AZREPOS_SP_CERT_THUMBPRINT="9b6555292e4ea21cbc2ebd23e66e2f91ebbe92dc"
```

**Also see: [credential.azreposServicePrincipalCertificateThumbprint][credential-azrepos-sp-cert-thumbprint]**

---

### GIT_TRACE2

Turns on Trace2 Normal Format tracing - see [Git's Trace2 Normal Format
Expand Down Expand Up @@ -985,7 +1100,8 @@ Defaults to disabled.
[credential-allowwindowsauth]: environment.md#credentialallowWindowsAuth
[credential-authority]: configuration.md#credentialauthority-deprecated
[credential-autodetecttimeout]: configuration.md#credentialautodetecttimeout
[credential-azrepos-credential-type]: configuration.md#azreposcredentialtype
[credential-azrepos-credential-type]: configuration.md#credentialazreposcredentialtype
[credential-azrepos-managedidentity]: configuration.md#credentialazreposmanagedidentity
[credential-bitbucketauthmodes]: configuration.md#credentialbitbucketAuthModes
[credential-cacheoptions]: configuration.md#credentialcacheoptions
[credential-credentialstore]: configuration.md#credentialcredentialstore
Expand Down Expand Up @@ -1022,6 +1138,7 @@ Defaults to disabled.
[github-emu]: https://docs.github.com/en/enterprise-cloud@latest/admin/identity-and-access-management/using-enterprise-managed-users-for-iam/about-enterprise-managed-users
[network-http-proxy]: netconfig.md#http-proxy
[libsecret]: https://wiki.gnome.org/Projects/Libsecret
[managed-identity]: https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
[migration-guide]: migration.md#gcm_authority
[passwordstore]: https://www.passwordstore.org/
[trace2-normal-docs]: https://git-scm.com/docs/api-trace2#_the_normal_format_target
Expand All @@ -1031,3 +1148,11 @@ Defaults to disabled.
[trace2-performance-docs]: https://git-scm.com/docs/api-trace2#_the_performance_format_target
[trace2-performance-config]: configuration.md#trace2perfTarget
[windows-broker]: windows-broker.md
[service-principal]: https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals
[azrepos-sp-mid]: https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/service-principal-managed-identity
[gcm-azrepos-sp]: #gcm_azrepos_service_principal
[gcm-azrepos-sp-secret]: #gcm_azrepos_sp_secret
[gcm-azrepos-sp-cert-thumbprint]: #gcm_azrepos_sp_cert_thumbprint
[credential-azrepos-sp]: configuration.md#credentialazreposserviceprincipal
[credential-azrepos-sp-secret]: configuration.md#credentialazreposserviceprincipalsecret
[credential-azrepos-sp-cert-thumbprint]: configuration.md#credentialazreposserviceprincipalcertificatethumbprint
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
using System;
using System.Threading.Tasks;
using GitCredentialManager.Authentication;
using GitCredentialManager.Tests.Objects;
using Microsoft.Identity.Client.AppConfig;
using Xunit;

namespace GitCredentialManager.Tests.Authentication
{
public class MicrosoftAuthenticationTests
{
[Fact]
public async System.Threading.Tasks.Task MicrosoftAuthentication_GetAccessTokenAsync_NoInteraction_ThrowsException()
public async Task MicrosoftAuthentication_GetTokenForUserAsync_NoInteraction_ThrowsException()
{
const string authority = "https://login.microsoftonline.com/common";
const string clientId = "C9E8FDA6-1D46-484C-917C-3DBD518F27C3";
Expand All @@ -24,7 +26,48 @@ public async System.Threading.Tasks.Task MicrosoftAuthentication_GetAccessTokenA
var msAuth = new MicrosoftAuthentication(context);

await Assert.ThrowsAsync<Trace2InvalidOperationException>(
() => msAuth.GetTokenAsync(authority, clientId, redirectUri, scopes, userName, false));
() => msAuth.GetTokenForUserAsync(authority, clientId, redirectUri, scopes, userName, false));
}

[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
[InlineData("system")]
[InlineData("SYSTEM")]
[InlineData("sYsTeM")]
[InlineData("00000000-0000-0000-0000-000000000000")]
[InlineData("id://00000000-0000-0000-0000-000000000000")]
[InlineData("ID://00000000-0000-0000-0000-000000000000")]
[InlineData("Id://00000000-0000-0000-0000-000000000000")]
public void MicrosoftAuthentication_GetManagedIdentity_ValidSystemId_ReturnsSystemId(string str)
{
ManagedIdentityId actual = MicrosoftAuthentication.GetManagedIdentity(str);
Assert.Equal(ManagedIdentityId.SystemAssigned, actual);
}

[Theory]
[InlineData("8B49DCA0-1298-4A0D-AD6D-934E40230839")]
[InlineData("id://8B49DCA0-1298-4A0D-AD6D-934E40230839")]
[InlineData("ID://8B49DCA0-1298-4A0D-AD6D-934E40230839")]
[InlineData("Id://8B49DCA0-1298-4A0D-AD6D-934E40230839")]
[InlineData("resource://8B49DCA0-1298-4A0D-AD6D-934E40230839")]
[InlineData("RESOURCE://8B49DCA0-1298-4A0D-AD6D-934E40230839")]
[InlineData("rEsOuRcE://8B49DCA0-1298-4A0D-AD6D-934E40230839")]
[InlineData("resource://00000000-0000-0000-0000-000000000000")]
public void MicrosoftAuthentication_GetManagedIdentity_ValidUserIdByClientId_ReturnsUserId(string str)
{
ManagedIdentityId actual = MicrosoftAuthentication.GetManagedIdentity(str);
Assert.NotNull(actual);
Assert.NotEqual(ManagedIdentityId.SystemAssigned, actual);
}

[Theory]
[InlineData("unknown://8B49DCA0-1298-4A0D-AD6D-934E40230839")]
[InlineData("this is a string")]
public void MicrosoftAuthentication_GetManagedIdentity_Invalid_ThrowsArgumentException(string str)
{
Assert.Throws<ArgumentException>(() => MicrosoftAuthentication.GetManagedIdentity(str));
}
}
}
Loading