<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Iam on Colin Barker</title>
        <link>https://colinbarker.me.uk/tags/iam/</link>
        <description>Recent content in Iam on Colin Barker</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-gb</language>
        <lastBuildDate>Sun, 12 Jan 2025 14:32:19 +0000</lastBuildDate><atom:link href="https://colinbarker.me.uk/tags/iam/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>GitHub Actions and OIDC Update for Terraform and AWS</title>
        <link>https://colinbarker.me.uk/blog/2025-01-12-github-actions-oidc-update/</link>
        <pubDate>Sun, 12 Jan 2025 14:32:19 +0000</pubDate>
        
        <guid>https://colinbarker.me.uk/blog/2025-01-12-github-actions-oidc-update/</guid>
        <description>&lt;img src="https://static.colinbarker.me.uk/img/blog/2023/02/roman-synkevych-wX2L8L-fGeA-unsplash.jpg" alt="Featured image of post GitHub Actions and OIDC Update for Terraform and AWS" /&gt;&lt;blockquote&gt;
&lt;p&gt;Header photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@synkevych?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Roman Synkevych 🇺🇦&lt;/a&gt; on &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/photos/wX2L8L-fGeA?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: This blog posts follows on from my original post back in 2023 where I first set this up. You can find the original blog post &lt;a class=&#34;link&#34; href=&#34;https://colinbarker.me.uk/blog/2023-02-28-github-actions-using-aws-and-openid&#34; &gt;GitHub Actions using AWS and OpenID&lt;/a&gt; by using the link.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;before-we-begin&#34;&gt;Before we begin
&lt;/h2&gt;&lt;p&gt;Please make sure to read my original blog post, it has been updated with the new steps, but this post goes on to specifically call out the changes that allowed this to happen.&lt;/p&gt;
&lt;h2 id=&#34;what-changed&#34;&gt;What changed?
&lt;/h2&gt;&lt;p&gt;A few months beyond my original blog post, GitHub and AWS updated the way that they authenticate between each other, by removing the need to pin the certificate thumbprint as part of the OIDC authentication process. &lt;a class=&#34;link&#34; href=&#34;https://github.blog/changelog/2023-07-13-github-actions-oidc-integration-with-aws-no-longer-requires-pinning-of-intermediate-tls-certificates/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Blog Post&lt;/a&gt;. AWS added GitHub to one if its many root certificate authorities (CAs), meaning GitHub can update their authentication certificate without the need for us to update the thumbprint that existed in the setup step of the OIDC setup. &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Documentation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For a while the &lt;a class=&#34;link&#34; href=&#34;https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md#release-v15120-2024-04-11&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS SDK&lt;/a&gt; and the &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform-provider-aws/pull/37255&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform AWS Provider&lt;/a&gt; had not been updated, so still required a thumbprint to be added to the OIDC provider to allow Terraform to create the resource. Thankfully, in December, AWS updated their main Go SDK, which allowed the owners of the Terraform AWS Provider to make their change to make the Thumbprints Optional.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; For existing implementations, this might be harder to work in, due to a quirk with the AWS API and the way Terraform works. There is a &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform-provider-aws/issues/40509&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;bug issue&lt;/a&gt; open for this. Essentially Terraform will not update the API if there is no default setting, clearing out the Thumbprint list with no default means Terraform will not update the API, so the thumbprints are not removed. As the default behaviour for AWS OIDC configurations that are trusted by AWS means that it ignores the thumbprint list, this should not cause any issues with existing OIDC setups. This is only an issue with Terraform, and not the AWS API.&lt;/p&gt;
&lt;h2 id=&#34;creation-of-the-openid-connect-provider&#34;&gt;Creation of the OpenID Connect Provider
&lt;/h2&gt;&lt;p&gt;Setting up the Identity Provider (IdP) will need to be the updated. The &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;walkthrough&lt;/a&gt; documentation, has also been updated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The provider URL - in the case of GitHub this is &lt;code&gt;https://token.actions.githubusercontent.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;Audience&amp;rdquo; - which scopes what can use this. Confusingly in Terraform this is also known as the &lt;code&gt;client_id_list&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You no longer need to generate the thumbprint&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;adding-the-resource-in-terraform&#34;&gt;Adding the resource in Terraform
&lt;/h3&gt;&lt;p&gt;Now that we have the only two bits we need, it is easy enough to amend / change your Terraform code to set up the &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenID Connect Provider&lt;/a&gt; in IAM. This code example below has been updated to use the only bits you need, removing the need for the old &lt;code&gt;thumbprint_list&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_openid_connect_provider&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;github&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;url&lt;/span&gt; = &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://token.actions.githubusercontent.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;client_id_list&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;sts.amazonaws.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Everything else inside the original blog post still stands.&lt;/p&gt;
&lt;h2 id=&#34;what-about-other-openid-connect-providers&#34;&gt;What about other OpenID Connect Providers?
&lt;/h2&gt;&lt;p&gt;There are only a limited number of providers that AWS have on their root certification CA approved list. Therefore you will need to read the documentation on each provider to find out. If you are still using another OIDC provider with AWS, and need to use the thumbprint, then the usual steps still apply. Below is an updated version of the steps needed for a 3rd party OIDC provider.&lt;/p&gt;
&lt;p&gt;You will need to ensure you have the following&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The provider URL - this is normally supplied by your third party, and should be a public address&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;Audience&amp;rdquo; - which scopes what can use this. Once again in Terraform this is also known as the &lt;code&gt;client_id_list&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The Thumbprint of the endpoint - This one is the tricker one, as you will need to generate this yourself.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;generating-the-thumbprint&#34;&gt;Generating the thumbprint
&lt;/h3&gt;&lt;p&gt;For this example, you will need to ensure that you have downloaded the OIDC provider certificates, or have them to hand to generate the thumbprint. Ideally, if you can get the thumbprint from the provider, that would mean you can skip all the steps.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If you know the url that needs to be used, then you can use the following &lt;code&gt;openssl&lt;/code&gt; command like before.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl s_client -servername tokens.endpoint.oidc.provider.com -showcerts -connect tokens.endpoint.oidc.provider.com:443
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;
&lt;p&gt;Grab the certificate shown in the output, you will see this starting with &lt;code&gt;-----BEGIN CERTIFICATE-----&lt;/code&gt;, then place this content into a file. For this demo, I will use &lt;code&gt;openid.crt&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use the OpenSSL command again to generate the fingerprint from the file created above.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl x509 -in openid.crt -fingerprint -sha1 -noout
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Which should output the fingerprint. Strip away all the extra parts, and the &lt;code&gt;:&lt;/code&gt; between each of the pairs of hexadecimal characters, and you should end up with something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;6938fd4d98bab03faadb97b34396831e3780aea1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; You will need to make the letters lowercase, as Terraform is case sensitive for the variable we need to put this in, but AWS is not case sensitive, so it can sent Terraform into a bit of a loop. ⚠️&lt;/p&gt;
&lt;h3 id=&#34;adding-the-resource-in-terraform-1&#34;&gt;Adding the resource in Terraform
&lt;/h3&gt;&lt;p&gt;With all of this, you can now start to put together the Terraform elements. We can use the Terraform resource for setting up the &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenID Connect Provider&lt;/a&gt; in IAM. Below is a code example, using the information gathered from the documentation and the thumbprint generation, and all placed into a single resource object.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_openid_connect_provider&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;other_oidc_provider&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;url&lt;/span&gt; = &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://tokens.endpoint.oidc.provider.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;client_id_list&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;sts.amazonaws.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;thumbprint_list&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;6938fd4d98bab03faadb97b34396831e3780aea1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;round-up&#34;&gt;Round up
&lt;/h2&gt;&lt;p&gt;While this is a shorter than normal blog post, this should hopefully show the differences between the two types now. Once we get an update on how the bug regarding existing OIDC setups work, I am sure I will post another update!&lt;/p&gt;
&lt;p&gt;Any questions, please let me know!&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GitHub Actions using AWS and OpenID</title>
        <link>https://colinbarker.me.uk/blog/2023-02-28-github-actions-using-aws-and-openid/</link>
        <pubDate>Tue, 28 Feb 2023 16:29:20 +0000</pubDate>
        
        <guid>https://colinbarker.me.uk/blog/2023-02-28-github-actions-using-aws-and-openid/</guid>
        <description>&lt;img src="https://static.colinbarker.me.uk/img/blog/2023/02/roman-synkevych-wX2L8L-fGeA-unsplash.jpg" alt="Featured image of post GitHub Actions using AWS and OpenID" /&gt;&lt;blockquote&gt;
