GitHub Actions workflows usually require access to a cloud provider (such as AWS, Azure, GCP) in order to use their services and deploy software. The workflow will normally authenticate using credentials such as a password or token before it may access the cloud’s services. These credentials are created in the cloud provider, they are static and stored in Github as secrets. These credentials are valid until you rotate them which you may want to do as a security best practice. Rotation requires commitment in time, effort and it’s not performed seamlessly by any means.
OpenID Connect (OIDC) substitutes the static credentials approach by configuring the workflow to use short-lived access token that was requested directly from the cloud provider. The cloud provider is also configured to support OIDC and this way a trust relationship is enabled between the cloud provider and Github action workflows.
The following diagram shows how Github’s OIDC provider integrates with your workflows and cloud provider
In locals change <REPOSITORY_NAME> with your repo where its github actions needs access to your AWS account
locals {
repository = "repo:<REPOSITORY_NAME>:*"
github_thumbprint = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
}
resource "aws_iam_openid_connect_provider" "github_openid" {
url = "https://token.actions.githubusercontent.com"
client_id_list = [
"sts.amazonaws.com",
]
thumbprint_list = local.github_thumbprint
}
Assign necessary permissions to enable the trust between AWS and Github Action Workflow
resource "aws_iam_role" "github_role" {
name = "GitHib-Actions-Role"
force_detach_policies = true
assume_role_policy = data.aws_iam_policy_document.github_assume_role_policy.json
max_session_duration = 43200
}
data "aws_iam_policy_document" "github_assume_role_policy" {
statement {
sid = "AllowAssumeRoleWithWebIdentity"
actions = ["sts:AssumeRoleWithWebIdentity"]
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:aud"
values = ["sts.amazonaws.com"]
}
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:sub"
values = [local.repository]
}
principals {
type = "Federated"
identifiers = [aws_iam_openid_connect_provider.github_openid.arn]
}
}
}
Provide tailored access to the role for the various AWS resources (Lambda, IAM and S3 full access in this example)
resource "aws_iam_role_policy_attachment" "github_attachment" {
role = aws_iam_role.github_role.name
policy_arn = aws_iam_policy.github_policy.arn
}
resource "aws_iam_policy" "github_policy" {
name = "GithubActionsPolicy"
description = "Github Actions IAM Policy"
policy = data.aws_iam_policy_document.github_document.json
}
data "aws_iam_policy_document" "github_document" {
statement {
actions = [
"sts:AssumeRole",
"lambda:*",
"s3:*",
"iam:*",
]
resources = [
"*"
]
}
}
Change <AWS_REGION> and <AWS_ACCOUNT_ID> to your AWS environment values.
name: Github OIDC example workflow
on:
workflow_dispatch: {}
permissions:
id-token: write
contents: write
jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1-node16
with:
aws-region: <AWS_REGION>
role-to-assume: 'arn:aws:iam::<AWS_ACCOUNT_ID>:role/GithubRole'
- name: Test s3 list buckets
run: aws s3 ls