Deploying to AWS using GitHub Actions via OpenID Connect [OIDC]
Learn how to use GitHub Actions and OIDC for safe AWS deployment.
![Deploying to AWS using GitHub Actions via OpenID Connect [OIDC]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1734465809709%2F02abc891-0a57-4c34-8e60-068806b36ac5.png&w=3840&q=75)
Search for a command to run...
Learn how to use GitHub Actions and OIDC for safe AWS deployment.
![Deploying to AWS using GitHub Actions via OpenID Connect [OIDC]](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1734465809709%2F02abc891-0a57-4c34-8e60-068806b36ac5.png&w=3840&q=75)
No comments yet. Be the first to comment.
It’s been a few weeks since the completion of Amazon Web Services (AWS) re:Invent. I wanted to share some thoughts. Unfortunately, Amazon Web Services (AWS) re: Invent 2025 didn’t go as planned. Before the event, I had planned all my sessions, the ke...

The first self-replicating worm that compromised npm packages with cloud token-stealing malware

We all know that since the advent of the COVID-19 pandemic, businesses are embracing cloud computing for its scalability, flexibility, and cost savings. However, these advantages come with a growing attack surface, and cloud security flaws have becom...

Imagine you're in a security assessment with your Compliance Team or an External Assessor, and they point out that your AWS environment CloudWatch Log doesn't have a retention period set. CloudWatch Logs retention is an important part of AWS security...

Another incredible year at AWS re:Inforce, and the 2025 edition in Philadelphia did not disappoint. Over the three days, I gained a deeper understanding of AWS security, reconnected with familiar faces who have become like family, and welcomed new pr...

In today's fast-paced development landscape, implementing secure, automated CI/CD pipelines is crucial for efficient software delivery. Traditionally, deploying to AWS using GitHub Actions required creating an IAM user (service account) with key credentials (Access Key and Secret Key).
These credentials would then be stored in GitHub as secrets to enable the Actions workflow. However, this approach posed significant security risks. The stored secrets could remain valid indefinitely, often exceeding the recommended 90-day rotation period for credentials.
If compromised, especially if the credentials have elevated permissions, then malicious actors could exploit them to deploy unauthorized resources like crypto miners or access sensitive data, leading to severe security breaches.
With the integration of GitHub Actions and OpenID Connect (OIDC), Deploying resources to AWS will become more secure. This publication walks you through deploying an S3 bucket to AWS using GitHub Actions and OIDC.
OIDC allows GitHub Actions to securely authenticate with AWS without relying on long-lived access keys. Instead, it leverages temporary credentials granted via an identity provider (IdP) trust relationship between AWS and GitHub.
This approach:
Reduces the risk of credential exposure.
Simplifies authentication management.
Facilitates least-privilege access with short-lived tokens.
An AWS account with IAM permission to create an S3 Bucket.
Basic understanding of creating an AWS IAM role and its functionality.
Basic understanding of GitHub Actions.
Basic Understanding of OIDC OpenID Connector
GitHub repository for your project. Here is my Repository for this project
NOTE:
I’ve outlined two methods for configuring the OIDC Identity provider and connecting it to an IAM role in AWS. The first involves using the Management console, while the second involves utilizing a CloudFormation template provided in the subsequent steps below.
Log in to AWS Management Console:
Go to the IAM Service:
Select Identity Providers:
Click on Add Provider
Choose OpenID Connect, then add Provider Url and Audience. By default, this information is the same for everyone, as GitHub/AWS provides it.
For the provider URL: Use https://token.actions.githubusercontent.com
For the Audience Use sts.amazonaws.com


Now that we've set up the Identity provider, we’ll create an IAM role with the specific permissions we want our GitHub action to have. We’ll also specify the name of the GitHub repository to which the role will grant permission. Finally, we’ll link the Identity provider to the IAM role we created.
Click to open the created identity provider
Click on the Assign Role button at the right corner of the screen

Choose Create a new role

Select “Web identity” as the trusted entity type. Then, fill out the form fields:
- GitHub organization
- GitHub repository
Click on NEXT.

Attached the required permission. In our use case, we will attach S3 full access permission.
Click on NEXT.

Provide the role name and description, and then click on Create role.

