Enhancing GitHub Actions Security using OIDC Authentication for Cloud Providers

December 13, 2022
May 28, 2024
Enhancing GitHub Actions Security using OIDC Authentication for Cloud Providers

Enhancing GitHub Actions Security using OIDC Authentication for Cloud Providers

Introduction

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.

Benefits of using OIDC

  • No cloud secrets
  • You will configure OICD trust on your cloud provider and your workflow will request short-lived token from the cloud provider through OIDC instead of storing cloud credentials as long-lived Github secrets
  • Rotating credentials
  • With OIDC, you cloud provider issues a temporary access token that is only valid for the specific workflow job run and then expires
  • Authentication and authorization management
  • By leveraging the authentication and authorization tools provided by your cloud provider to manage access to cloud resources, you have more precise control over how workflows can authenticate.

How it works

The following diagram shows how Github’s OIDC provider integrates with your workflows and cloud provider

alter-text
  1. In your cloud provider, create a Github OIDC provider. Configure a cloud role with the associate permissions. This way your cloud role and your GitHub workflow(s) establish a trust which is needed by the workflow to access the cloud.
  2. At every job run iteration, GitHub’s OIDC provider auto-generates a short-lived OIDC token. And is used to authenticate with the cloud provider
  3. An action is used in your job to request this token from GitHub’s OIDC provider, and present it to the cloud provider.
  4. Once the cloud provider successfully validates the claims presented in the token, it then provides a short-lived cloud access token that is available only for the duration of the job.

Example: GitHub and AWS OIDC integration using terraform

AWS configuration

  • Create the OIDC 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
}

  • Create the Github IAM role in AWS

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]
  }
}
}

  • Give additional permissions to the role

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 = [
    "*"
  ]
}
}

Github Configuration

  • Workflow example to utilize OIDC

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

References:

We use cookies on our website

Cookies help us improve your experience, personalize content, and analyze traffic. Click 'Accept' to agree.