{"id":140,"date":"2018-12-05T00:00:00","date_gmt":"2018-12-05T08:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/nuget\/lock-down-your-dependencies-using-configurable-trust-policies"},"modified":"2018-12-05T00:00:00","modified_gmt":"2018-12-05T08:00:00","slug":"lock-down-your-dependencies-using-configurable-trust-policies","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/lock-down-your-dependencies-using-configurable-trust-policies\/","title":{"rendered":"Lock down your dependencies using configurable trust policies"},"content":{"rendered":"<p>For the past several months we have focused on various features to improve package security and trust. Around a year back, we had <a href=\"https:\/\/blog.nuget.org\/20170914\/NuGet-Package-Signing.html\">announced our plans on various signing functionalities<\/a> that we have been implementing at a steady pace. We enabled <a href=\"https:\/\/blog.nuget.org\/20180522\/Introducing-signed-package-submissions.html\">package author signing<\/a> and <a href=\"https:\/\/blog.nuget.org\/20180810\/Introducing-Repository-Signatures.html\">NuGet.org repository signing<\/a> earlier this year. Continuing on the signing journey, we are happy to announce configurable client policies to secure developer environments for packages. With this feature, developers can now customize their environment to define package authors and\/or package repositories they trust thereby allowing only trusted packages to be installed. This information is stored in the <code>nuget.config<\/code> file and can be configured to match your needs.<\/p>\n<h2>How to lock down your environment<\/h2>\n<h3>Turn on <code>require<\/code> mode<\/h3>\n<p>You can enforce all your package dependencies to be signed just by enabling the <code>require<\/code> mode.<\/p>\n<pre><code class=\"language-cmd\">nuget.exe config -set signatureValidationMode=require<\/code><\/pre>\n<h3>Configure trusted package repositories<\/h3>\n<p>You can then define your trust boundaries by specifying <code>trustedSigners<\/code>. For example, * You may just want to trust all packages available in NuGet.org:<\/p>\n<pre><code class=\"language-cmd\"> nuget.exe trusted-signers add -name NuGet.org -serviceindex https:\/\/api.nuget.org\/v3\/index.json<\/code><\/pre>\n<p>If you want to trust packages from specific NuGet authors\/accounts, you can specify the collection of owners:<\/p>\n<pre><code class=\"language-cmd\"> nuget.exe trusted-signers add -name NuGet.org -serviceindex https:\/\/api.nuget.org\/v3\/index.json -owners microsoft;nuget<\/code><\/pre>\n<blockquote>\n<p>NuGet.org adds repository signature to all new packages. We have started signing existing packages and we will announce when we are done. Subscribe to <a href=\"https:\/\/docs.microsoft.com\/nuget\/tools\/cli-ref-verify\">NuGet\/Announcements<\/a> repo for latest NuGet updates.<\/p>\n<\/blockquote>\n<h3>Configure trusted package authors<\/h3>\n<p>You can configure trust based on the author signature by specifying the certificate fingerprint in SHA256. You can get the SHA256 fingerprint from any signed package using the <a href=\"https:\/\/docs.microsoft.com\/nuget\/tools\/cli-ref-verify\">verify command<\/a>. This enables you to consume packages from this trusted author irrespective of the package repository\/source.<\/p>\n<pre><code class=\"language-cmd\">nuget.exe trusted-signers add -name Microsoft -certificateFingerprint 3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE<\/code><\/pre>\n<blockquote>\n<p>You can also add trusted signers, author or repository, by using an existing signed package. For more information see the <a href=\"https:\/\/docs.microsoft.com\/nuget\/tools\/cli-ref-trusted-signers\">trusted-signers<\/a> command reference.<\/p>\n<\/blockquote>\n<h3>Best practices<\/h3>\n<h4>Share your <code>nuget.config<\/code><\/h4>\n<p><code>nuget.config<\/code> is a great option to share your settings across all your team members and even CI machines. If you keep your <code>nuget.config<\/code> file with the solution folder, install and restore operations will always use these settings. And this file can be easily shared along with your source code. To create a <code>nuget.config<\/code> file you can use the <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/core\/tools\/dotnet-new?tabs=netcore21\"><code>dotnet new nugetconfig<\/code><\/a> from your solution root folder.<\/p>\n<h4>Use a different global-packages folder<\/h4>\n<p>If you have different repos\/solutions on your machine with different trust configurations, you must isolate the global-packages folder for each solution. This is because NuGet does trust validation only on package extraction to the <code>globalPackagesFolder<\/code> i.e. if a package is already present in the <code>globalPackagesFolder<\/code>, there is no check performed.<\/p>\n<h3>Example Config File<\/h3>\n<p>The following <code>nuget.config<\/code> file uses <code>require<\/code> mode and trusts packages in NuGet.org from the <em>Microsoft<\/em> account. Additionally, it also trusts packages signed with a private certificate.<\/p>\n<blockquote>\n<p>Note that the global package folder has also been customized.<\/p>\n<\/blockquote>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;configuration&gt;\n\n  &lt;config&gt;\n    &lt;add key=\"signatureValidationMode\" value=\"require\" \/&gt;    \n    &lt;add key=\"globalPackagesFolder\" value=\"%USERPROFILE%\\.nuget\\TrustedPackages\" \/&gt;\n  &lt;\/config&gt;\n\n &lt;packageSources&gt;\n    &lt;clear \/&gt;\n    &lt;add key=\"local\" value=\"\\\\myserver\\packages\\\" \/&gt;\n    &lt;add key=\"nuget\" value=\"https:\/\/api.nuget.org\/v3\/index.json\" \/&gt;\n &lt;\/packageSources&gt;\n\n &lt;trustedSigners&gt; \n  &lt;author name=\"MyCompanyCert\"&gt;\n    &lt;certificate fingerprint=\"F23175B9B052CE9C9D7E1546316F48A422DA3051FC79F4DB58ED5D78E372CEEC\" \n                 hashAlgorithm=\"SHA256\" \n                 allowUntrustedRoot=\"true\" \/&gt; &lt;!-- Enable private certificates--&gt;\n  &lt;\/author&gt;\n\n  &lt;repository name=\"nuget.org\" serviceIndex=\"https:\/\/api.nuget.org\/v3\/index.json\"&gt;\n    &lt;certificate fingerprint=\"0E5F38F57DC1BCC806D8494F4F90FBCEDD988B46760709CBEEC6F4219AA6157D\" \n                 hashAlgorithm=\"SHA256\" \n                 allowUntrustedRoot=\"false\" \/&gt;\n    &lt;owners&gt;Microsoft&lt;\/owners&gt;\n  &lt;\/repository&gt;\n &lt;\/trustedSigners&gt;\n&lt;\/configuration&gt;\n<\/code><\/pre>\n<h2>Reference documentation<\/h2>\n<p>Here are the docs for <a href=\"https:\/\/docs.microsoft.com\/en-us\/nuget\/consume-packages\/installing-signed-packages#configure-package-signature-requirements\">configuring package signature requirements<\/a>, the nuget.config <a href=\"https:\/\/docs.microsoft.com\/nuget\/reference\/nuget-config-file#trustedsigners-section\">trustedSigners section<\/a>, and the <a href=\"https:\/\/docs.microsoft.com\/nuget\/tools\/cli-ref-trusted-signers\">trusted-signers<\/a> command.<\/p>\n<h2>Conclusion<\/h2>\n<p>Defining trust policies enable additional security checks to protect your entire dependency graph, not only for packages obtained from NuGet.org but also from any other package repository. As long as all the packages you consume are signed you can enable the <code>require<\/code> mode to detect any tampered or unsigned package. It lets you control the authors and repositories that you trust. For more information on how to protect your dependencies with signed packages, look at our <a href=\"https:\/\/docs.microsoft.com\/nuget\/reference\/signed-packages-reference\">documentation<\/a>. If you have any feedback or encounter any issues while using this feature, do reach out to us by creating a <a href=\"https:\/\/github.com\/NuGet\/Home\/issues\">GitHub issue<\/a> or by tagging <a href=\"https:\/\/twitter.com\/nuget\">@nuget<\/a> in your tweets.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For the past several months we have focused on various features to improve package security and trust. Around a year back, we had announced our plans on various signing functionalities that we have been implementing at a steady pace. We enabled package author signing and NuGet.org repository signing earlier this year. Continuing on the signing [&hellip;]<\/p>\n","protected":false},"author":636,"featured_media":611,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[7874,326],"tags":[],"class_list":["post-140","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-nuget","category-security"],"acf":[],"blog_post_summary":"<p>For the past several months we have focused on various features to improve package security and trust. Around a year back, we had announced our plans on various signing functionalities that we have been implementing at a steady pace. We enabled package author signing and NuGet.org repository signing earlier this year. Continuing on the signing [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/140","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/636"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=140"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/140\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/611"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}