Open the CloudFormation Template File in this Repository
Access the CloudFormation YAML file
Update Role Name
Look for the section defining the IAM role in the template
Modify the RoleName property to match the desired role name.
Parameters:
RoleName:
Type: String
Default: "YourUpdatedRoleName"
Description: Name of the IAM role to be created
Update Repository Name
Locate the parameter, resource, or property specifying the repository name.
Replace it with the appropriate repository name.
# GitHub repository name in format owner/repo
RepoName:
Type: String
Default: "YourUpdatedRepoName"
Description: GitHub repository name in format owner/repo
Save the Changes
Deploy the CloudFormation Template
You have successfully deployed your CloudFormation stack! Everything is now set up, and your resources should be ready to use.
In the repository below, you’ll find the GitHub action workflow and a README file that explains how the GitHub action works and how to create your own.
Create a new file .github/workflows/s3-deploy.yml in your repository with the following content:
name: Deploy AWS S3 Bucket with OIDC authentication
on:
push
env:
AWS_REGION : "us-east-1"
AWS_ROLE_TO_ASSUME: "arn:aws:iam::{YOUR-AWS-ACCOUNT-ID}:role/github-actions-s3-oidc-role-dev"
REPOSITORY_NAME: "${{ github.actor }}"
BUCKET_NAME: "${{ github.actor }}-oidc-test-bucket"
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.AWS_ROLE_TO_ASSUME }}
role-session-name: s3-deploy-action-session
aws-region: ${{ env.AWS_REGION }}
- name: Check if bucket exists
id: check_bucket
run: |
if aws s3api head-bucket --bucket ${{ env.BUCKET_NAME }} 2>/dev/null; then
echo "Bucket ${{ env.BUCKET_NAME }} already exists"
echo "bucket_exists=true" >> $GITHUB_OUTPUT
else
echo "Bucket ${{ env.BUCKET_NAME }} does not exist"
echo "bucket_exists=false" >> $GITHUB_OUTPUT
fi
- name: Create S3 bucket
if: steps.check_bucket.outputs.bucket_exists == 'false'
run: |
aws s3api create-bucket \
--bucket ${{ env.BUCKET_NAME }} \
--region ${{ env.AWS_REGION }} \
$(if [ "${{ env.AWS_REGION }}" != "us-east-1" ]; then echo "--create-bucket-configuration LocationConstraint=${{ env.AWS_REGION }}"; fi)
echo "Configuring bucket settings..."
aws s3api put-bucket-versioning \
--bucket ${{ env.BUCKET_NAME }} \
--versioning-configuration Status=Enabled
aws s3api put-bucket-encryption \
--bucket ${{ env.BUCKET_NAME }} \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
}'
- name: Configure bucket public access
if: steps.check_bucket.outputs.bucket_exists == 'false'
run: |
aws s3api put-public-access-block \
--bucket ${{ env.BUCKET_NAME }} \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
The workflow triggers on every push and performs the following operations:
Authenticates with AWS using OIDC
Check if the specified S3 bucket exists
Creates a new bucket if it doesn't exist
Configures bucket security settings and encryption
You need to replace the AWS_ROLE_TO_ASSUME environment variable with your IAM role ARN. Your role ARN should look similar to:
arn:aws:iam::{YOUR-AWS-ACCOUNT-ID}:role/github-actions-s3-oidc-role-dev
Commit and push the changes to your main branch.
Go to the Actions tab in your GitHub repository to monitor the workflow execution.
Verify the S3 bucket creation in the AWS Management Console.

Enhanced Security: Eliminates the need for long-term AWS credentials in GitHub Secrets.
Scalability: Easily manage permissions for multiple repositories.
Cost-Effective: Automates deployment without additional infrastructure.
By leveraging GitHub Actions with OIDC, you can build secure, streamlined CI/CD pipelines to deploy resources like S3 buckets to AWS. This setup not only reduces complexity but also ensures your workflows adhere to modern security best practices.
Try extending this workflow to deploy additional AWS resources, such as Lambda functions or DynamoDB tables, and explore the power of GitHub Actions in simplifying cloud deployments.
Congratulations !!!! Feel free to share your thoughts or ask questions about this guide!