What is OIDC?
OpenID Connect (OIDC) allows your GitHub Actions workflows to access GCP resources without storing any credentials as long-lived GitHub secrets. GCP implements this through Workload Identity. This is the most secure authentication method for production environments.
Choose your preferred method for setting up OIDC authentication:
Use our Terraform module to automatically create all required GCP resources:
Use our Terraform module to create all GCP resources that Terrateam requires.
module "terraform_gcp_terrateam_setup" {
source = " github.com/terrateamio/terraform-gcp-terrateam-setup "
github_org = " GITHUB_ORG " # GitHub organization or username
project_id = " PROJECT_ID "
service_account_description = " Terrateam service account "
workload_identity_pool_id = " terrateam-pool "
workload_identity_provider = " terrateam-provider "
service_account_name = " terrateam "
service_account_role = " roles/editor "
output "google_iam_workload_identity_pool_provider_github_provider_name" {
value = module . terraform_gcp_terrateam_setup
Save the output value google_iam_workload_identity_pool_provider_github_provider_name - you’ll need it for Terrateam configuration.
After setting up GCP resources, configure Terrateam to use OIDC authentication:
Create the .terrateam/config.yml configuration file at the root of your Terraform repository.
service_account : " terrateam@PROJECT_ID.iam.gserviceaccount.com "
workload_identity_provider : " WORKLOAD_IDENTITY_PROVIDER "
Test that OIDC authentication is working:
Create a simple Terraform configuration in your repository
Open a pull request with the changes
Comment terrateam plan on the pull request
Terrateam should successfully authenticate using OIDC and show the plan output
For custom configurations or when you need to understand exactly what resources are being created:
Need to set up OIDC manually? Expand for step-by-step instructions
Create a Terrateam service account:
gcloud iam service-accounts create terrateam \
--description= " Terrateam service account " \
--display-name= " Terrateam " \
Create the workload identity pool:
gcloud iam workload-identity-pools create " terrateam-pool " \
--display-name= " Terrateam pool "
Create the OIDC provider in the workload identity pool:
gcloud iam workload-identity-pools providers create-oidc " terrateam-provider " \
--workload-identity-pool= " terrateam-pool " \
--display-name= " Terrateam provider " \
--issuer-uri= " https://token.actions.githubusercontent.com " \
--attribute-mapping= " google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner " \
--attribute-condition= " assertion.repository_owner == 'GITHUB_ORG' "
Allow the workload identity pool to impersonate the service account:
gcloud iam service-accounts add-iam-policy-binding " terrateam@PROJECT_ID.iam.gserviceaccount.com " \
--role= " roles/iam.workloadIdentityUser " \
--member= " principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/terrateam-pool/attribute.repository_owner/GITHUB_ORG "
Attach an IAM role to give the service account necessary permissions. We suggest roles/editor as a starting point:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member= " serviceAccount:terrateam@PROJECT_ID.iam.gserviceaccount.com " \
Get the full workload identity provider name for Terrateam configuration:
gcloud iam workload-identity-pools providers describe " terrateam-provider " \
--workload-identity-pool= " terrateam-pool " \
Follow the Configure Terrateam for OIDC section above to complete your setup.
Multiple Environments
You can use different service accounts for different environments and operations. For example:
- tag_query : " dir:terraform/production/** "
service_account : " terrateam-prod@prod-project.iam.gserviceaccount.com "
workload_identity_provider : " projects/123456789/locations/global/workloadIdentityPools/terrateam-pool/providers/terrateam-provider "
service_account : " terrateam-prod@prod-project.iam.gserviceaccount.com "
workload_identity_provider : " projects/123456789/locations/global/workloadIdentityPools/terrateam-pool/providers/terrateam-provider "
- tag_query : " dir:terraform/staging/** "
service_account : " terrateam-staging@staging-project.iam.gserviceaccount.com "
workload_identity_provider : " projects/123456789/locations/global/workloadIdentityPools/terrateam-pool/providers/terrateam-provider "
service_account : " terrateam-staging@staging-project.iam.gserviceaccount.com "
workload_identity_provider : " projects/123456789/locations/global/workloadIdentityPools/terrateam-pool/providers/terrateam-provider "
For more details, read the Cloud Credentials documentation .
The example above names a service account per workflow. The service account and workload identity provider come from your Terrateam configuration, so Google cannot tell which environment a run belongs to. Any run matching the workflow can request any credentials the configuration names.
Associating a workflow with a GitHub Environment closes that gap. GitHub signs the environment into the token it issues, so Google validates the environment instead of trusting your configuration.
This follows Google’s guidance to use attribute conditions when federating with GitHub and to grant roles to identities matching specific criteria rather than to every member of a pool. Google recommends a single pool and provider for GitHub, with attributes separating access. See Configure Workload Identity Federation with deployment pipelines .
- tag_query : " dir:terraform/production/** "
service_account : " terrateam-prod@PROJECT_ID.iam.gserviceaccount.com "
workload_identity_provider : " projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/terrateam-pool/providers/terrateam-provider "
Terrateam runs each environment as its own job, and that job runs in the GitHub Environment you name. Create the environment in your repository settings before the first run.
Add attribute.environment to the provider you created during setup:
gcloud iam workload-identity-pools providers update-oidc " terrateam-provider " \
--workload-identity-pool= " terrateam-pool " \
--attribute-mapping= " google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner,attribute.environment=assertion.environment " \
--attribute-condition= " assertion.repository_owner == 'GITHUB_ORG' "
A job running in an environment also changes the subject claim to repo:GITHUB_ORG/REPO:environment:production. Review any binding that matches on google.subject before you roll this out.
Replace the attribute.repository_owner binding from the setup steps with one binding per environment:
gcloud iam service-accounts add-iam-policy-binding " terrateam-prod@PROJECT_ID.iam.gserviceaccount.com " \
--role= " roles/iam.workloadIdentityUser " \
--member= " principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/terrateam-pool/attribute.environment/production "
A run in the staging environment receives a token carrying "environment": "staging", which does not satisfy this binding. Google refuses the impersonation.
Scoping by workspace
Terrateam sets TERRATEAM_DIR, TERRATEAM_WORKSPACE, and TERRATEAM_STACK before running each directory and workspace. The oidc step expands these in service_account, workload_identity_provider, and audience:
service_account : " terrateam-${TERRATEAM_WORKSPACE}@PROJECT_ID.iam.gserviceaccount.com "
workload_identity_provider : " projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/terrateam-pool/providers/terrateam-provider "
These variables are set per directory and workspace, so they resolve in plan and apply steps only. An oidc step under hooks runs before a workspace is selected and fails if it references them.
The GitHub token carries no workspace claim, so Google cannot verify the workspace. This selects which service account a run requests. Use a GitHub Environment when you need Google to enforce the boundary.
Now that you have GCP authentication configured, you are now able to use Terrateam for plan and apply operations against GCP resources.