&lt;p&gt;Header photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@synkevych?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Roman Synkevych 🇺🇦&lt;/a&gt; on &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/photos/wX2L8L-fGeA?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Edited: 12th Jan 2025 - The &lt;a class=&#34;link&#34; href=&#34;https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md#release-v15120-2024-04-11&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS SDK&lt;/a&gt; and the &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform-provider-aws/pull/37255&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform AWS Provider&lt;/a&gt; was updated to make the thumbprint optional! See my latest blog post &lt;a class=&#34;link&#34; href=&#34;https://colinbarker.me.uk/blog/2025-01-12-github-actions-oidc-update&#34; &gt;here&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Edited: 18th Sept 2024 - As AWS no longer require you to use a thumbprint when setting up the OIDC connection the thumbprint section is no longer needed, however the &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform-provider-aws/issues/32480&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform Provider&lt;/a&gt; still has an open bug for this. Hopefully, once this issue is closed I will remove the section completely!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;what-is-openid&#34;&gt;What is OpenID?
&lt;/h2&gt;&lt;p&gt;Always a good start, understanding what the key component to this whole post is! As always though, I will reference &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/OpenID&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
    &lt;p&gt;OpenID is an open standard and decentralized authentication protocol promoted by the non-profit OpenID Foundation. It allows users to be authenticated by co-operating sites (known as relying parties, or RP) using a third-party identity provider (IDP) service&amp;hellip;&lt;/p&gt;&lt;span class=&#34;cite&#34;&gt;&lt;span&gt;― &lt;/span&gt;&lt;span&gt;Wikipedia, &lt;/span&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/OpenID&#34;&gt;&lt;cite&gt;OpenID&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;Simple right! Well the technical details of how OpenID works is probably for a much more in-depth specific technical blog for this technology, but the one thing that we need to understand here is that OpenID allows users to be authenticated using 3rd party identify providers. In the case of AWS, their OpenID Connect set up would allow a service in GitHub to authenticate to AWS, and through the IAM system, assume a specific role.&lt;/p&gt;
