<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Karanbir Singh</title>
    <description>The latest articles on DEV Community by Karanbir Singh (@karanbir).</description>
    <link>https://dev.to/karanbir</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F436443%2Fe0d257f2-dcb0-4822-b12e-87aae37b8581.png</url>
      <title>DEV Community: Karanbir Singh</title>
      <link>https://dev.to/karanbir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karanbir"/>
    <language>en</language>
    <item>
      <title>AWS API gateway JWT Authorizer with Zitadel</title>
      <dc:creator>Karanbir Singh</dc:creator>
      <pubDate>Sun, 26 Feb 2023 18:12:50 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-api-gateway-jwt-authorizer-4mnc</link>
      <guid>https://dev.to/aws-builders/aws-api-gateway-jwt-authorizer-4mnc</guid>
      <description>&lt;p&gt;&lt;strong&gt;AWS API gateway&lt;/strong&gt; introduced HTTP API endpoints based integration in recent 2-3 years and they are different from the legacy REST API endpoint.&lt;/p&gt;

&lt;p&gt;With this AWS also introduced JWT authorizer based authorization for the endpoints and made life easy for all the architects and developers, who were previously forced to use a custom authorizer only.&lt;/p&gt;

&lt;p&gt;In this blog post which you are reading the primary focus is on &lt;strong&gt;AWS API gateway JWT Authorizer&lt;/strong&gt; - with Pulumi as IAC provisioner &amp;amp; Zitadel for the identity/ authentication provider.&lt;/p&gt;

&lt;p&gt;Reference to the zitadel setup for client_credentials flow &lt;a href="https://dev.to/karanbir/using-configuring-zitadel-for-integration-with-aws-4cgf"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AWS account.&lt;/li&gt;
&lt;li&gt;Average knowledge about AWS, AWS API Gateway, AWS Lambda Functions.&lt;/li&gt;
&lt;li&gt;AWS CLI, Pulumi CLI on local machine.&lt;/li&gt;
&lt;li&gt;NodeJS 16 on local machine.&lt;/li&gt;
&lt;li&gt;Zitadel cloud account(setting up zitacloud is out of scope of this blog post) - refer my other blog post &lt;a href="https://dev.to/karanbir/using-configuring-zitadel-for-integration-with-aws-4cgf"&gt;here&lt;/a&gt; for setting up zitadel cloud account&lt;/li&gt;
&lt;li&gt;You may also use any other Identity provider. (like AWS cognito, etc.)&lt;/li&gt;
&lt;li&gt;Great to have knowledge of JWT.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Flow Diagram Positive Scenario
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7l1j6n7lhewjwfxwrjlo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7l1j6n7lhewjwfxwrjlo.gif" alt="Flow Diagram Positive Scenario Gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; client fetches the access token required by the API endpoint before hitting the actual endpoint.&lt;/li&gt;
&lt;li&gt;client sends request along with JWT as part of an &lt;strong&gt;Authorization&lt;/strong&gt; Header prefixed with Bearer or can be without Bearer, to API gateway.&lt;/li&gt;
&lt;li&gt;AWS API gateway delegates the Authorization to it's self managed Authorizer(not sure how they might be doing it - could be internally lambda managed?!).&lt;/li&gt;
&lt;li&gt;fetches the jwks based on the issuer property &amp;amp; validates the signature of the JWT based on the kid in the input JWT.&lt;/li&gt;
&lt;li&gt;internal JWT authorizer will return back true/ success.&lt;/li&gt;
&lt;li&gt;API gateway will pass on the original request to the AWS lambda function.&lt;/li&gt;
&lt;li&gt;Lambda function will reply back the response.&lt;/li&gt;
&lt;li&gt;Response received from the lambda function is sent back to the client.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen5yobnxc3ywb5klzty7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen5yobnxc3ywb5klzty7.png" alt="Flow Diagram Positive Scenario"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Flow Diagram Negative Scenario
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6mi9diyupeh4fwyuzlt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6mi9diyupeh4fwyuzlt.gif" alt="Flow Diagram Negative Scenario GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;client fetches the access token required by the API endpoint before hitting the actual endpoint. (or if skipped for testing purpose)&lt;/li&gt;
&lt;li&gt;client sends incorrect or blank or expired or misconfigured token.&lt;/li&gt;
&lt;li&gt;AWS API gateway delegates the Authorization to it's self managed Authorizer(not sure how they might be doing it - could be internally lambda managed?!). It will delegate only if the header was present.&lt;/li&gt;
&lt;li&gt;fetches the jwks based on the issuer property &amp;amp; validates the signature of the JWT based on the kid in the input JWT.&lt;/li&gt;
&lt;li&gt;authorizer will reply back with false.&lt;/li&gt;
&lt;li&gt;API gateway sends back the response as 401 (Unauthorized) or 403(forbidden).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01t538mxn8fgmli2rf8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01t538mxn8fgmli2rf8v.png" alt="Flow Diagram Negative Scenario"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code and configuration
&lt;/h2&gt;

