{"id":291809,"date":"2021-07-06T14:00:27","date_gmt":"2021-07-06T11:00:27","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-sign-your-docker-images-to-increase-trust-cloudsavvy-it\/"},"modified":"2021-07-06T14:00:27","modified_gmt":"2021-07-06T11:00:27","slug":"how-to-sign-your-docker-images-to-increase-trust-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-sign-your-docker-images-to-increase-trust-cloudsavvy-it\/","title":{"rendered":"#How to Sign Your Docker Images to Increase Trust \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a25e347339b5\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a25e347339b5\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sign-your-docker-images-to-increase-trust-cloudsavvy-it\/#Generating_Keys\" >Generating Keys<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sign-your-docker-images-to-increase-trust-cloudsavvy-it\/#Adding_Your_Public_Key_to_Your_Registry\" >Adding Your Public Key to Your Registry<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sign-your-docker-images-to-increase-trust-cloudsavvy-it\/#Signing_Images\" >Signing Images<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sign-your-docker-images-to-increase-trust-cloudsavvy-it\/#Verifying_Trusted_Images\" >Verifying Trusted Images<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sign-your-docker-images-to-increase-trust-cloudsavvy-it\/#Summary\" >Summary<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#How to Sign Your Docker Images to Increase Trust \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage aligncenter size-full wp-image-10864\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/04\/075c8694.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Illustration showing the Docker logo\" width=\"1600\" height=\"900\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Most Docker images are distributed without any verification that they\u2019re what they claim to be. You can increase trust in your images by digitally signing them. This proves to users that you published the image, not an imposter.<\/p>\n<p>Docker\u2019s signing system is known as <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/engine\/security\/trust\">content trust<\/a>. It\u2019s exposed through the <code>docker trust<\/code> CLI command. Content Trust uses key sets to let registries verify the identity of prospective publishers. Users of signed images can be confident they come from the expected source.<\/p>\n<h2 id=\"generating-keys\"><span class=\"ez-toc-section\" id=\"Generating_Keys\"><\/span>Generating Keys<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You\u2019ll need a key pair to start using Content Trust. Key pairs can be issued by certificate authorities or generated by the Docker CLI.<\/p>\n<p>Run <code>docker trust key generate your-name<\/code> to create a key. You\u2019ll be prompted to enter a passphrase. This will need to be supplied each time you use the key to sign or verify images. Press enter at each prompt to continue.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12392\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/07\/1294cc6d.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"965\" height=\"316\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Once you\u2019re done, two files will be generated in <code>~\/.docker\/trust<\/code>: the private key and its corresponding public key. Similarly to SSH keys, the private key should never be shared and must not be lost. If you need to move between machines, you can import a private key file into another Docker installation using <code>docker trust key load my-key.pem<\/code>.<\/p>\n<h2 id=\"adding-your-public-key-to-your-registry\"><span class=\"ez-toc-section\" id=\"Adding_Your_Public_Key_to_Your_Registry\"><\/span>Adding Your Public Key to Your Registry<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker Hub supports all the features of <code>docker trust<\/code>. If you\u2019re using a private Docker Registry server, a more involved setup process is required.<\/p>\n<p>The Registry server doesn\u2019t offer built-in signature support. You need a separate <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/hub.docker.com\/_\/notary\">Docker Notary<\/a> service that handles signature verification for image pushes and pulls. Notary <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/theupdateframework\/notary\/blob\/master\/docs\/running_a_service.md\">has three components<\/a>, the server, a signing service, and a MySQL database. It <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/engine\/security\/trust\/trust_delegation\">should be deployed<\/a> on the same URL as your registry server.<\/p>\n<p>You can get Notary up and running by using its Docker Compose file:<\/p>\n<pre><code>git clone https:\/\/github.com\/theupdateframework\/notary.git&#13;\ndocker-compose up -d<\/code><\/pre>\n<p>This basic deployment will run with a self-signed TLS certificate. It\u2019s intended for development use only. You\u2019ll need to trust the certificate authority file <code>fixtures\/root-ca.crt<\/code> in the repository before clients can successfully connect.<\/p>\n<pre><code>sudo mkdir -p \/usr\/share\/ca-certificates\/extra&#13;\nsudo cp fixtures\/root-ca.crt \/usr\/share\/ca-certificates\/extra\/notary.crt&#13;\nsudo update-ca-certificates<\/code><\/pre>\n<p>The commands above will copy the certificate file into the <code>ca-certificates<\/code> storage location. <code>update-ca-certificates<\/code> reloads all certificates, adding the Notary authority to your system.<\/p>\n<p>If you\u2019re going to run Notary in production, you\u2019ll need to setup authentication so only authorized users can add new keys. The <code>NOTARY_AUTH<\/code> environment variable should be set when starting the service with <code>docker-compose<\/code>. This accepts Base64-encoded credentials in <code>username:password<\/code> format. You\u2019ll be prompted to supply these when interacting with Notary.<\/p>\n<pre><code>export NOTARY_AUTH=$(echo \"username\" | base64):$(echo \"password\" | base64)&#13;\ndocker-compose up -d<\/code><\/pre>\n<p>Now you\u2019re ready to add your public key to your Notary server. Keys are added on a per-repository basis. This lets you isolate images from each other and enables support for <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/engine\/security\/trust\/trust_delegation\">delegated third-party contributors<\/a>. You can add other individuals with publish rights later on by getting them to repeat the command with their private key.<\/p>\n<pre><code>docker trust signer add your-key-name registry.example.com\/my-image<\/code><\/pre>\n<p>You\u2019ll need to enter the key\u2019s passphrase. It\u2019ll then be available on your registry server.<\/p>\n<h2 id=\"signing-images\"><span class=\"ez-toc-section\" id=\"Signing_Images\"><\/span>Signing Images<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Once your key\u2019s on the registry, you can start to sign images. Use the <code>docker trust sign<\/code> command. Make sure each image is tagged with the correct registry URL.<\/p>\n<pre><code>docker trust sign registry.example.com\/my-image:latest<\/code><\/pre>\n<p>This command will sign the image with your key and then push it straight up to the registry. There\u2019s no need to manually run <code>docker push<\/code> afterwards. You\u2019ll need to setup a repository key and passphrase to protect the individual image\u2019s trust data. Follow each prompt to setup your signing keys.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12394\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/07\/2ab2be9f.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1290\" height=\"792\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>If you\u2019ve got existing workflows using <code>docker push<\/code>, you can opt for that command instead of <code>docker trust<\/code>. Complete the preceding steps to create a key and add it to Notary. Set the <code>DOCKER_CONTENT_TRUST<\/code> environment variable to have Docker CLI commands detect Content Trust and <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">app<\/a>ly it automatically.<\/p>\n<pre><code>export DOCKER_CONTENT_TRUST=1&#13;\ndocker push registry.example.com\/my-image:latest<\/code><\/pre>\n<p>You\u2019ll see the shell output matches what <code>docker trust sign<\/code> produces. Docker performs the same actions as the more explicit command.<\/p>\n<h2 id=\"verifying-trusted-images\"><span class=\"ez-toc-section\" id=\"Verifying_Trusted_Images\"><\/span>Verifying Trusted Images<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The <code>DOCKER_CONTENT_TRUST<\/code> variable reappears with greater importance when it comes to verifying images you pull. Docker does not attempt to verify images by default, even if they contain trust data. You must set the environment variable in your shell to activate content trust validation.<\/p>\n<pre><code>export DOCKER_CONTENT_TRUST=1&#13;\ndocker pull registry.example.com\/my-image:latest<\/code><\/pre>\n<p>When the variable is set, all image pulls will be checked against their registry\u2019s Notary server. If Notary can\u2019t provide any trust data, the image is treated as unsigned and the pull will be aborted. This protects you from images published by malicious actors masquerading as a genuine publisher.<\/p>\n<p>Docker Enterprise users can configure an optional daemon setting to prevent Docker Engine from working with untrusted images already on the host. These may have arrived in <code>tar<\/code> archives from an unsafe source.<\/p>\n<p>Edit <code>\/etc\/docker\/daemon.json<\/code> and add the following key:<\/p>\n<pre class=\"json\"><code>{&#13;\n    \"content-trust\": {&#13;\n        \"mode\": \"enforced\"&#13;\n    }&#13;\n}<\/code><\/pre>\n<p>Reload the Docker daemon configuration with <code>systemctl reload docker<\/code> to apply the change.<\/p>\n<p>You can inspect the trust status of an image using <code>docker trust inspect<\/code>. This will show the signatures associated with the image, allowing you to check whether it\u2019s been signed.<\/p>\n<pre><code>docker trust inspect registry.example.com\/my-image:latest<\/code><\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12393\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/07\/25bea790.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1277\" height=\"736\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>If you\u2019ve published an image which you no longer want to sign, use the <code>docker trust revoke<\/code> command. This will delete the image\u2019s trust data, causing it to fail all subsequent Docker client verifications.<\/p>\n<pre><code>docker trust revoke registry.example.com\/my-image:latest<\/code><\/pre>\n<h2 id=\"summary\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker Content Trust adds digital signatures to the Docker ecosystem, increasing safety when using images. If you push images to Docker Hub, you\u2019ve already got everything you need to use the feature. Set the <code>DOCKER_CONTENT_TRUST<\/code> environment variable and use Docker commands as normal.<\/p>\n<p>For self-hosted registry users, setup is more complicated but still worth the effort in a trust-critical environment. At the time of writing, Notary still <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/engine\/security\/trust\/deploying_notary\">hasn\u2019t got an<\/a> official stable release and the documentation lives in its <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/theupdateframework\/notary\">GitHub repository<\/a>.\n<\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/12388\/how-to-sign-your-docker-images-to-increase-trust\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#How to Sign Your Docker Images to Increase Trust \u2013 CloudSavvy IT&#8221; Most Docker images are distributed without any verification that they\u2019re what they claim to be. You can increase trust in your images by digitally signing them. This proves to users that you published the image, not an imposter. Docker\u2019s signing system is known&#8230;<\/p>\n","protected":false},"author":1,"featured_media":291810,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/04\/075c8694.jpeg","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-291809","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/291809","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=291809"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/291809\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/291810"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=291809"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=291809"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=291809"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}