{"id":238248,"date":"2022-08-05T02:08:00","date_gmt":"2022-08-05T06:08:00","guid":{"rendered":"https:\/\/wordpress-756359-3782526.cloudwaysapps.com\/?p=238248"},"modified":"2024-09-30T08:09:48","modified_gmt":"2024-09-30T08:09:48","slug":"22-08-05-smallstep","status":"publish","type":"post","link":"https:\/\/www.travis-ci.com\/blog\/22-08-05-smallstep\/","title":{"rendered":"Doing Certificates with Smallstep &amp; Travis"},"content":{"rendered":"\n<p>You may know something called the ACME protocol for automated certificate management has seen vast adoption in the Web PKI since its inception in 2016. While initially conceived for usage on the public web, the protocol is also well-suited for usage on internal networks, e.g. infranets, infrachats at Colleges, etc. Let\u2019s lerarn more about Smallstep.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"whats-a-x509-certificate\">What\u2019s a X.509 Certificate<\/h2>\n\n\n\n<p>X.509 was first issued in 1988 and was started in association with the X.500 standard. It strictly follows structural system of certificate authorities (CA) for issuing the certificates. The X.509 trust model has three primary substances: certification authority (CA), certificate holder (CH) and relying party (RP). The certification authority is a trusted outsider between the certificate holder and relying party. CAs primary role is to issue a certificate by confirming both the inputs included in the communication.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"pki-standards-for-x509\">PKI standards for X.509<\/h2>\n\n\n\n<p>The X.509 Public-Key Infrastructure (PKI) standard is widely used as a scalable and flexible authentication mechanism. Flaws in X.509 implementations can make relying applications susceptible to impersonation attacks or interoperability issues. In practice, many libraries implementing X.509 have been shown to suffer from flaws that are due to noncompliance with the standard. Developing a compliant implementation is especially hindered by the design complexity, ambiguities, or under-specifications in the standard written in natural languages.<\/p>\n\n\n\n<p>Some of the PKI standards:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>SSL (The predecessor of SSL)<\/li>\n\n\n\n<li>TLS<\/li>\n\n\n\n<li>Online Certificate Status Protocol (OCSP)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"usage\">Usage<\/h2>\n\n\n\n<p>So what I\u2019ve done is create a very simple&nbsp;<code>.travis.yml<\/code>&nbsp;showing off some of Smallstep\u2019s features, and you can start thinking about how this could be useful for your project that\u2019s running Travis. So let\u2019s get into the&nbsp;<code>.travis.yml<\/code>&nbsp;file I created:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dist: jammy\nlanguage: go\ngroup: edge\nsudo: true\n\nscript: \n - wget https:\/\/dl.step.sm\/gh-release\/cli\/docs-cli-install\/v0.20.0\/step-cli_0.20.0_amd64.deb\n - sudo dpkg -i step-cli_0.20.0_amd64.deb\n - step -v \n - step certificate create --profile root-ca \"Montana Mendy Travis CI keys\" ca.crt ca.key --insecure --no-password\n - step certificate inspect https:\/\/smallstep.com<\/code><\/pre>\n\n\n\n<p>This is me using Smallstep on Debian creating a&nbsp;<code>localhost.key<\/code>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"155\" src=\"https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183217280-a7d7e3e3-bf01-4b36-8a94-d8ce2d41e5a6-1024x155-1.png\" alt=\"\" class=\"wp-image-240085\" srcset=\"https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183217280-a7d7e3e3-bf01-4b36-8a94-d8ce2d41e5a6-1024x155-1.png 1024w, https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183217280-a7d7e3e3-bf01-4b36-8a94-d8ce2d41e5a6-1024x155-1-300x45.png 300w, https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183217280-a7d7e3e3-bf01-4b36-8a94-d8ce2d41e5a6-1024x155-1-768x116.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>You\u2019ll see that we are grabbing Smallstep using&nbsp;<code>wget<\/code>, we then use&nbsp;<code>dpkg<\/code>&nbsp;to unzip it, I then check&nbsp;<code>step -v<\/code>&nbsp;to see Smallstep is infact in our VM. I then run the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>step certificate create --profile root-ca \"Montana Mendy Travis CI keys\" ca.crt ca.key --insecure --no-password<\/code><\/pre>\n\n\n\n<p>This is going to create a certificate for me without a password requirement, if you want a password, I\u2019ve created a bash script that enters it into the prompt that becomes accessible once Smallstep asks for your password:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\npass=\"toocool\"\necho $pass | step certificate create --profile root-ca \"Montana Mendy Travis CI keys\" ca.crt ca.key<\/code><\/pre>\n\n\n\n<p>That will get you going in Travis CI if you want a password, and are using this foundation for more than testing purposes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"acme-user-experience\">ACME User Experience<\/h2>\n\n\n\n<p>Now when we are talking the normal user experience when using ACME (not Smallstep per se), it\u2019s something like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Generate a PKCS#10 [RFC2986] Certificate Signing Request (CSR).<\/li>\n\n\n\n<li>Cut and paste the CSR into a CA\u2019s web page.<\/li>\n\n\n\n<li>Prove ownership of the domain(s) in the CSR by one of the following methods:<\/li>\n\n\n\n<li>Put a CA-provided challenge at a specific place on the web server.<\/li>\n\n\n\n<li>Put a CA-provided challenge in a DNS record corresponding to the target domain.<\/li>\n\n\n\n<li>Receive a CA-provided challenge at (hopefully) an administrator-controlled email address corresponding to th domain, and then respond to it on the CA\u2019s web page.<\/li>\n\n\n\n<li>Download the issued certificate and install it on the user\u2019s Web Server.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"jws\">JWS<\/h2>\n\n\n\n<p>If a client wishes to fetch a resource from the server (which would otherwise be done with a GET), then it MUST send a POST request with a JWS body as described above, where the payload of the JWS is a zero-length octet string. In other words, the \u201cpayload\u201d field of the JWS object MUST be present and set to the empty string (\u201c\u201d), or you\u2019ll get a&nbsp;<code>null<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"oh-no-i-got-stuck-at-an-interactive-prompt\">Oh no I got stuck at an interactive prompt!<\/h2>\n\n\n\n<p>Well don\u2019t worry, we\u2019re gonna pass&nbsp;<code>pass<\/code>&nbsp;with&nbsp;<code>$pass<\/code>&nbsp;and telling it to run that along with the&nbsp;<code>step<\/code>&nbsp;command as you remmeber above, but please remember you\u2019ll want to run the following to make sure it has proper permissions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod u+x step.sh \n.\/step.sh<\/code><\/pre>\n\n\n\n<p>The value of the Replay-Nonce header field MUST be an octet string encoded according to the&nbsp;<code>base64url<\/code>&nbsp;encoding. When setting up some of the policies please remember the clients MUST ignore invalid&nbsp;<code>Replay-Nonce<\/code>&nbsp;values, this is an example of what they look like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>base64url = ALPHA \/ DIGIT \/ \"-\" \/ \"_\"\nReplay-Nonce = 1*base64url<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"314\" src=\"https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183215829-e4085090-8f5a-4c6e-ab30-5b7846e3a31c-1024x314-2.png\" alt=\"\" class=\"wp-image-242775\" srcset=\"https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183215829-e4085090-8f5a-4c6e-ab30-5b7846e3a31c-1024x314-2.png 1024w, https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183215829-e4085090-8f5a-4c6e-ab30-5b7846e3a31c-1024x314-2-300x92.png 300w, https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183215829-e4085090-8f5a-4c6e-ab30-5b7846e3a31c-1024x314-2-768x236.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><em>Fig. 1. Overview of the interoperable implementation architecture.<\/em><\/p>\n\n\n\n<p>I can\u2019t get into every aspect of ACME, but do some research about the Interoperable Implementation Arch. It\u2019s quite interesting.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-can-i-sum-up-the-acme-protocol\">How can I sum up The ACME Protocol?<\/h2>\n\n\n\n<p>The ACME client creates a key pair (sometimes referred to as a key value pair), for the domains and provides the ACME server with the public key (contained in an&nbsp;<code>X.509<\/code>&nbsp;certificate signing request (CSR)). The ACME server then issues a certificate containing the public key and all domains previously requested by the client.<\/p>\n\n\n\n<p>The actual ACME protocol is designed to work asynchronously and breaks the sketched flow into several (smaller) steps. Each of these steps is linked to the flow using unique identifiers (provided in URLs) that are issued by the ACME server step-by-step during the flow. The protocol requires the client to authenticate each message (based on the JSON Web Signature (JWS) standard.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ratelimit\">Ratelimit<\/h2>\n\n\n\n<p>Once the rate limit is exceeded, the server MUST respond with an error with the type&nbsp;<code>urn:ietf:params:acme:error:rateLimited<\/code>. Additionally, the server&nbsp;<em>SHOULD<\/em>&nbsp;send a Retry-After header field and tell the end-user when they should try again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-build\">The Build<\/h2>\n\n\n\n<p>You\u2019ll then see the following if your build worked correctly:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"550\" src=\"https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183211757-499552fb-b0f4-4e96-984a-c95dca09a832-1024x550-2.png\" alt=\"\" class=\"wp-image-242780\" srcset=\"https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183211757-499552fb-b0f4-4e96-984a-c95dca09a832-1024x550-2.png 1024w, https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183211757-499552fb-b0f4-4e96-984a-c95dca09a832-1024x550-2-300x161.png 300w, https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/08\/183211757-499552fb-b0f4-4e96-984a-c95dca09a832-1024x550-2-768x413.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>You\u2019ll notice&nbsp;<code>curl<\/code>&nbsp;will pull all the things you need from Google, then we run&nbsp;<code>gcloud components update kubectl<\/code>, and we make sure we Docker listed as a service. Your build should look similar to this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"205\" src=\"https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/07\/181833484-d5193c31-1298-4983-b83f-50ac924e2e65-1-1024x205-1.png\" alt=\"\" class=\"wp-image-242773\" srcset=\"https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/07\/181833484-d5193c31-1298-4983-b83f-50ac924e2e65-1-1024x205-1.png 1024w, https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/07\/181833484-d5193c31-1298-4983-b83f-50ac924e2e65-1-1024x205-1-300x60.png 300w, https:\/\/www.travis-ci.com\/wp-content\/uploads\/2022\/07\/181833484-d5193c31-1298-4983-b83f-50ac924e2e65-1-1024x205-1-768x154.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>You\u2019ll see I have this command as well in our&nbsp;<code>.travis.yml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>step certificate inspect https:\/\/smallstep.com<\/code><\/pre>\n\n\n\n<p>This is to make sure&nbsp;<code>certificate insepct<\/code>&nbsp;is working, and as you can see Smallstep is doing a wonderful job.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>You just got a rundown on The ACME Protocol, and how you can use&nbsp;<code>smallstep<\/code>&nbsp;to use The ACME Protocol and leverage some of it in your Travis CI project.<\/p>\n\n\n\n<p>As always, if you have any questions about this tutorial, please email me at&nbsp;<a href=\"mailto:montana@travis-ci.org\">montana@travis-ci.org<\/a>&nbsp;and I will assist you.<\/p>\n\n\n\n<p>Happy building! Down below you will find relevant links to this tutorial:<\/p>\n\n\n\n<p>Here are some relevant links before you go!<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.smallstep.com\/\">Smallstep<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/Montana\/travis-smallstep\">My GitHub Repo on ACME\/Travis<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>You may know something called the ACME protocol for automated certificate management has seen vast adoption in the Web PKI since its inception in 2016. While initially conceived for usage on the public web, the protocol is also well-suited for usage on internal networks, e.g. infranets, infrachats at Colleges, etc. Let\u2019s lerarn more about Smallstep. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_breakdance_hide_in_design_set":false,"_breakdance_tags":"","footnotes":""},"categories":[16],"tags":[7,19,20,5],"class_list":["post-238248","post","type-post","status-publish","format-standard","hentry","category-news","tag-community","tag-feature","tag-infrastructure","tag-news"],"_links":{"self":[{"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/posts\/238248","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/comments?post=238248"}],"version-history":[{"count":6,"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/posts\/238248\/revisions"}],"predecessor-version":[{"id":242783,"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/posts\/238248\/revisions\/242783"}],"wp:attachment":[{"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/media?parent=238248"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/categories?post=238248"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.travis-ci.com\/wp-json\/wp\/v2\/tags?post=238248"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}