Terraform module to configure GitHub Actions as an OpenID Connect (OIDC) identity provider in AWS, allowing GitHub Actions to obtain short-lived credentials by assuming IAM roles directly, and enabling secure authentication between GitHub Actions workflows and AWS resources.
- Terraform 1.3+
The following snippet shows the minimum required configuration to create a working OIDC connection between GitHub Actions and AWS.
module "oidc_github" {
source = "unfunco/oidc-github/aws"
version = "3.1.0"
github_subjects = ["org/repo"]
}By default, bare github_subjects entries are expanded to the
ref:refs/heads/main subject. You can set default_subject to a different
value such as ref:refs/heads/master, pull_request, or *, but * is
broader than most projects need.
Each github_subjects entry can also include an explicit GitHub OIDC subject
suffix. That means pull requests do not require default_subject = "*",
and can be allowed explicitly alongside the default branch:
github_subjects = [
"org/repo",
"org/repo:pull_request",
"org/repo:ref:refs/heads/release/*",
"org/repo:ref:refs/tags/v*",
]To attach additional AWS managed policies to the IAM role, provide the policy
name or path after policy/ and the module will generate the correct ARN for
the active AWS partition:
iam_role_policy_names = [
"ReadOnlyAccess",
"service-role/AWSLambdaBasicExecutionRole",
]The following demonstrates how to use GitHub Actions once the Terraform module has been applied to your AWS account. The action receives a JSON Web Token (JWT) from the GitHub OIDC provider and then requests an access token from AWS.
jobs:
caller-identity:
name: Check caller identity
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v6
with:
aws-region: eu-west-2
role-to-assume: arn:aws:iam::123456789010:role/GitHubActions
- run: aws sts get-caller-identityFor GitHub Enterprise Cloud with data residency, set
github_enterprise_subdomain to the label before .ghe.com (for example,
acme for acme.ghe.com). This uses the issuer
https://token.actions.acme.ghe.com and organisation audiences at
https://acme.ghe.com/ORG. Leave enterprise_slug empty unless your enterprise
has separately enabled a custom OIDC issuer with a path in its iss claim.
Check the token's actual iss and sub claims when configuring AWS; some
enterprises use immutable owner@ownerId/repo@repoId subjects.
For a custom enterprise-scoped issuer, set enterprise_slug to the slug in
the token's iss claim. This adds /SLUG to the issuer URL and IAM condition
keys; it is independent of the data-residency subdomain.
Setting enterprise_slug in AWS is only one side of the configuration. An
enterprise administrator must also enable the custom issuer policy in GitHub so
that Actions will issue tokens from the enterprise-scoped URL. For an
enterprise on github.com, this can be enabled with:
gh auth refresh -h github.com -s admin:enterprise
gh api \
-X PUT \
-H "Accept: application/vnd.github+json" \
/enterprises/ENTERPRISE/actions/oidc/customization/issuer \
--input - <<< '{"include_enterprise_slug":true}'A successful request returns 204 No Content, so gh api will exit without a
response body. Add -i if you want to see the HTTP status line.
To validate the change end-to-end, rerun a workflow that requests an OIDC token
and confirm that your cloud provider sees the enterprise-scoped issuer (for
example token.actions.githubusercontent.com/ENTERPRISE) or that
aws-actions/configure-aws-credentials now succeeds against the
enterprise-scoped IAM OIDC provider.
| Name | Type |
|---|---|
| aws_iam_openid_connect_provider.github | resource |
| aws_iam_role.github | resource |
| aws_iam_role_policy.inline_policies | resource |
| aws_iam_role_policy_attachment.admin | resource |
| aws_iam_role_policy_attachment.custom | resource |
| aws_iam_openid_connect_provider.github | data source |
| aws_iam_policy_document.assume_role | data source |
| aws_partition.this | data source |
| tls_certificate.github | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| additional_audiences | Additional OIDC audiences allowed to assume the role. | list(string) |
null |
no |
| additional_thumbprints | Additional thumbprints for the OIDC provider. | list(string) |
[] |
no |
| create | Enable/disable the creation of all resources. | bool |
true |
no |
| create_iam_role | Enable/disable creation of the IAM role. | bool |
true |
no |
| create_oidc_provider | Enable/disable the creation of the GitHub OIDC provider. | bool |
true |
no |
| dangerously_attach_admin_policy | Enable/disable the attachment of the AdministratorAccess policy. | bool |
false |
no |
| default_subject | Default GitHub OIDC subject pattern appended to github_subjects entries without an explicit subject suffix. Examples: ref:refs/heads/main, pull_request, *. | string |
"ref:refs/heads/main" |
no |
| enterprise_slug | Enterprise slug for an explicitly enabled custom OIDC issuer. Adds a path to the issuer URL and IAM condition keys; leave empty for data residency alone. | string |
"" |
no |
| github_enterprise_subdomain | GitHub Enterprise Cloud data residency subdomain (e.g. acme for acme.ghe.com). Leave empty to use github.com. | string |
"" |
no |
| github_subjects | GitHub repository subject patterns authorized to assume the role. Entries may be bare owner/repository values or include an explicit subject suffix such as :pull_request or :ref:refs/tags/v*. | list(string) |
[] |
no |
| iam_role_description | Description of the IAM role to be created. | string |
"Assumed by the GitHub OIDC provider." |
no |
| iam_role_force_detach_policies | Force detachment of policies attached to the IAM role. | bool |
false |
no |
| iam_role_inline_policies | Inline policies map with policy name as key and json as value. | map(string) |
{} |
no |
| iam_role_max_session_duration | The maximum session duration in seconds. | number |
3600 |
no |
| iam_role_name | The name of the IAM role to be created and made assumable by GitHub Actions. | string |
"GitHubActions" |
no |
| iam_role_path | The path under which to create IAM role. | string |
"/" |
no |
| iam_role_permissions_boundary | The ARN of the permissions boundary to be used by the IAM role. | string |
"" |
no |
| iam_role_policy_names | AWS managed IAM policy names to attach to the IAM role. Provide the value after policy/, for example ReadOnlyAccess or service-role/AWSLambdaBasicExecutionRole. |
list(string) |
[] |
no |
| iam_role_tags | Additional tags to be applied to the IAM role. | map(string) |
{} |
no |
| oidc_provider_tags | Tags to be applied to the OIDC provider. | map(string) |
{} |
no |
| tags | Tags to be applied to all applicable resources. | map(string) |
{} |
no |
| Name | Description |
|---|---|
| assume_role_policy | The assume role policy document that can be attached to your IAM roles. |
| iam_role_arn | The ARN of the IAM role. |
| iam_role_name | The name of the IAM role. |
| oidc_provider_arn | The ARN of the OIDC provider. |
| oidc_provider_url | The URL of the OIDC provider. |
- Configuring OpenID Connect in Amazon Web Services
- Creating OpenID Connect (OIDC) identity providers
- Obtaining the thumbprint for an OpenID Connect Identity Provider
- GitHub Actions – Update on OIDC integration with AWS
© 2021 Daniel Morris
Made available under the terms of the MIT License.