&lt;p&gt;The code repository referred is from the previous &lt;a href="https://dev.to/aws-builders/aws-api-gateway-mtls-authentication-with-smallstep-pulumi-2o65"&gt;blog post&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;change the configuration in the stack's yml files&lt;/li&gt;
&lt;li&gt;domain, cert, zitacloud issuer, etc. as per your setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Link to the repo is &lt;a href="https://github.com/krnbr/aws-api-gateway/tree/authorizer" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the branch is &lt;a href="https://github.com/krnbr/aws-api-gateway/tree/authorizer" rel="noopener noreferrer"&gt;authorizer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The config related to the JWT authorizer are in the &lt;a href="https://github.com/krnbr/aws-api-gateway/blob/authorizer/non-mtls-apis/Pulumi.neuw-ap-south-1.yaml" rel="noopener noreferrer"&gt;file&lt;/a&gt;:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config:
  aws:profile: &amp;lt;AWS_PROFILE&amp;gt;
  aws:region: &amp;lt;AWS_REGION&amp;gt;
  non-mtls-apis:API_DOMAIN: &amp;lt;API_DOMAIN&amp;gt;
  non-mtls-apis:API_DOMAIN_MTLS: &amp;lt;MTLS_API_DOMAIN&amp;gt;
  non-mtls-apis:HOSTED_ZONE_NAME: &amp;lt;HOSTED_ZONE&amp;gt;
  non-mtls-apis:JWT:
    audiences:
      - test
      - aws_client
    issuer: https://instance_code.zitadel.cloud/
  non-mtls-apis:SUB_DOMAIN: &amp;lt;SUB_DOMAIN&amp;gt;
  non-mtls-apis:SUB_DOMAIN_MTLS: mtls.&amp;lt;SUB_DOMAIN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make changes to the audiences and issuer as per the setup.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;audiences&lt;/strong&gt; will be part of the JWT access token as &lt;strong&gt;aud&lt;/strong&gt; claim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;issuer&lt;/strong&gt; is also part of the JWT as &lt;strong&gt;iss&lt;/strong&gt; claim.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If these configurations are not correct - then the API gateway will give error while accessing the endpoints&lt;/p&gt;

&lt;p&gt;The error could be &lt;strong&gt;401 unauthorized&lt;/strong&gt; and relating to the below:-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;issuer incorrect&lt;/li&gt;
&lt;li&gt;jwks url not accessible&lt;/li&gt;
&lt;li&gt;keys not resolvable, kid mismatch&lt;/li&gt;
&lt;li&gt;JWT's - exp nbf, iat not correct&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Please feel free to reach me over Linkedin &lt;a href="https://www.linkedin.com/in/krnbr/" rel="noopener noreferrer"&gt;here&lt;/a&gt; for further questions, doubts or suggestions.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>pulumi</category>
      <category>jwt</category>
      <category>authorizer</category>
    </item>
    <item>
      <title>Using &amp; configuring zitadel for integration with AWS</title>
      <dc:creator>Karanbir Singh</dc:creator>
      <pubDate>Sun, 26 Feb 2023 18:04:20 +0000</pubDate>
      <link>https://dev.to/karanbir/using-configuring-zitadel-for-integration-with-aws-4cgf</link>
      <guid>https://dev.to/karanbir/using-configuring-zitadel-for-integration-with-aws-4cgf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This blog post is primarily related to setting up zitadel cloud account for the post - where I will be explaining the JWT authorizer.&lt;/p&gt;

