<?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: Kishan Patel</title>
    <description>The latest articles on DEV Community by Kishan Patel (@kishan_patel_39444796092d).</description>
    <link>https://dev.to/kishan_patel_39444796092d</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2777270%2F003e210c-9f18-4d0b-851e-d679394c1974.png</url>
      <title>DEV Community: Kishan Patel</title>
      <link>https://dev.to/kishan_patel_39444796092d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kishan_patel_39444796092d"/>
    <language>en</language>
    <item>
      <title>Correct and Still Broken: A GitHub OIDC Story</title>
      <dc:creator>Kishan Patel</dc:creator>
      <pubDate>Thu, 24 Sep 2026 13:31:10 +0000</pubDate>
      <link>https://dev.to/kishan_patel_39444796092d/correct-and-still-broken-a-github-oidc-story-5a58</link>
      <guid>https://dev.to/kishan_patel_39444796092d/correct-and-still-broken-a-github-oidc-story-5a58</guid>
      <description>&lt;h3&gt;
  
  
  The Moment It Broke
&lt;/h3&gt;

&lt;p&gt;"Welcome to my static site"! These words were like music to my eyes after I set up the AWS backend to host my static HTML website. Excited, I created the basic blog site with Astro and configured CI/CD in &lt;code&gt;deploy.yml&lt;/code&gt; to start the deployment process and guess what came up!... "Welcome to my static site!" Something was wrong...&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Debugged The Issue
&lt;/h3&gt;

&lt;p&gt;I opened up my browser's console to debug if there were any errors, none. I cleared my cache, still my static site showed up. Then I went one level up, I checked in my S3 bucket, it wasn't there... my site never made it to S3. So, I went one more level above, my GitHub actions, and there it was &lt;code&gt;Error: Could not assume role with OIDC: Not authorized to perform sts:AssumeRoleWithWebIdentity&lt;/code&gt;. I then went back to the AWS console and made sure I had &lt;code&gt;github-deploy-site&lt;/code&gt; which was added from Terraform, to rule out Terraform Drift. Next I wanted to see what GitHub was actually sending, so I added a debug step right before the credentials step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;- run: &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ github.repository &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;} / &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ github.ref &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It printed &lt;code&gt;Nasheik/KishanBuilds&lt;/code&gt; and &lt;code&gt;refs/heads/main&lt;/code&gt;. Exactly what my trust policy expected. It was all correct, and at the time I did not realize that those two variables are not the &lt;code&gt;sub&lt;/code&gt; claim. It was only after I asked Claude for help that I was pointed to a GitHub changelog from April 2026 that I hadn't found on my own. The subject portion of GitHub tokens had changed!&lt;/p&gt;

&lt;p&gt;Part of what made this take so long is that the error tells you almost nothing. The same message covers a genuinely mismatched claim, a missing &lt;code&gt;permissions: id-token: write&lt;/code&gt; block so no token is ever minted, and the format change I hit. Three unrelated problems at three different layers, one identical string.&lt;/p&gt;

&lt;h3&gt;
  
  
  The OIDC Process
&lt;/h3&gt;

&lt;p&gt;When I push to the main branch, GitHub mints a short-lived JSON Web Token for each workflow run. It only exists for that run. The three claims that matter in this token are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;iss&lt;/code&gt; — the issuer, GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt; — the audience, &lt;code&gt;sts.amazonaws.com&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt; — the subject, The repo and branch the workflow is running on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main part is the subject. The IAM role's trust policy has a condition on that &lt;code&gt;sub&lt;/code&gt; string and gets used by STS to compare, if they do not match we get the error I got before. If they do match, you get the temporary credentials required to move forward, or, as in my case, upload files to S3 bucket.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Change GitHub Made
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"Repos created after July 15, 2026 get the new &lt;code&gt;sub&lt;/code&gt; format by default."&lt;/strong&gt; This was it, one line I found after Claude pointed me in the right direction. Source: &lt;a href="https://github.blog/changelog/2026-04-23-immutable-subject-claims-for-github-actions-oidc-tokens/" rel="noopener noreferrer"&gt;https://github.blog/changelog/2026-04-23-immutable-subject-claims-for-github-actions-oidc-tokens/&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;Old: repo:OWNER/REPO:ref:refs/heads/BRANCH
New: repo:OWNER@OWNER-ID/REPO@REPO-ID:ref:refs/heads/BRANCH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What my trust policy expected:
repo:Nasheik/KishanBuilds:ref:refs/heads/main

What GitHub actually sent:
repo:Nasheik@MY-OWNER-ID/KishanBuilds@MY-REPO-ID:ref:refs/heads/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was made to prevent someone from inheriting your trust policy. Because the old format is just names, if you abandon your repo, someone else could claim and reproduce that &lt;code&gt;sub&lt;/code&gt; string. With this change, that is not possible as your ID and your repo's ID are embedded into it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Fix
&lt;/h3&gt;

