.github/workflows | ||
dist | ||
src | ||
tests | ||
.eslintrc.js | ||
.gitignore | ||
.prettierrc.js | ||
action.yml | ||
LICENSE | ||
package-lock.json | ||
package.json | ||
README.md | ||
tsconfig.json |
oidc-auth-google-cloud
This GitHub Action exchanges a GitHub Actions OIDC token into a Google Cloud access token using Workload Identity Federation. This obviates the need to export a long-lived Google Cloud service account key and establishes a trust delegation relationship between a particular GitHub Actions workflow invocation and permissions on Google Cloud.
Previously
- Create a Google Cloud service account and grant IAM permissions
- Export the long-lived JSON service account key
- Upload the JSON service account key to a GitHub secret
With Workload Identity Federation
- Create a Google Cloud service account and grant IAM permissions
- Create and configure a Workload Identity Provider for GitHub
- Exchange the GitHub Actions OIDC token for a short-lived Google Cloud access token
Prerequisites
- This action requires you to create and configure a Google Cloud Workload Identity Provider. See [#setup] for instructions.
Usage
jobs:
run:
# ...
# Add "id-token" with the intended permissions.
permissions:
id-token: write
contents: read
steps:
- id: 'google-cloud-auth'
name: 'Authenticate to Google Cloud'
uses: 'github.com/sethvargo/oidc-auth-google-cloud'
with:
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
service_account: 'my-service-account@my-project.iam.gserviceaccount.com'
# Example of using the output:
- id: 'access-secret'
run: |-
curl https://secretmanager.googleapis.com/v1/projects/my-project/secrets/my-secret/versions/1:access \
--header "Authorization: Bearer ${{ steps.integration.outputs.access_token }}"
Inputs
-
workload_identity_provider
: (Required) The full identifier of the Workload Identity Provider, including the project number, pool name, and provider name. This must be the full identifier which includes all parts, for example:projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider
-
service_account
: (Required) Email address or unique identifier of the Google Cloud service account for which to generate credentials. For example:my-service-account@my-project.iam.gserviceaccount.com
-
audience
: (Optional) The value for the audience (aud
) parameter in the generated GitHub Actions OIDC token. At present, the only valid value is"sigstore"
, but this variable exists in case custom values are permitted in the future. The default value is"sigstore"
. -
delegates
: (Optional) List of additional service account emails or unique identities to use for impersonation in the chain. By default there are no delegates. -
lifetime
: (Optional) Desired lifetime duration of the access token, in seconds. This must be specified as the number of seconds with a trailing "s" (e.g. 30s). The default value is 1 hour (3600s).
Outputs
-
access_token
: The authenticated Google Cloud access token for calling other Google Cloud APIs. -
expiration
: The RFC3339 UTC "Zulu" format timestamp when the token expires.
Setup
To exchange a GitHub Actions OIDC token for a Google Cloud access token, you must create and configure a Workload Identity Provider. These instructions use the gcloud command-line tool.
-
Create or use an existing Google Cloud project. You must have privileges to create Workload Identity Pools, Workload Identity Providers, and to manage Service Accounts and IAM permissions. Save your project ID as an environment variable. The rest of these steps assume this environment variable is set:
export PROJECT_ID="my-project" # update with your value
-
(Optional) Create a Google Cloud Service Account. If you already have a Service Account, take note of the email address and skip this step.
gcloud iam service-accounts create "my-service-account" \ --project "${PROJECT_ID}"
-
(Optional) Grant the Google Cloud Service Account permissions to access Google Cloud resources. This step varies by use case. For demonstration purposes, you could grant access to a Google Secret Manager secret or Google Cloud Storage object.
-
Create a Workload Identity Pool:
gcloud iam workload-identity-pools create "my-pool" \ --project="${PROJECT_ID}" \ --location="global" \ --display-name="Demo pool"
-
Create a Workload Identity Provider in that pool:
gcloud iam workload-identity-pools providers create-oidc "my-provider" \ --project="${PROJECT_ID}" \ --location="global" \ --workload-identity-pool="my-pool" \ --display-name="Demo provider" \ --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.aud=assertion.aud" \ --issuer-uri="https://vstoken.actions.githubusercontent.com" \ --allowed-audiences="sigstore"
- The audience of "sigstore" is currently the only value GitHub allows.
- The attribute mappings map claims in the GitHub Actions JWT to
assertions you can make about the request (like the repository or GitHub
username of the principal invoking the GitHub Action). These can be used
to further restrict the authentication using
--attribute-condition
flags.
-
Get the full ID for the Workload Identity Provider:
gcloud iam workload-identity-pools providers describe "my-provider" \ --project="${PROJECT_ID}" \ --location="global" \ --workload-identity-pool="my-pool"
Take note of the
name
attribute. It will be of the format:projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider
Save this value as an environment variable:
export WORKLOAD_IDENTITY_PROVIDER_ID="..." # value from above
-
Allow authentications from the Workload Identity Provider to impersonate the Service Account created above:
Warning: This grants access to any resource in the pool (all GitHub repos). It's strongly recommended that you map to a specific attribute such as the actor or repository name instead. See mapping external identities for more information.
gcloud iam service-accounts add-iam-policy-binding "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_PROVIDER_ID}/*"
To map to a specific repository:
gcloud iam service-accounts add-iam-policy-binding "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_PROVIDER_ID}/attribute.repo/my-repo"
-
Use this GitHub Action with the Workload Identity Provider ID and Service Account email. The GitHub Action will mint a GitHub OIDC token and exchange the GitHub token for a Google Cloud access token (assuming the authorization is correct). This all happens without exporting a Google Cloud service account key JSON!