&lt;p&gt;I will skip the obvious setting up a zitadel account part, setting up of zitadel account is very straightforward and simple. Thanks to their great documentation on their site and great discussions over their discord server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration for client_credentials grant &amp;amp; Jwt type access token
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Setup a service user.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z_kdHah3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wtjismmv9mruy3d5nk3r.png" alt="Setup a service user" width="880" height="363"&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the user details and &lt;strong&gt;access token type JWT&lt;/strong&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RpYdQ0eM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4is7u79w25306n3okh6i.png" alt="access token type JWT" width="880" height="363"&gt;
&lt;/li&gt;
&lt;li&gt;Generate Client credentials
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_qTOhLnO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yi6cg3x2qrtnnbo2qbam.png" alt="Generate Client credentials" width="880" height="428"&gt;
&lt;/li&gt;
&lt;li&gt;Copy the client credentials
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OdX0mS_8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2i6azk77z2r0op7xqbm.png" alt="Call the token endpoint as below" width="880" height="439"&gt;
&lt;/li&gt;
&lt;li&gt;Call the token endpoint as below
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SHeBusR7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/je01tcthsypybh8jcsio.png" alt="Call the token endpoint as below" width="880" height="401"&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Please feel free to reach out to me over Linkedin &lt;a href="https://www.linkedin.com/in/krnbr/"&gt;here&lt;/a&gt; for further questions, doubts or suggestions.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>zitade</category>
      <category>clientcredentials</category>
    </item>
    <item>
      <title>AWS API Gateway MTLS authentication - with SmallStep &amp; Pulumi</title>
      <dc:creator>Karanbir Singh</dc:creator>
      <pubDate>Fri, 17 Feb 2023 07:32:53 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-api-gateway-mtls-authentication-with-smallstep-pulumi-2o65</link>
      <guid>https://dev.to/aws-builders/aws-api-gateway-mtls-authentication-with-smallstep-pulumi-2o65</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;During the 2022 Christmas holidays, I got (re-)introduced to &lt;a href="https://smallstep.com/"&gt;&lt;strong&gt;Smallstep&lt;/strong&gt;&lt;/a&gt; and believe me it is a very promising tech in &lt;strong&gt;PKI&lt;/strong&gt; space, It eases a good number of complex problems that occur if you were self managing the &lt;strong&gt;PKI&lt;/strong&gt; all by yourself from scratch.&lt;/p&gt;

&lt;p&gt;This blog post's main focus is going to be about - Securing the APIs deployed on AWS API gateway using &lt;strong&gt;MTLS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The second focus is on how we can leverage &lt;a href="https://smallstep.com/"&gt;&lt;strong&gt;Smallstep&lt;/strong&gt;&lt;/a&gt; for the &lt;strong&gt;PKI&lt;/strong&gt; part.&lt;/p&gt;

&lt;p&gt;Third most important part being the infra provisioning using &lt;a href="https://www.pulumi.com/"&gt;&lt;strong&gt;Pulumi&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;basic knowledge of mtls &amp;amp; PKI.&lt;/li&gt;
&lt;li&gt;above average knowledge of AWS.&lt;/li&gt;
&lt;li&gt;must own a domain. buy it from AWS route 53, or buy it from somewhere else and configure in AWS route 53 using NS entries.&lt;/li&gt;
&lt;li&gt;AWS CLI installed.&lt;/li&gt;
&lt;li&gt;configure AWS credentials on local, profile based.&lt;/li&gt;
&lt;li&gt;some knowledge of &lt;a href="https://www.pulumi.com/"&gt;&lt;strong&gt;Pulumi&lt;/strong&gt;&lt;/a&gt; IAC.&lt;/li&gt;
&lt;li&gt;Pulumi CLI on local machine.&lt;/li&gt;
&lt;li&gt;account at &lt;a href="https://www.pulumi.com/"&gt;&lt;strong&gt;Pulumi&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;account at &lt;a href="https://smallstep.com/"&gt;&lt;strong&gt;Smallstep&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;step CLI on the developer machine. (OPTIONAL)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Stack Diagram &amp;amp; Details
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m4PTh4qA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2d07tvgo3ab4trhx7z4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m4PTh4qA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2d07tvgo3ab4trhx7z4.png" alt="The stack diagram" width="771" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The following are the important stacks which are part of this POC:-&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;infra&lt;/strong&gt; stack (REQUIRED)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;manages the Certificates required for the API gateway custom domains, using the AWS certificate Manager.&lt;/li&gt;
&lt;li&gt;holds the s3 bucket that is required for the trust store certificate chain.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;functions&lt;/strong&gt; stack (REQUIRED)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;manages the lambda function(s), presently a very basic single lambda function, and related permissions, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;mtls-apis&lt;/strong&gt; stack (REQUIRED)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;manages the API gateway related configuration, routes, integration, etc.&lt;/li&gt;
&lt;li&gt;it refers the &lt;strong&gt;infra&lt;/strong&gt; stack to pull certificate ARNs etc.&lt;/li&gt;
&lt;li&gt;it refers the &lt;strong&gt;infra&lt;/strong&gt; stack to pull s3 bucket &amp;amp; the ca.pem reference for the API gateway.&lt;/li&gt;
&lt;li&gt;it refers the &lt;strong&gt;functions&lt;/strong&gt; stack to pull lambda function ARNs etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;non-mtls-apis&lt;/strong&gt; stack (OPTIONAL)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;manages the API gateway related configuration, routes, integration, etc.&lt;/li&gt;
&lt;li&gt;it refers the infra stack to pull certificate ARNs etc.&lt;/li&gt;
&lt;li&gt;it refers the functions stack to pull lambda function ARNs etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Code details
&lt;/h2&gt;