&lt;p&gt;The fix for this was rather simple: change this condition&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;condition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"StringEquals"&lt;/span&gt;
  &lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"token.actions.githubusercontent.com:sub"&lt;/span&gt;
  &lt;span class="nx"&gt;values&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"repo:${var.github_repo}:ref:refs/heads/main"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;condition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"StringEquals"&lt;/span&gt;
  &lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"token.actions.githubusercontent.com:sub"&lt;/span&gt;
  &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"repo:${var.github_repo}:ref:refs/heads/main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"repo:${split("&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="s2"&gt;", var.github_repo)[0]}@${var.github_owner_id}/${split("&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="s2"&gt;", var.github_repo)[1]}@${var.github_repo_id}:ref:refs/heads/main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This accepts either format for this specific repo, so I'm covered whichever way GitHub sends it, but the IDs are pinned, so a different repo would need its own values.&lt;/p&gt;

&lt;h3&gt;
  
  
  What It Taught Me
&lt;/h3&gt;

&lt;p&gt;This tiny bug taught me two different lessons at once. First one, tutorials have timestamps, especially in a field like tech where everything changes so rapidly. You have to continuously learn, break, and re-learn. Second, when it comes to using different services, issues often stem from what one service sends and what the other service expects to receive, which is exactly what I thought my debug step was doing. Double checking that bridge will help catch bugs faster, as long as you're checking the real thing and not something that resembles it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next
&lt;/h3&gt;

&lt;p&gt;Next up: moving Terraform itself into CI. Right now my site deploys through Actions while my infrastructure gets applied from my laptop, which means the only record of what exists in AWS is a file on my machine. Fixing that means remote state, a plan step on every PR, and working out how a pipeline gets permission to manage the very role it's authenticating with, a problem that starts looking a lot like the one mentioned in this post.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>github</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Terraforming a Blog: The Setup</title>
      <dc:creator>Kishan Patel</dc:creator>
      <pubDate>Fri, 11 Sep 2026 12:25:20 +0000</pubDate>
      <link>https://dev.to/kishan_patel_39444796092d/terraforming-a-blog-the-setup-1ofn</link>
      <guid>https://dev.to/kishan_patel_39444796092d/terraforming-a-blog-the-setup-1ofn</guid>
      <description>&lt;h3&gt;
  
  
  Why engineer something when you can overengineer it?
&lt;/h3&gt;

&lt;p&gt;As I am just getting back into cloud, I looked up many different videos and articles about how I should learn cloud engineering. The first one that caught my eye was to start a blog site. There are tons of good options to start a blog with, but I decided why not try to create one myself as an initial project. I also hate writing and never know what to write about, so I figured building the project first would give me something to actually write about. Anddd that's what this is!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Github - Allows for version control and CICD pipeline via Actions&lt;/li&gt;
&lt;li&gt;Terraform - Allocate Resources needed to Run my website&lt;/li&gt;
&lt;li&gt;AWS - Backend Terraform allocates resources from

&lt;ul&gt;
&lt;li&gt;S3 - Where my website is hosted as well as Terraform State&lt;/li&gt;
&lt;li&gt;CloudFront - Content Distribution for my website&lt;/li&gt;
&lt;li&gt;ACM - TLS Certification for CloudFront&lt;/li&gt;
&lt;li&gt;Route 53 - DNS and Domain&lt;/li&gt;
&lt;li&gt;AWS Budgets for cost alerts&lt;/li&gt;
&lt;li&gt;IAM - Defines exactly what each identity is allowed to do

&lt;ul&gt;
&lt;li&gt;SSO - Gives me temporary access to run Terraform locally via CLI, nothing stored&lt;/li&gt;
&lt;li&gt;OIDC - Gives GitHub Actions temporary access to push site to S3, nothing stored&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment Pipeline
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftmobfo62xy5kf9yo9udq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftmobfo62xy5kf9yo9udq.png" alt="Deployment pipeline: CLI push triggers GitHub Actions, which assumes an AWS role via OIDC, builds the site, syncs assets and HTML to S3 separately, then resolves the CloudFront distribution ID and invalidates it" width="500" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After pushing to my GitHub's main branch, GitHub Actions trigger. The actions trigger an &lt;code&gt;npm run build&lt;/code&gt; which creates &lt;code&gt;dist/&lt;/code&gt; output which will be pushed to the website's S3 bucket. When syncing to S3, assets are stored, cached, and immutable - On the other hand html is stored, but not cached, so if I decided to add another blog, the html doesn't get stuck and show old pages on the website. After that, I look up the CloudFront distribution ID and invalidate everything there, so CloudFront, the content distributor, doesn't get stuck sending old copies of the website.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why should you care?
&lt;/h3&gt;

&lt;p&gt;This may not be for those who are less interested in tech and just want something up and running asap. This set up requires understanding of cloud but does give it to you in the process of creation. The ultimate upside is the control, free tier managed services only go so far, then the next tier requires payment. At some point you will hit your limit then have to spend to push the limits further out. That said, there is a reason they charge for their services, there's a lot that I have not covered about security and dynamic sites here.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next
&lt;/h3&gt;

&lt;p&gt;This is just the beginning. I have set up my blog website using Terraform, I plan to improve on the site itself while blogging about it. My next blog will go into further detail about the OIDC bug I encountered and how I fixed it. This is to teach and to learn. What I did may be helpful to you, but it definitely will be helpful for me! Happy Learning!&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>aws</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
