Skip to content

Commit 446b697

Browse files
authored
document security best practices for managing credentials. (#3240)
1 parent 1343b10 commit 446b697

File tree

4 files changed

+68
-21
lines changed

4 files changed

+68
-21
lines changed

docs/concepts/Security-Best-Practices.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ For more information about Dependabot alerts & security updates, [see the follow
119119

120120
When using multiple public & private NuGet source feeds, a package can be downloaded from any of the feeds. To ensure your build is predictable and secure from known attacks such as [Dependency Confusion](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610), knowing what specific feed(s) your packages are coming from is a best practice. You can use a single feed or private feed with upstreaming capabilities for protection.
121121

122-
For more information to secure your package feeds, see [3 Ways to Mitigate Risk When Using Private Package Feeds](https://azure.microsoft.com/resources/3-ways-to-mitigate-risk-using-private-package-feeds/).
122+
For more information to secure your package feeds, see [3 Ways to Mitigate Risk When Using Private Package Feeds](https://azure.microsoft.com/resources/3-ways-to-mitigate-risk-using-private-package-feeds/en-us/).
123+
124+
When using a private feed, refer to the [security best practices for managing credentials](../consume-packages/consuming-packages-authenticated-feeds.md#security-best-practices-for-managing-credentials).
123125

124126
### Client trust policies
125127

docs/consume-packages/consuming-packages-authenticated-feeds.md

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,50 @@ For HTTP feeds, NuGet will make an unauthenticated request, and if the server re
1616
1. [Credentials in *nuget.config* files](#credentials-in-nugetconfig-files).
1717
1. [Use a NuGet credential provider, if your package source provides one](#credential-providers).
1818

19-
> [!NOTE]
20-
> We recommend using a credential provider when possible.
21-
> Using a credential provider avoids secrets in the *nuget.config* file, reducing risk of accidentally leaking secrets via source control.
22-
> Additionally, it typically reduces the number of places you need to update when a credential expires or changes.
23-
> If the credential provider supports single sign-on, it may reduce the number of times you need to login, or the number of places that credentials need to be saved.
24-
2519
The credentials you need to use are determined by the package source.
2620
Therefore, unless you're using a credential provider, you should check with your package source for what credentials to use.
2721
It is very common for package sources to forbid you from using your password (that you log into the website with) with NuGet.
2822
Typically you need to create a Personal Access Token to use as NuGet's password, but you should check the documentation for the NuGet server you're using.
2923
Some package sources, such as Azure DevOps and GitHub, have scoped access tokens, so you may need to ensure that any tokens you create include the required scope.
3024

25+
## Security best practices for managing credentials
26+
27+
Although NuGet searches for credentials in the order mentioned above, we recommend the following sequence for securely managing credentials when authenticating with private feeds:
28+
29+
1. **Credential Provider**: It is highly recommended to use a credential provider whenever possible.
30+
This approach avoids storing secrets in plain text and minimizes the risk of accidentally exposing secrets through source control.
31+
Moreover, it generally reduces the number of places you need to update when a credential expires or changes.
32+
If the credential provider supports single sign-on, it may decrease the frequency of logins or the number of places where credentials need to be saved.
33+
Refer to the [credential providers](#credential-providers) section for more information.
34+
35+
1. **Encrypted Credentials in nuget.config**: If a credential provider is not available, you should consider using encrypted credentials.
36+
This approach provides an extra layer of security by storing the credentials in an encrypted format.
37+
For more information, refer to the section on [credentials in *nuget.config* files](#credentials-in-nugetconfig-files).
38+
39+
> [!NOTE]
40+
> Be aware that encrypted passwords are only supported on Windows.
41+
> Moreover, they can only be decrypted on the same machine and by the same user who originally encrypted them.
42+
43+
1. **Using Environment Variable Macros in nuget.config**: If using encrypted credentials is not possible, consider storing the credentials in the *nuget.config* file with environment variable macros.
44+
This approach allows you to reference environment variables that contain the actual credentials.
45+
It enhances transparency and helps end users understand how their credentials are configured.
46+
For more information, refer to the section on [credentials in *nuget.config* files](#credentials-in-nugetconfig-files).
47+
48+
1. **Using Environment Variables Directly**: As a fallback option, you can store the credentials directly in environment variables.
49+
However, be aware that this approach may offer less visibility and control compared to using environment variable macros in the *nuget.config* file.
50+
For more information, refer to the section on [credentials in environment variables](#credentials-in-environment-variables).
51+
52+
1. **Clear Text Credentials in NuGet.Config**: It is highly recommended to use one of the previously mentioned options.
53+
If these options are not feasible, you can store the credentials in the *nuget.config* file.
54+
However, this option should only be used in environments where no other secure option is available.
55+
For more information, refer to the section on [credentials in *nuget.config* files](#credentials-in-nugetconfig-files).
56+
57+
> [!WARNING]
58+
> Storing credentials in clear text in the *nuget.config* file, especially when saving the file in source control, is risky as it increases the chances of accidental credential leaks.
59+
> If you must store credentials in the *nuget.config* file, consider using one of the more secure options mentioned above.
60+
61+
By adhering to these best practices, you can securely authenticate private feeds while minimizing the risk of sensitive information exposure.
62+
3163
## Credentials in environment variables
3264

3365
NuGet will search for an environment variable named `NuGetPackageSourceCredentials_{name}`, where `{name}` is the value of `key="name"` in your *nuget.config* file's package source.
@@ -68,7 +100,7 @@ For more information about valid authentication types, see [the docs on package
68100
See [the *nuget.config* file reference doc section on package source credentials](../reference/nuget-config-file.md#packagesourcecredentials) for more information, including syntax.
69101
However, it's easier to use [`dotnet nuget update source`](/dotnet/core/tools/dotnet-nuget-update-source) on the command line to set the credentials.
70102

71-
> ![Warning]
103+
> [!WARNING]
72104
> Take care when setting credentials in *nuget.config* files, especially when saving the credential as plain text.
73105
> If the credential is written to a *nuget.config* file that is in source control, there is an increased risk of accidentally leaking the secret.
74106
>

docs/reference/cli-reference/cli-ref-sources.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ where `<operation>` is one of *List, Add, Remove, Enable, Disable,* or *Update*,
5353

5454
Specifies the password for authenticating with the source.
5555

56+
> [!NOTE]
57+
> Be aware that encrypted passwords are only supported on Windows.
58+
> Moreover, they can only be decrypted on the same machine and by the same user who originally encrypted them.
59+
5660
- **`-src|-Source`**
5761

5862
Path to the package(s) source.
@@ -61,6 +65,10 @@ where `<operation>` is one of *List, Add, Remove, Enable, Disable,* or *Update*,
6165

6266
Indicates to store the password in unencrypted text instead of the default behavior of storing an encrypted form.
6367

68+
> [!WARNING]
69+
> Storing passwords in clear text is strongly discouraged.
70+
> For more information on managing credentials securely, refer to the [security best practices for consuming packages from private feeds](../../consume-packages/consuming-packages-authenticated-feeds.md#security-best-practices-for-managing-credentials).
71+
6472
- **`-UserName`**
6573

6674
Specifies the user name for authenticating with the source.
@@ -80,9 +88,6 @@ where `<operation>` is one of *List, Add, Remove, Enable, Disable,* or *Update*,
8088

8189
Specifies the amount of detail displayed in the output: `normal` (the default), `quiet`, or `detailed`.
8290

83-
> [!Note]
84-
> Make sure to add the sources' password under the same user context as the nuget.exe is later used to access the package source. The password will be stored encrypted in the config file and can only be decrypted in the same user context as it was encrypted. So for example when you use a build server to restore NuGet packages the password must be encrypted with the same Windows user under which the build server task will run.
85-
8691
Also see [Environment variables](cli-ref-environment-variables.md)
8792

8893
## Examples

docs/reference/nuget-config-file.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ Optionally, valid authentication types can be specified with the `-validauthenti
150150
| cleartextpassword | The unencrypted password for the source. Note: environment variables can be used for improved security. |
151151
| validauthenticationtypes | Comma-separated list of valid authentication types for this source. Set this to `basic` if the server advertises NTLM or Negotiate and your credentials must be sent using the Basic mechanism, for instance when using a PAT with on-premises Azure DevOps Server. Other valid values include `negotiate`, `kerberos`, `ntlm`, and `digest`, but these values are unlikely to be useful. |
152152

153+
> [!WARNING]
154+
> Storing passwords in clear text is strongly discouraged.
155+
> Please note that encrypted passwords are only supported on Windows.
156+
> Furthermore, they can only be decrypted when used on the same machine and by the same user who originally encrypted them.
157+
> For more information on managing credentials securely, refer to the [security best practices for consuming packages from private feeds](../consume-packages/consuming-packages-authenticated-feeds.md#security-best-practices-for-managing-credentials).
158+
153159
> [!Tip]
154160
> If a non-encrypted password is passed for `password` the error message ["The parameter is incorrect" will occur](https://github.com/NuGet/Home/issues/3245).
155161
@@ -170,49 +176,51 @@ In the config file, the `<packageSourceCredentials>` element contains child node
170176
</packageSourceCredentials>
171177
```
172178

173-
When using unencrypted passwords stored in an environment variable:
179+
Additionally, valid authentication methods can be supplied.
174180

175181
```xml
176182
<packageSourceCredentials>
177183
<Contoso>
178184
<add key="Username" value="[email protected]" />
179-
<add key="ClearTextPassword" value="%ContosoPassword%" />
185+
<add key="Password" value="..." />
186+
<add key="ValidAuthenticationTypes" value="basic" />
180187
</Contoso>
181188
<Test_x0020_Source>
182189
<add key="Username" value="user" />
183-
<add key="ClearTextPassword" value="%TestSourcePassword%" />
190+
<add key="Password" value="..." />
191+
<add key="ValidAuthenticationTypes" value="basic, negotiate" />
184192
</Test_x0020_Source>
185193
</packageSourceCredentials>
186194
```
187195

188-
When using unencrypted passwords:
196+
When using unencrypted passwords stored in an environment variable:
189197

190198
```xml
191199
<packageSourceCredentials>
192200
<Contoso>
193201
<add key="Username" value="[email protected]" />
194-
<add key="ClearTextPassword" value="33f!!lloppa" />
202+
<add key="ClearTextPassword" value="%ContosoPassword%" />
195203
</Contoso>
196204
<Test_x0020_Source>
197205
<add key="Username" value="user" />
198-
<add key="ClearTextPassword" value="hal+9ooo_da!sY" />
206+
<add key="ClearTextPassword" value="%TestSourcePassword%" />
199207
</Test_x0020_Source>
200208
</packageSourceCredentials>
201209
```
202210

203-
Additionally, valid authentication methods can be supplied:
211+
When using unencrypted passwords:
212+
> [!WARNING]
213+
> Storing passwords in clear text is strongly discouraged.
204214
205215
```xml
206216
<packageSourceCredentials>
207217
<Contoso>
208218
<add key="Username" value="[email protected]" />
209-
<add key="Password" value="..." />
210-
<add key="ValidAuthenticationTypes" value="basic" />
219+
<add key="ClearTextPassword" value="33f!!lloppa" />
211220
</Contoso>
212221
<Test_x0020_Source>
213222
<add key="Username" value="user" />
214223
<add key="ClearTextPassword" value="hal+9ooo_da!sY" />
215-
<add key="ValidAuthenticationTypes" value="basic, negotiate" />
216224
</Test_x0020_Source>
217225
</packageSourceCredentials>
218226
```

0 commit comments

Comments
 (0)