-
Notifications
You must be signed in to change notification settings - Fork 266
[Spec] NuGet Config schema changes to enable trusted signers
Status: Reviewing
Issue for spec - NuGet/Home#6524
Parent spec - Repository-Signatures
Related spec - NuGet-Package-Signing-Client-Policy
As the next wave of package signing, consumers need to be able to trust specific package signers. Further, the trust information needs to be stored into the user's machine.
All NuGet package consumers.
- Enable package consumers to store repository and author trust information.
- Update the schema for the nuget.config file to be able to store repository and author trust information.
- Define a gesture for users to be able to trust signers.
-
Trusted signer key -
Allows a user add a friendly name to identify the signer's trust information. -
Trusted signer type - Identifies the trusted signer with a type. The only permitted values are
authorandrepository. If the value isrepositoryaserviceIndexelement should exist.
Further for each certificate used by the repository, we should store the following -
-
Certificate fingerprint -
Used to assert the package being verified has been signed by the trusted repository. The fingerprint should be a calculated based on theRepository Certificate Fingerprint Algorithmdescribed below. -
Certificate fingerprint algorithm -
Allows for crypto-agility while calculating the certificate fingerprint. The algorithm currently supported are -SHA256SHA384SHA512
-
Untrusted root -
Indicates if it is allowed or disallowed that this certificate chains to an untrusted root.
We should store the following information to enable a trust relationship between a package consumer and a package repository.
- Repository source service index URI -
Allows communication with the source to refresh certificate list and to match with theV3ServiceIndexattribute in a repository signature. If this property is present in a trusted signer entry, the entry is taken to be a repository.
If the user wants to only trust specific package owners for a repository, they should be able to specify a list of trusted owners that will be compared against the Package Owners field in the repository signature metadata.
Trust information should be stored in the nuget.config file.
<trustedSigners>
<NAME>
<add key="type" value="TRUSTED_SIGNER_TYPE" />
<add key="serviceIndex" value="SERVICE_INDEX_URI" /> <!-- If present then type should be Repository -->
<add key="CERT_HASH"
value="FINGERPRINT_ALGORITHM"
untrustedRoot="UNTRUSTED_ROOT" />
<add key="owners" value="LIST_OF_TRUSTED_OWNERS" /> <!-- Can only be present if type is Repository -->
</NAME>
</trustedSigners >For example -
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="NuGet.Org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<trustedSigners>
<NuGet.Org>
<add key="type" value="repository" />
<add key="serviceIndex"
value="https://api.nuget.org/v3/index.json" />
<add key="jQCosvMgBxcgQGNesKaHU1Axvgly73B6jkRXZsf9Y8w="
value="SHA256"
untrustedRoot="disallow" />
<add key="vPv9/fx05OEc4atG7ny+5KXeLbV8xuZhp8ct1fgIhpfdP97ZQ2B801YBaBP61zd="
value="SHA384"
untrustedRoot="disallow" />
<add key="owners" value="aspnet;microsoft" />
</NuGet.Org>
<vsts>
<add key="type" value="repository" />
<add key="serviceIndex"
value="https://api.vsts.com/feed/index.json" />
<add key="OdiswAGAy7da6Gs6sghKmg9e9r90wM385jRXZsf9Y5q="
value="SHA256"
untrustedRoot="allow" />
</vsts>
<Microsoft>
<add key="type" value="author" />
<add key="jQCosvMgBxcgQGNesKaHU1Axvgly73B6jkRXZsf9Y8w="
value="SHA256"
untrustedRoot="disallow" />
</Microsoft>
<PatoBeltran>
<add key="type" value="author" />
<add key="jQCosvMgBxcgQGNesKaHU1Axvgly73B6jkRXZsf9Y8w="
value="SHA256"
untrustedRoot="allow" />
</PatoBeltran>
</trustedSigners>
</configuration>To enable the following user gestures we need to create a new nuget trusted-signers command.
| Operation | Signer Type | Command | Remarks |
|---|---|---|---|
| List | All | nuget trusted-signers |
|
| Add | Repository | nuget trusted-signers Add -Name <n> [-Owners <o>] |
Only works if there exists a source with the same name |
| Add | Repository | nuget trusted-signers Add -Name <n> -ServiceIndex <s> [-Owners <o>] |
|
| Add | Author | nuget trusted-signers Add -Name <n> -CertificateFingerprint <f> -FingerprintAlgorithm <a> [-UntrustedRoot <u>] |
If entry with the same name exists, append the new certificate element.untrustedRoot defaults to disallow
|
| Add | Repository | nuget trusted-signers Add <package_path> -Repository -Name <n> [-Owners <o>] [-UntrustedRoot <u>] |
Only works if package is repository signed or repository countersigned.untrustedRoot defaults to disallow
|
| Add | Author | nuget trusted-signers Add <package_path> -Author -Name <n> [-UntrustedRoot <u>] |
Only works if package is author signed.untrustedRoot defaults to disallow
|
| Remove | Any | nuget trusted-signers Remove -Name <n> |
|
| Sync | Repository | nuget trusted-signers Sync -Name <n> |
Refreshes certificates entries with the ones announced by the repository. The entry has to exist and be a trusted repository with a service index or a corresponding package source. |
This gesture will be translated to dotnet CLI by updating the dotnet nuget add, dotnet nuget remove commands and add a dotnet nuget sync and a dotnet nuget list commands.
| Operation | Signer Type | Command | Remarks |
|---|---|---|---|
| List | All | dotnet nuget list trusted-signers |
|
| Add | Repository | dotnet nuget add trusted-signers -Name <n> [-Owners <o>] |
Only works if there exists a source with the same name |
| Add | Repository | dotnet nuget add trusted-signers -Name <n> -ServiceIndex <s> [-Owners <o>] |
|
| Add | Author | dotnet nuget add trusted-signers -Name <n> -CertificateFingerprint <f> -FingerprintAlgorithm <a> [-UntrustedRoot <u>] |
If entry with the same name exists, append the new certificate element.untrustedRoot defaults to disallow
|
| Add | Repository | dotnet nuget add trusted-signers <package_path> -Repository -Name <n> [-Owners <o>] [-UntrustedRoot <u>] |
Only works if package is repository signed or repository countersigned.untrustedRoot defaults to disallow
|
| Add | Author | dotnet nuget add trusted-signers <package_path> -Author -Name <n> [-UntrustedRoot <u>] |
Only works if package is author signed.untrustedRoot defaults to disallow
|
| Remove | Any | dotnet nuget remove trusted-signers -Name <n> |
|
| Sync | Repository | dotnet nuget sync trusted-signers -Name <n> |
Refreshes certificates entries with the ones announced by the repository. The entry has to exist and be a trusted repository with a service index or a corresponding package source. |
Over the course of time, a repository could deprecate or add certificates to their list of supported certificates. The sync action is designed as a way for the user to explicitly update their trust to that specific repository. This action will send a request to the appropriate service index to get a list of certificates that will replace the current trusted certificates for the corresponding trusted repository entry.
- Given the current inheritance model of the nuget.config, what happens when two configs at different levels have a
trustedSignerelement with the same name? - What happens when there exist multiple entries with the same
serviceIndex, different name value, but with conflicting certificate elements? (e.g. samecertificateFingerprintbut differentuntrustedRootvalue) - Is the schema proposed the most readable/ user-friendly? Is there a way to make it less verbose and still have a deterministic experience for the user.
- If the sync action automatically refreshes the certificates list in a trusted repository entry with the ones announced by the server, should there be a gesture to let the update the
untrustedRootsetting on each certificate given by the server? - Given that
typevalue is based on the presence ofserviceIndex, shouldserviceIndexbe an additional property of the type element? - If a user has a different config on two folders inside a solution, given that we don’t have the granularity of which package asked for a specific package to be downloaded, what trusted signers will be used when verifying each of the packages downloaded?
- The current design only lets the user to add a trusted author with a single certificate and hand edit if more than one certificate should be trusted. Is there a way to create a "batch add" to let the user add a trusted author with multiple certificates?
- Owners in a repository signature are not limited to a set of characters, therefore it is possible that a package owner has a character such as commas (
,). With the current design we are adding the comma (,) delimiter to the owners list, should we update the schema to give a single entry to each trusted owner?
Check out the proposals in the accepted & proposed folders on the repository, and active PRs for proposals being discussed today.