&lt;p&gt;The code repository for the successful POC is &lt;a href="https://github.com/krnbr/aws-api-gateway-mtls"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The folder structure is same as per the above stack diagram.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important points:-&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Public DNS zone in AWS route 53 was created manually. That is not part of the stack provisioning.&lt;/li&gt;
&lt;li&gt;The order of executing the stack is &lt;a href="https://github.com/krnbr/aws-api-gateway-mtls/tree/main/mtls-infra"&gt;infra&lt;/a&gt;, &lt;a href="https://github.com/krnbr/aws-api-gateway-mtls/tree/main/functions"&gt;functions&lt;/a&gt; &amp;amp; then &lt;a href="https://github.com/krnbr/aws-api-gateway-mtls/tree/main/mtls-apis"&gt;mtls-apis&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Change the config in the pulumi yaml files in respective folders of all stack, for &lt;strong&gt;AWS credentials&lt;/strong&gt;, &lt;strong&gt;region&lt;/strong&gt;, and &lt;strong&gt;DNS domain&lt;/strong&gt; related changes&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;ca.pem&lt;/strong&gt; in the &lt;a href="https://github.com/krnbr/aws-api-gateway-mtls/tree/main/mtls-infra"&gt;infra&lt;/a&gt; stack needs to be replaced based on the own set of smallstep account. It is currently related to my own smallstep account.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  create the ca trust store file.
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Make sure you have a SmallStep Account &amp;amp; you are logged in to same.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By default intermediate and root are created for your account. Click on view details by clicking three dots against the entries of root and intermediate certificates and copy both of certificates into a single file.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XAFMbySG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/821sspmy8aoqd61x7f82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XAFMbySG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/821sspmy8aoqd61x7f82.png" alt="List of certificates" width="880" height="487"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Place the &lt;strong&gt;ca.pem&lt;/strong&gt; in the infra stack's folder.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  create client certificate
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the smallstep dashboard goto -&amp;gt; &lt;strong&gt;Authorities&lt;/strong&gt; -&amp;gt; Click on the &lt;strong&gt;authority&lt;/strong&gt; -&amp;gt; &lt;strong&gt;create certificate using UI&lt;/strong&gt;, fill subject &amp;amp; expiration, as shown below:-
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zEIetICp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8z4jgc5502mz9n1igx2f.png" alt="Create Certificate" width="880" height="492"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorize&lt;/strong&gt;.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3ul99YIU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e3bk1o4frc6lhyze64x9.png" alt="Authorize" width="880" height="552"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Download key and certificate&lt;/strong&gt;, key is only downloadable at this time, later on it will not be available, keep it safe, otherwise the MTLS protected API endpoint might be compromised
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cfS_CJF5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x55xpwb2z0wx9djx51jr.png" alt="Download key and certificate" width="880" height="645"&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Testing the API endpoint using POSTMAN
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Configure the client cert and key in the certificates section in the settings of POSTMAN&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If client cert not provided, the we will get -** Error: read ECONNRESET**&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the client cert and key combo is not correct we will get &lt;strong&gt;403&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If all successful, the API will response back as below:-&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;the path is going to be &lt;a href="https://domain.com/v1/ping"&gt;https://domain.com/v1/ping&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "ping": "pong",
    "success": true,
    "timestamp": 1676617772241
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Please feel free to reach out to me over Linkedin &lt;a href="https://www.linkedin.com/in/krnbr/"&gt;here&lt;/a&gt; for further questions, doubts or suggestions.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>pulumi</category>
      <category>smallstep</category>
      <category>mtls</category>
    </item>
    <item>
      <title>AWS EC2 Metadata sidecar using Nginx</title>
      <dc:creator>Karanbir Singh</dc:creator>
      <pubDate>Sun, 28 Aug 2022 18:27:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-ec2-metadata-viewer-using-nginx-3jgo</link>
      <guid>https://dev.to/aws-builders/aws-ec2-metadata-viewer-using-nginx-3jgo</guid>
      <description>&lt;h2&gt;
  
  
  AWS EC2 Metadata viewer using Nginx Docker Image
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fs3JAG9L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AsxiSakblhBpaVnDa__ZXWA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fs3JAG9L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AsxiSakblhBpaVnDa__ZXWA.png" alt="" width="505" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is just a hobby docker image to &lt;strong&gt;view&lt;/strong&gt;/ look out for the &lt;strong&gt;ec2 instance’s metadata&lt;/strong&gt; using a UI/ html hosted inside/ via &lt;strong&gt;nginx docker image&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While managing the AWS ec2 instances checking the instance metadata via curl is very manual and very repetitive work. So to fetch the same using some UI would be very easy for most us.&lt;/p&gt;