&lt;p&gt;The question is, why go to the effort to set this all up when a simple Access Key/Secret Key combination would work? Well, as you know from &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/wellarchitected/latest/framework/sec-iam.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Well-Architected best practices&lt;/a&gt;, you should always use temporary credentials over static ones. With the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;assumption of an AWS role&lt;/a&gt;, it uses temporary credentials. With OpenID Connect-compatible identity providers, such as GitHub, you would need to set this up using a Web Identity source. With this post, I will show you how I set this up for this blog (and for the &lt;a class=&#34;link&#34; href=&#34;https://www.tokonatsu.org.uk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tokonatsu&lt;/a&gt; website!)&lt;/p&gt;
&lt;h2 id=&#34;github-actions-using-iam-access-keys&#34;&gt;GitHub Actions using IAM Access Keys
&lt;/h2&gt;&lt;p&gt;This is where I started, as you can see below GitHub has my secrets for the &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;, statically set quite a while ago!&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsOriginalSecrets.png&#34; data-caption=&#34;IAM Access Key and Secret Key statically used&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsOriginalSecrets.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;IAM Access Key and Secret Key statically used&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;Within my GitHub actions pipeline, I am using the &lt;a class=&#34;link&#34; href=&#34;https://github.com/marketplace/actions/configure-aws-credentials-action-for-github-actions&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Configure AWS Credentials&lt;/a&gt; action from the &lt;a class=&#34;link&#34; href=&#34;https://github.com/marketplace&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Marketplace&lt;/a&gt; to configure the secrets for use in the pipeline.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Configure AWS Credentials&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;aws-credentials-configure&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;aws-actions/configure-aws-credentials@v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;aws-access-key-id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;aws-secret-access-key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;aws-region&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.AWS_DEFAULT_REGION }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If you want to see the whole file, then there is a link here to the &lt;a class=&#34;link&#34; href=&#34;https://github.com/mystcb/blog/blob/9909d7cb5dafc560ffb84e235fdf9213d8138f74/.github/workflows/build-and-deploy-site.yaml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;build-and-deploy.yaml&lt;/a&gt; (prior to the changes) file on GitHub.&lt;/p&gt;
&lt;p&gt;As you can see, it is pretty simple, and it worked. The IAM user that owned those keys was happy to sit there and allow the pipeline to access the service. However, that IAM user is still static, and the keys will need to be manually be rotated. From a security stance, anyone that found that key out would be able to do as much as the pipeline could do to my website. As I use &lt;code&gt;aws s3 sync&lt;/code&gt; to copy the website up, while also using the &lt;code&gt;-delete&lt;/code&gt; parameter, it means that I need delete access for this IAM user! Not really the best!&lt;/p&gt;
&lt;p&gt;By using Terraform, I was able to set up all the correct access and switch my pipeline over to using role assumption, thus temporary credentials. GitHub do provide a &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;walkthrough&lt;/a&gt; to set up the OpenID Connect, which is what I based this configuration on. Along with the Terraform Documentation hopefully, this will help you with your journey!&lt;/p&gt;
&lt;h2 id=&#34;creation-of-the-openid-connect-provider&#34;&gt;Creation of the OpenID Connect Provider
&lt;/h2&gt;&lt;p&gt;Setting up the Identity Provider (IdP) will need to be the first step. This action will create a description in IAM of the external IdP and establishes the trust between your account and the organisation, in this case GitHub. This step requires just a few options, of which can be harder to get.&lt;/p&gt;
&lt;p&gt;Using the &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;walkthrough&lt;/a&gt; documentation, we can see that the following is required:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The provider URL - in the case of GitHub this is &lt;code&gt;https://token.actions.githubusercontent.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &amp;ldquo;Audience&amp;rdquo; - which scopes what can use this. Confusingly in Terrraform this is also known as the &lt;code&gt;client_id_list&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The Thumbprint of the endpoint - This one is the tricker one, as you will need to generate this yourself.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;generating-the-thumbprint&#34;&gt;Generating the thumbprint
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;This section is no longer required&lt;/strong&gt; - AWS and GitHub no longer require the setting of thumbprints between them however, the &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform-provider-aws/issues/32480&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform Provider for AWS&lt;/a&gt; still has an open bug as it still requires a value to enter this in. For the best option, just enter in the value &lt;code&gt;00000000000000000000000000000000000000000&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This part wasn&amp;rsquo;t as clear in the GitHub documentation, but I went over to the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Documentation&lt;/a&gt; which gave me instructions on how to generate the thumbprint. You would need a copy of the &lt;code&gt;openssl&lt;/code&gt; CLI o be able to do this, but the quickest way is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use the OpenSSL command to check against the provider URL to get the certificate.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl s_client -servername token.actions.githubusercontent.com -showcerts -connect token.actions.githubusercontent.com:443
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;
&lt;p&gt;Grab the certificate shown in the output, you will see this starting with &lt;code&gt;-----BEGIN CERTIFICATE-----&lt;/code&gt;, then place this content into a file. For this demo, I will use &lt;code&gt;github_openid.crt&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use the OpenSSL command again to generate the fingerprint from the file created above.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;openssl x509 -in github_openid.crt -fingerprint -sha1 -noout
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Which should output the fingerprint. Strip away all the extra parts, and the &lt;code&gt;:&lt;/code&gt; between each of the pairs of hexadecimal characters, and you should end up with something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;6938fd4d98bab03faadb97b34396831e3780aea1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; You will need to make the letters lowercase, as Terraform is case sensitive for the variable we need to put this in, but AWS is not case sensitive, so it can sent Terraform into a bit of a loop. ⚠️&lt;/p&gt;
&lt;h3 id=&#34;adding-the-resource-in-terraform&#34;&gt;Adding the resource in Terraform
&lt;/h3&gt;&lt;p&gt;With all of this, you can now start to put together the Terraform elements. We can use the Terraform resource for setting up the &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenID Connect Provider&lt;/a&gt; in IAM. Below is a code example, using the information gathered from the documentation and the thumbprint generation, and all placed into a single resource object.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_openid_connect_provider&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;github&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;url&lt;/span&gt; = &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://token.actions.githubusercontent.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;client_id_list&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;sts.amazonaws.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;thumbprint_list&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;6938fd4d98bab03faadb97b34396831e3780aea1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This seems simple enough, but this is just authorising GitHub to be a trusted source, and that identities from GitHub can be used to authenticate against AWS. The IAM role set up is where the main bulk of granting access is completed.&lt;/p&gt;
&lt;h2 id=&#34;creating-the-iam-role&#34;&gt;Creating the IAM Role
&lt;/h2&gt;&lt;h3 id=&#34;iam-policy---bucket-access&#34;&gt;IAM Policy - Bucket Access
&lt;/h3&gt;&lt;p&gt;Before access can be granted to the GitHub Actions pipeline, we will need to create a policy that defines the access that the role will have. There isn&amp;rsquo;t much in the way of any difference to this part than creating any other policy however, for this blog and the &lt;a class=&#34;link&#34; href=&#34;https://www.tokonatsu.org.uk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tokonatsu&lt;/a&gt; website, we need some additional permissions outside of the simple &lt;code&gt;s3:PutObject&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the example below, as my S3 bucket is also a resource in Terraform, you can see how I have pulled the bucket ARN for the resource from the outputs of the S3 bucket creation. It is normally best practice to reference variables and other outputs rather than using strings.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# tfsec:ignore:aws-iam-no-policy-wildcards
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_policy_document&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;website_colins_blog_policy&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;version&lt;/span&gt; = &lt;span class=&#34;s2&#34;&gt;&amp;#34;2012-10-17&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;statement&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;effect&lt;/span&gt; = &lt;span class=&#34;s2&#34;&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;resources&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;aws_s3_bucket&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;website_colins_blog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;         # or &amp;#34;unique-bucket-name-for-site&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;aws_s3_bucket&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;website_colins_blog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arn&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/*&amp;#34;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;   # or &amp;#34;unique-bucket-name-for-site/*&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;actions&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;s3:DeleteObject&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;s3:GetBucketLocation&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;s3:GetObject&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;s3:ListBucket&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;s3:PutObject&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;⚠️ &lt;strong&gt;Note:&lt;/strong&gt; As I use &lt;code&gt;tfsec&lt;/code&gt; to keep an eye on my Terraform, it attempts to look at the policy and look for anything that might be considered an issue. On the first line you can see the &lt;code&gt;tfsec:ignore:aws-iam-no-policy-wildcards&lt;/code&gt; comment, which means &lt;code&gt;tfsec&lt;/code&gt; will ignore that rule when it checks my Terraform. As we need to give this role access to do the listed actions on all objects in the bucket, a wildcard is easier. Hence the rule to stop the error from showing up. ⚠️&lt;/p&gt;
&lt;h3 id=&#34;iam-policy---role-assumption&#34;&gt;IAM Policy - Role Assumption
&lt;/h3&gt;&lt;p&gt;As we will be using rule assumption, there needs to be an additional policy document created that will be added to the Role, that can tell it who can assume the role. You might have seen a similar version when using &lt;code&gt;sts:AssumeRole&lt;/code&gt; as an action, for principles that cover other accounts as an example. With the &lt;code&gt;sts:AssumeRoleWithWebIdentity&lt;/code&gt; what we are telling AWS tha the role assumption needs to happen if they have a &amp;ldquo;web identity&amp;rdquo;, one of the external providers.&lt;/p&gt;
&lt;p&gt;The primary element to ensuring the right IdP is used when looking for which identity to grant access too, we need to reference the &lt;code&gt;ARN&lt;/code&gt; of the OpenID Connect Provider added earlier. As the Terraform resource we used above was identified with &lt;code&gt;aws_iam_openid_connect_provider.github&lt;/code&gt;, we can use one of its attributes to programmatically add the ARN to the principles. We will need to specify the &lt;code&gt;type&lt;/code&gt; in Terraform as &amp;ldquo;Federated&amp;rdquo; as well.&lt;/p&gt;
&lt;p&gt;The last two bits are &lt;code&gt;condition&lt;/code&gt; blocks and these are unique to the GitHub OpenID Connect set up. There is a little more detail on the &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services#adding-the-identity-provider-to-aws&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Actions: OpenID Connect in AWS&lt;/a&gt; page. Using this page, I am adding two &amp;ldquo;StringLike&amp;rdquo; tests to the role, that looks for two specific variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;token.actions.githubusercontent.com:sub&lt;/code&gt; - Which is used to specify which repo&amp;rsquo;s GitHub actions are allowed access.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;token.actions.githubusercontent.com:aud&lt;/code&gt; - That ensures that AWS&amp;rsquo;s STS service is the one that is requesting the identity type, and no others.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;token.actions.githubusercontent.com:sub&lt;/code&gt; in my actual repo it says that any &lt;code&gt;repo&lt;/code&gt; in my personal space &lt;code&gt;mystcb&lt;/code&gt; called &lt;code&gt;blog&lt;/code&gt; using any branch, can access. While this is very open, my personal blog only really can be edited by myself, and I would want the role to also activate on any test branches as well. This is shown on my personal Terraform as &lt;code&gt;repo:mystcb/blog:*&lt;/code&gt;. The example I have below is more specific, and only allows access if the GitHub action is working from the &lt;code&gt;main&lt;/code&gt; branch. What I wanted to show here is a secure version, but also showing how you can add wildcards to the &lt;code&gt;value&lt;/code&gt; to cover more branches if need be.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_policy_document&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;website_colins_blog_role_assumption&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;version&lt;/span&gt; = &lt;span class=&#34;s2&#34;&gt;&amp;#34;2012-10-17&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;statement&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;effect&lt;/span&gt; = &lt;span class=&#34;s2&#34;&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;actions&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;sts:AssumeRoleWithWebIdentity&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;condition&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;test&lt;/span&gt;     = &lt;span class=&#34;s2&#34;&gt;&amp;#34;StringLike&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;      variable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;token.actions.githubusercontent.com:sub&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;values&lt;/span&gt;   = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;repo:mystcb/blog:ref:refs/heads/main&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;condition&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;test&lt;/span&gt;     = &lt;span class=&#34;s2&#34;&gt;&amp;#34;StringLike&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;      variable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;token.actions.githubusercontent.com:aud&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;values&lt;/span&gt;   = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;sts.amazonaws.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;principals&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;type&lt;/span&gt;        = &lt;span class=&#34;s2&#34;&gt;&amp;#34;Federated&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;identifiers&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;aws_iam_openid_connect_provider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;github&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Now we have our two policy documents as Terraform data objects, we can then pull them together to create the role&lt;/p&gt;
&lt;h3 id=&#34;creation-of-the-iam-role&#34;&gt;Creation of the IAM Role
&lt;/h3&gt;&lt;p&gt;For us to create the role, we need to pull together all the bits we have created so far. This will mean doing a few special tricks with the data resources.&lt;/p&gt;
&lt;p&gt;Firstly we need to create an &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IAM Policy&lt;/a&gt; resource, that the &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IAM Role&lt;/a&gt; resource can use to &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;attach&lt;/a&gt; to the newly created role.&lt;/p&gt;
&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IAM Policy&lt;/a&gt; resource require 3 elements, the &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt; , and the &lt;code&gt;policy&lt;/code&gt; in JSON format. While the name and path can be as custom as you need, the policy in JSON format is what might trip a few people up. The &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IAM Policy Document&lt;/a&gt; data object has just one Attribute output tha can be referenced here: &lt;code&gt;json&lt;/code&gt;. This conversion means we can quickly add the three together to make the IAM Policy object in AWS.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_policy&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;website_colins_blog&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;   = &lt;span class=&#34;s2&#34;&gt;&amp;#34;access_to_website_colins_blog_s3&amp;#34;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;    # This is my example name!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;path&lt;/span&gt;   = &lt;span class=&#34;s2&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;                                   # Root path for ease
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;policy&lt;/span&gt; = &lt;span class=&#34;nb&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;aws_iam_policy_document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;website_colins_blog_policy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Next, we need to create the role itself which has two key elements, the &lt;code&gt;name&lt;/code&gt; and the &lt;code&gt;assume_role_policy&lt;/code&gt;. The name is as you want this to be however, the &lt;code&gt;assume_role_policy&lt;/code&gt; will be needed to let AWS IAM know what can assume this role. In our case, it is the JSON output from our second &lt;a class=&#34;link&#34; href=&#34;#creating-the-iam-policy---role-assumption&#34; &gt;IAM Policy Document&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_role&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;website_colins_blog_github_role&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;               = &lt;span class=&#34;s2&#34;&gt;&amp;#34;access_to_website_colins_blog_s3_role&amp;#34;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;      # This is my example name!
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;assume_role_policy&lt;/span&gt; = &lt;span class=&#34;nb&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;aws_iam_policy_document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;website_colins_blog_role_assumption&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Great! Now we have role, and we can assume it it - well not exactly, one last step. With IAM, you can attach multiple policies to a single role, which if you created in line with the &lt;code&gt;aws_iam_role&lt;/code&gt; resource it can make it a little more complicated, and very long. The AWS provider allows us two methods to manage the role&amp;rsquo;s policies. One is through &lt;code&gt;managed_policy_arns&lt;/code&gt;/&lt;code&gt;inline_policy&lt;/code&gt; or &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;aws_iam_policy_attachment&lt;/a&gt;. The former two work very much the same, but takes exclusive authority over the state of the IAM Role itself. This means if you attach policies using the latter resource object, you will find Terraform getting stuck in a cycle. For this example, I am using the policy attachment resource.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_role_policy_attachment&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;website_colins_blog&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;role&lt;/span&gt;       = &lt;span class=&#34;nx&#34;&gt;aws_iam_role&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;website_colins_blog_github_role&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;policy_arn&lt;/span&gt; = &lt;span class=&#34;nx&#34;&gt;aws_iam_policy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;website_colins_blog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This block is where all the references from before make this easier. This is where the role resource object, and the policy resource object come together to create the role. Now, AWS is aware of GitHub, its OpenID Connect provider, and we have given a specific repo&amp;rsquo;s GitHub actions that run on the main branch access to assume a role in AWS, which give it access to AWS S3. The role assumption will use temporary credentials for each of the runs!&lt;/p&gt;
&lt;p&gt;One last bit, this part will enable you to get the ARN for the role, which will be required for the configuration of GitHub.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;website_colins_blog_role_arn&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;description&lt;/span&gt; = &lt;span class=&#34;s2&#34;&gt;&amp;#34;The role ARN for the Website: Colin&amp;#39;s Blog Role&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;value&lt;/span&gt;       = &lt;span class=&#34;nx&#34;&gt;aws_iam_role&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;website_colins_blog_github_role&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;arn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Very simple, it just outputs the ARN for the role which will need to be copied to GitHub. For the rest of the blog, I am going to be using an example role in my examples. This will not work, so make sure you are getting your role that matches your account. The ARN we will be using will be&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;arn:aws:iam::12326264843:role/access_to_website_colins_blog_s3_role&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsRoleCreated.png&#34; data-caption=&#34;One IAM Role created, with federation to GitHub&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsRoleCreated.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;One IAM Role created, with federation to GitHub&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;h2 id=&#34;github-actionsworkflow-updates&#34;&gt;GitHub Actions/Workflow Updates
&lt;/h2&gt;&lt;p&gt;To enable this, we need to update the workflow yaml file, and this is probably the easiest bit of the whole post!&lt;/p&gt;
&lt;h3 id=&#34;add-the-role-arn-as-a-secret&#34;&gt;Add the Role ARN as a secret
&lt;/h3&gt;&lt;p&gt;This is where we need to move back to GitHub and grab the ARN from above, and add this as an add the URL to the Repository Secrets. You should be able to find your version at &lt;code&gt;https://github.com/&amp;lt;yourname/org&amp;gt;/&amp;lt;yourrepo&amp;gt;/settings/secrets/actions&lt;/code&gt;. This is under &lt;code&gt;Settings -&amp;gt; Secrets and variables -&amp;gt; Actions&lt;/code&gt; and click &lt;code&gt;New Secret&lt;/code&gt;. Enter in a name for the secret, and its value which I have put in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: &lt;code&gt;AWS_ROLE_ARN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secret&lt;/strong&gt;: &lt;code&gt;arn:aws:iam::12326264843:role/access_to_website_colins_blog_s3_role&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsAddNewSecret.png&#34; data-caption=&#34;Entering in the new secret with the role ARN&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsAddNewSecret.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Entering in the new secret with the role ARN&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;Once you have added that, make sure to remove the two existing Repository Secrets, in my case I called them&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The AWS CLI will always use the keys over role assumption in it&amp;rsquo;s priority so always best to remove them. With the two older secrets removed you should now have just the &lt;code&gt;AWS_ROLE_ARN&lt;/code&gt; and &lt;code&gt;AWS_DEFAULT_REGION&lt;/code&gt;&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsListSecretsNew.png&#34; data-caption=&#34;Only the final two secrets left&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsListSecretsNew.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Only the final two secrets left&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;h3 id=&#34;update-the-workflow-yaml-file&#34;&gt;Update the Workflow YAML file
&lt;/h3&gt;&lt;p&gt;For GitHub actions to be able to assume the role, there are two changes that need to be made to the workflow yaml file. The first one, will be the need to enable the workflow to interact with GitHub&amp;rsquo;s OIDC Token endpoint. Part of the assumption process will require us to identify as a web identity from GitHub to have AWS know who we are. As such you will need to add additional &lt;code&gt;permissions&lt;/code&gt; to the job. Specifically the following&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;id-token&lt;/code&gt; to &lt;code&gt;write&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contents&lt;/code&gt; to &lt;code&gt;read&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So it should look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hugo_build_and_deploy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runs-on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ubuntu-latest&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;permissions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id-token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Later on in the pipeline, where we configured the AWS credentials before, you will need to remove the older secret variables, and put the new secrets in:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Configure AWS Credentials&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;aws-credentials-configure&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;aws-actions/configure-aws-credentials@v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;role-to-assume&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.AWS_ROLE_ARN }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;aws-region&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.AWS_DEFAULT_REGION }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;To see this whole file in context, I would recommend having a look at &lt;a class=&#34;link&#34; href=&#34;https://github.com/mystcb/blog/blob/main/.github/workflows/build-and-deploy-site.yaml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;this blog&amp;rsquo;s workflow&lt;/a&gt; on GitHub!&lt;/p&gt;
&lt;p&gt;All you need to do now, is run the GitHub Actions workflow, and make sure it works! With my blog workflow, it was pretty much a drop in replacement for the IAM credentials. There were a &lt;a class=&#34;link&#34; href=&#34;https://github.com/mystcb/blog/actions&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;few minor issues&lt;/a&gt; with my workflow, but nothing that following this wouldn&amp;rsquo;t have resolved fo me!&lt;/p&gt;
&lt;h2 id=&#34;some-minor-issues&#34;&gt;Some minor issues
&lt;/h2&gt;&lt;p&gt;As you can see, it wasn&amp;rsquo;t exactly first time running for me! It did take a while, and also I had placed a &lt;code&gt;--acl public-read&lt;/code&gt; as part of the &lt;code&gt;aws s3 sync&lt;/code&gt; command, which the new bucket I created had been set to block public ACLs!&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsActionsList.png&#34; data-caption=&#34;Just a few mistakes!&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsActionsList.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Just a few mistakes!&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;There was one other issue, and that was with the &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; that is used. In normal operation, without the added permissions, this token worked fine with an additional Marketplace action called &lt;a class=&#34;link&#34; href=&#34;https://github.com/marketplace/actions/github-deployments&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Deployments&lt;/a&gt;. However, changing this over to allow the OpenID Connect feature, it meant that the token mysteriously stopped working.&lt;/p&gt;
&lt;h3 id=&#34;switching-to-use-a-fine-grained-pat&#34;&gt;Switching to use a Fine-grained PAT
&lt;/h3&gt;&lt;p&gt;On the 18th of October 2022, GitHub offered up a new service called &lt;a class=&#34;link&#34; href=&#34;https://github.blog/2022-10-18-introducing-fine-grained-personal-access-tokens-for-github/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Fine-grained personal access tokens&lt;/a&gt;. The idea is that rather than creating a very open Personal Access Token (PAT), you could create a token that was very limited in it&amp;rsquo;s reach. It is still in beta as I write this blog (28th Feb 2023).&lt;/p&gt;
&lt;p&gt;Using this beta feature, I was able to create a new token, limiting it to specifically the blog repo, and specific permissions. The screenshot below shows the details about the new PAT. (I am aware I could probably reduce the permissions a little more!)&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsFineGrainedPAT.png&#34; data-caption=&#34;A new Fine-grained Personal Access Token (beta)&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2023/02/GitHubActionsFineGrainedPAT.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;A new Fine-grained Personal Access Token (beta)&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;From here, I added a new respository secret called &lt;code&gt;REPO_TOKEN&lt;/code&gt; with the value of the newly generated token, and then updated the part in the workflow that needed it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Set Deploy Status&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;deploy-status-start&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bobheadxi/deployments@v1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;step&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ secrets.REPO_TOKEN }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Prod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ref&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${{ github.ref }}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;round-up&#34;&gt;Round up
&lt;/h2&gt;&lt;p&gt;Hopefully what I have shown you in this post is how to move away from IAM Credentials, and use the OpenID Connect features of both AWS and GitHub to enable role based assumption to gain access to an S3 bucket that stores, in my case, a static website.&lt;/p&gt;
&lt;p&gt;If you do have any questions, comments, please let me know!&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
