Skip to content

Commit 969e452

Browse files
author
Matthew John Cheetham
authored
Add no-op credential storage option (git-ecosystem#1740)
Add a null/no-op credential store option that, as the name suggests, does nothing. This can be useful if the user wants to use another credential helper, configured in-front of GCM via Git, to store credentials. Example config: ```ini [credential] credentialStore = none helper = /bin/my-awesome-helper helper = /usr/local/bin/git-credential-manager ``` In this example, the `my-awesome-helper` will be consulted first to retrieve existing credentials before GCM, and will be asked to store any credentials generated by GCM. Fixes git-ecosystem#1283
2 parents c853292 + a96afbb commit 969e452

6 files changed

+55
-0
lines changed

docs/configuration.md

+1
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ _(unset)_|Windows: `wincredman`, macOS: `keychain`, Linux: _(none)_|-
585585
`gpg`|Use GPG to store encrypted files that are compatible with the [pass][pass] (requires GPG and `pass` to initialize the store).|macOS, Linux
586586
`cache`|Git's built-in [credential cache][credential-cache].|macOS, Linux
587587
`plaintext`|Store credentials in plaintext files (**UNSECURE**). Customize the plaintext store location with [`credential.plaintextStorePath`][credential-plaintextstorepath].|Windows, macOS, Linux
588+
`none`|Do not store credentials via GCM.|Windows, macOS, Linux
588589

589590
#### Example
590591

docs/credstores.md

+26
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ There are several options for storing credentials that GCM supports:
99
- GPG/[`pass`][passwordstore] compatible files
1010
- Git's built-in [credential cache][credential-cache]
1111
- Plaintext files
12+
- Passthrough/no-op (no credential store)
1213

1314
The default credential stores on macOS and Windows are the macOS Keychain and
1415
the Windows Credential Manager, respectively.
@@ -251,6 +252,31 @@ permissions on this directory such that no other users or applications can
251252
access files within. If possible, use a path that exists on an external volume
252253
that you take with you and use full-disk encryption.
253254

255+
## Passthrough/no-op (no credential store)
256+
257+
**Available on:** _Windows, macOS, Linux_
258+
259+
**:warning: .**
260+
261+
```batch
262+
SET GCM_CREDENTIAL_STORE="none"
263+
```
264+
265+
or
266+
267+
```shell
268+
git config --global credential.credentialStore none
269+
```
270+
271+
This option disables the internal credential store. All operations to store or
272+
retrieve credentials will do nothing, and will return success. This is useful if
273+
you want to use a different credential store, chained in sequence via Git
274+
configuration, and don't want GCM to store credentials.
275+
276+
Note that you'll want to ensure that another credential helper is placed before
277+
GCM in the `credential.helper` Git configuration or else you will be prompted to
278+
enter your credentials every time you interact with a remote repository.
279+
254280
[access-windows-credential-manager]: https://support.microsoft.com/en-us/windows/accessing-credential-manager-1b5c916a-6a16-889f-8581-fc16e8165ac0
255281
[aws-cloudshell]: https://aws.amazon.com/cloudshell/
256282
[azure-cloudshell]: https://docs.microsoft.com/azure/cloud-shell/overview

docs/environment.md

+1
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,7 @@ _(unset)_|Windows: `wincredman`, macOS: `keychain`, Linux: _(none)_|-
716716
`gpg`|Use GPG to store encrypted files that are compatible with the [`pass` utility][passwordstore] (requires GPG and `pass` to initialize the store).|macOS, Linux
717717
`cache`|Git's built-in [credential cache][git-credential-cache].|Windows, macOS, Linux
718718
`plaintext`|Store credentials in plaintext files (**UNSECURE**). Customize the plaintext store location with [`GCM_PLAINTEXT_STORE_PATH`][gcm-plaintext-store-path].|Windows, macOS, Linux
719+
`none`|Do not store credentials via GCM.|Windows, macOS, Linux
719720

720721
#### Windows
721722

src/shared/Core/Constants.cs

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public static class CredentialStoreNames
3838
public const string SecretService = "secretservice";
3939
public const string Plaintext = "plaintext";
4040
public const string Cache = "cache";
41+
public const string None = "none";
4142
}
4243

4344
public static class RegexPatterns

src/shared/Core/CredentialStore.cs

+7
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ private void EnsureBackingStore()
100100
_backingStore = new PlaintextCredentialStore(_context.FileSystem, plainStoreRoot, ns);
101101
break;
102102

103+
case StoreNames.None:
104+
_backingStore = new NullCredentialStore();
105+
break;
106+
103107
default:
104108
var sb = new StringBuilder();
105109
sb.AppendLine(string.IsNullOrWhiteSpace(credStoreName)
@@ -168,6 +172,9 @@ private static void AppendAvailableStoreList(StringBuilder sb)
168172

169173
sb.AppendFormat(" {1,-13} : store credentials in plain-text files (UNSECURE){0}",
170174
Environment.NewLine, StoreNames.Plaintext);
175+
176+
sb.AppendFormat(" {1, -13} : disable internal credential storage{0}",
177+
Environment.NewLine, StoreNames.None);
171178
}
172179

173180
private void ValidateWindowsCredentialManager()
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace GitCredentialManager;
5+
6+
/// <summary>
7+
/// Credential store that does nothing. This is useful when you want to disable internal credential storage
8+
/// and only use another helper configured in Git to store credentials.
9+
/// </summary>
10+
public class NullCredentialStore : ICredentialStore
11+
{
12+
public IList<string> GetAccounts(string service) => Array.Empty<string>();
13+
14+
public ICredential Get(string service, string account) => null;
15+
16+
public void AddOrUpdate(string service, string account, string secret) { }
17+
18+
public bool Remove(string service, string account) => false;
19+
}

0 commit comments

Comments
 (0)