&lt;p&gt;So here I was with the same challenge of removing the unwanted repeated stuff via curls and commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;AWS knowledge, AWS ec2 instance, etc. ❕&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker installed on ec2 instance (obviously) ❕&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;⚠️&lt;strong&gt;Be Aware of the fact that your metadata will be available over web via html. As exposing/ sharing metadata might be&lt;/strong&gt; &lt;strong&gt;security threat&lt;/strong&gt;. (for hobby purpose or private ips it might be ok or public ip with proper security group etc.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❗️ &lt;strong&gt;Metadata v1&lt;/strong&gt; for ec2. Extra work would certainly be required to expose v2 (that is based on tokens etc. and provides extra security over the metadata v1)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WLiHoOeP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2770/1%2AHYG_dB0w4UpvuZJiytgsTg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WLiHoOeP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2770/1%2AHYG_dB0w4UpvuZJiytgsTg.png" alt="" width="880" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Docker image can be accessed using the pull command as below:-&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull neuw/aws-ec2-nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Source code of the same is &lt;a href="https://github.com/neuw/aws-ec2-nginx"&gt;here&lt;/a&gt; available on Github&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For Running the command the container the command is like below:-&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -itd --name nginx -p 80:80 neuw/aws-ec2-nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And after the UI will be available at :-&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://machine_host_or_ip:port/metadata.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Replace hostname or ip and port accordingly&lt;/p&gt;

&lt;p&gt;And UI should be available as below by default&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--prMh5x_G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A7Bxwo7uupKh2YC4FxUYbAg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--prMh5x_G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A7Bxwo7uupKh2YC4FxUYbAg.png" alt="" width="880" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first input box you can change the url to /latest/** and it will show you response accordingly.&lt;/p&gt;

&lt;p&gt;Example:- &lt;strong&gt;/latest/meta-data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IXbswsGM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2102/1%2A7IqeFyH_ux7FZjOcssMGcA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IXbswsGM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2102/1%2A7IqeFyH_ux7FZjOcssMGcA.png" alt="" width="880" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Further one may use the following &lt;strong&gt;user-data&lt;/strong&gt; script while bootstrapping the ec2 instance(applicable for the AWS Linux 2 AMI only), details below:-&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/sh

yum update

# install docker and start the docker service
yum install docker -y
service docker start

# add ec2-user to the docker group
usermod -a -G docker ec2-user

# pull the image that was mentioned above
docker pull krnbr/ec2-nginx:latest

# run the same image as a container available on host's port 80
docker run -itd --name nginx -p 80:80 neuw/aws-ec2-nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Change port 80 to something more specific - And this image can run as sidecar to your other images, for debug purpose in lower environments&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
