Introduction
Workload Identity Federation (WIF) is a pivotal method for utilizing an external authentication system to authorize access to Google Cloud Platform (GCP) resources such as AWS, Azure, GitHub or with any identity provider (IdP) that supports OpenID Connect (OIDC).
In the context of GitHub Actions, it involves leveraging GitHub’s OpenID Connect (OIDC) system to issue a JWT token with predefined claims. This token serves as a temporary credential for accessing GCP resources throughout a job.
Keyless Authentication for Service Accounts
One of the core aspects of WIF is its capability to provide keyless authentication for Service Accounts (SAs). Instead of relying on keys with expiration, SAs are assigned identifiers associated with specific applications, and then permissions are granted accordingly. This enhances security and simplifies the management of authentication mechanisms.
Prerequisite
Enable the IAM, Resource Manager, Service Account Credentials, and Security Token Service APIs.
- Identity and Access Management (IAM) API
- Cloud Resource Manager API
- IAM Service Account Credentials API
- Security Token Service API
Setup Project
gcloud config set account <Service-Account>@<project-id>.iam.gserviceaccount.com
gcloud config set project <project-id>
gcloud auth login
Workload Identity Pool
A workload identity pool is an entity that lets you manage external identities.
1. Create a Workload Identity Pool
For instance, Pool id is
dataproc-github-identity-pool
gcloud iam workload-identity-pools create dataproc-github-identity-pool \
--location="global" \
--display-name="Mahendran Workload Identity Pool" \
--description="Mahendran Workload Identity Pool" --disabled
You can set up mappings between JWT token claims and WIF custom attributes.
2. Create a Workload Identity Provider dataproc-github-idp
and to the Pool dataproc-github-identity-pool
See Attribute Mapping and Conditions for
attribute-mapping="MAPPINGS"
gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
--location="global" \
--workload-identity-pool="POOL_ID" \
--issuer-uri="https://token.actions.githubusercontent.com/" \
--attribute-mapping="MAPPINGS" \
--attribute-condition="CONDITIONS"
2.1 For example, Create a pool `dataproc-github-idp`
gcloud iam workload-identity-pools providers create-oidc dataproc-github-idp \
--location="global" \
--workload-identity-pool="dataproc-github-identity-pool" \
--display-name="GitHub workload pool provider" \
--description="Mahendran's github workload pool provider" \
--issuer-uri="https://token.actions.githubusercontent.com/" \
--attribute-mapping="google.subject=assertion.sub" \
--attribute-condition="attribute.owner==assertion.repository_owner" \
--project data-proc-poc
2.2 List the Pool created
gcloud iam workload-identity-pools providers list --workload-identity-pool="dataproc-github-identity-pool" --location="global" --show-deleted
2.3 Get the name
gcloud iam workload-identity-pools list --location global --format "get(name)"
3. Attribute Mapping and Conditions
Attribute mapping allows you to establish connections between JWT token claims and WIF custom attributes. By defining attribute conditions, you can refine access controls based on specific criteria. This ensures granular control over resource access within the GCP environment.
The tokens issued by your external identity provider contain one or more attributes. Some identity providers refer to these attributes as claims.
Google STS tokens also contain one or more attributes, as listed in the following table:
References:
You may set up mappings between JWT token claims and WIF custom attributes
Example OIDC Claims:
Refer Attribute Mapping and Conditions
google.subject=assertion.sub
attribute.repository==assertion.repository
3.2 Verification
Go To the GCloud console, and verify the Provider and the attributes
Audience
, And AttributesAuthenticate a workload
1. Create a service account for the external workload
Use an existing service account
or create a new Service Account
1.1 Add roles to the Service Account
1.2 Principals vs PrincipalSet
Principals
, which represent incoming requests to WIF, can be assigned roles based on various attributes and conditions. This enables fine-grained access control, enhancing security and compliance measures.
To grant the Workload Identity User role (roles/iam.workloadIdentityUser
) to external identities that meet a certain criteria:
First lets look at a regular principal. A regular principle is the basic way of identifying an incoming request to WIF and essentially just uses the subject.
Choose one of the following or both
Add a Principal
gcloud iam service-accounts add-iam-policy-binding <service-account>@<project-id>.iam.gserviceaccount.com \
--role=roles/iam.workloadIdentityUser \
--member="principal://iam.googleapis.com/projects/1334884267/locations/global/workloadIdentityPools/dataproc-github-identity-pool/subject/repo:mahen-github/iac-gcp:pull_request"
Add a Principal-set to the Service Account
Here, I’m adding attribute.repository/mahen-github/iac-gcp
gcloud iam service-accounts add-iam-policy-binding <service-account>@<project-id>.iam.gserviceaccount.com \
--role=roles/iam.workloadIdentityUser \
--member="principalSet://iam.googleapis.com/projects/1334884267/locations/global/workloadIdentityPools/dataproc-github-identity-pool/attribute.repository/mahen-github/iac-gcp"
Add a Workflow to the github project
Refer the Project for example Workflow
The below workflow uses google-github-actions
to authenticate and google-github-actions/upload-cloud-storage@v2
to upload a file from github
build:
runs-on: ubuntu-latest
environment: dev # Fetches the env variables for dev
permissions:
contents: read
id-token: write
steps:
- name: Checkout actions-oidc-debugger
uses: actions/checkout@v3
- id: auth
name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
create_credentials_file: true
workload_identity_provider: '${{ vars.WORKLOAD_IDENTITY_PROVIDER }}'
service_account: '${{ secrets.SERVICE_ACCOUNT }}'
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: set credentials file
run: >-
gcloud auth login
--cred-file=${{steps.auth.outputs.credentials_file_path}}
- name: Use gcloud CLI
run: gcloud info
- id: upload-file
uses: google-github-actions/upload-cloud-storage@v2
with:
path: CHANGELOG.md
destination: '${{ vars.GCP_BUCKET }}'
process_gcloudignore: false
Conclusion
Workload Identity Federation, coupled with GitHub Actions integration, offers a robust solution for managing access to GCP resources securely. By leveraging OIDC providers, attribute mappings, and role assignments, organizations can establish streamlined authentication mechanisms while adhering to stringent security standards.
References
- Google Cloud Documentation: Workload Identity Federation with Deployment Pipelines
- Example Subject Claims
- GitHub Actions Security Guides: Automatic Token Authentication
- gcloud Reference: Workload Identity Pools
- Medium Article: GitHub OIDC Integration with GCP Workload Identity Federation
- Understanding OIDC and Identity Federation