WIF Publisher Module (GitHub → Google Cloud)

This Terraform module sets up Workload Identity Federation (WIF) between GitHub Actions and Google Cloud Platform, enabling secure, keyless authentication for publishing SDKs to Artifact Registry.

Features

Prerequisites

Usage

1. Create Module Configuration

Create a terraform.tfvars file or pass variables directly:

module "wif_publisher" {
  source = "./deployment/terraform/wif_publisher"

  # Required variables
  project_id    = "my-prod-project"
  gar_location  = "us-central1"
  gar_py_repo   = "mizoki-python"
  gar_npm_repo  = "mizoki-npm"

  # GitHub repository configuration
  repo_owner = "mediaintelligence"
  repo_name  = "MIZOKICloudRun"

  # Branch/tag restrictions (optional)
  allowed_ref_prefixes = [
    "refs/heads/main",
    "refs/tags/python-sdk-v",
    "refs/tags/ts-sdk-v"
  ]

  # Optional: Create repositories if they don't exist
  create_repos = false
}

2. Initialize and Apply Terraform

# Initialize Terraform
terraform init

# Review the plan
terraform plan

# Apply the configuration
terraform apply

3. Configure GitHub Secrets

After applying, set up GitHub secrets using the module outputs:

Using GitHub CLI

# Set repository context
export GH_REPO="mediaintelligence/MIZOKICloudRun"

# Get Terraform outputs
export GCP_WIF_PROVIDER="$(terraform output -raw wif_provider)"
export GCP_WIF_SA_EMAIL="$(terraform output -raw publisher_sa_email)"

# Set GitHub secrets
gh secret set GCP_PROJECT_ID   -R "$GH_REPO" -b"my-prod-project"
gh secret set GAR_LOCATION     -R "$GH_REPO" -b"us-central1"
gh secret set GAR_PY_REPO      -R "$GH_REPO" -b"mizoki-python"
gh secret set GAR_NPM_REPO     -R "$GH_REPO" -b"mizoki-npm"
gh secret set GCP_WIF_PROVIDER -R "$GH_REPO" -b"$GCP_WIF_PROVIDER"
gh secret set GCP_WIF_SA_EMAIL -R "$GH_REPO" -b"$GCP_WIF_SA_EMAIL"

Manual Configuration

Get the values from Terraform outputs:

terraform output wif_provider
terraform output publisher_sa_email

Then add these as repository secrets in GitHub:

  1. Go to Settings → Secrets and variables → Actions
  2. Add the following secrets: - GCP_PROJECT_ID: Your GCP project ID - GAR_LOCATION: Artifact Registry location - GAR_PY_REPO: Python repository name - GAR_NPM_REPO: NPM repository name - GCP_WIF_PROVIDER: Output from terraform output wif_provider - GCP_WIF_SA_EMAIL: Output from terraform output publisher_sa_email

4. Use in GitHub Actions

Example workflow using WIF authentication:

name: Publish SDK

on:
  push:
    tags:
      - 'python-sdk-v*'
      - 'ts-sdk-v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write  # Required for OIDC token

    steps:
      - uses: actions/checkout@v4

      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v2
        with:
          workload_identity_provider: ${{ secrets.GCP_WIF_PROVIDER }}
          service_account: ${{ secrets.GCP_WIF_SA_EMAIL }}

      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v2

      - name: Configure Artifact Registry
        run: |
          gcloud config set artifacts/location ${{ secrets.GAR_LOCATION }}
          gcloud config set artifacts/repository ${{ secrets.GAR_PY_REPO }}

      # Continue with SDK publishing steps...

Input Variables

Variable Type Default Description
project_id string - GCP project ID (required)
gar_location string - Artifact Registry location (required)
gar_py_repo string - Python repository name (required)
gar_npm_repo string - NPM repository name (required)
repo_owner string - GitHub repository owner (required)
repo_name string - GitHub repository name (required)
allow_all_branches bool false Allow all branches to authenticate
allowed_ref_prefixes list(string) ["refs/heads/main", "refs/tags/python-sdk-v", "refs/tags/ts-sdk-v"] Allowed branch/tag prefixes
pool_id string "github-pool" Workload Identity Pool ID
provider_id string "github" Provider ID within the pool
publisher_sa_id string "mizoki-publisher" Service Account ID
create_repos bool false Create Artifact Registry repositories

Outputs

Output Description Usage
wif_provider Full WIF provider resource path Use as GCP_WIF_PROVIDER secret
publisher_sa_email Publisher Service Account email Use as GCP_WIF_SA_EMAIL secret
principal_set_example Example principalSet member For reference/debugging
pool_name Workload Identity Pool resource name For reference
provider_resource_name Alternative provider format For reference

Security Considerations

  1. Branch Protection: By default, only main branch and specific tag patterns can authenticate
  2. Repository Scoping: Authentication is restricted to the specified GitHub repository
  3. Least Privilege: Service Account only has write access to specified Artifact Registry repositories
  4. No Keys: Uses OIDC tokens instead of service account keys

Troubleshooting

Authentication Failures

  1. Verify the GitHub Actions workflow has id-token: write permission
  2. Check that the repository and branch/tag match the configured restrictions
  3. Ensure all required APIs are enabled in your GCP project

Permission Errors

  1. Verify the Service Account has the correct IAM roles
  2. Check that Artifact Registry repositories exist (or set create_repos = true)
  3. Ensure the project has billing enabled

Viewing Logs

# Check Workload Identity Pool
gcloud iam workload-identity-pools describe github-pool --location=global

# Check Provider
gcloud iam workload-identity-pools providers describe github \
  --workload-identity-pool=github-pool --location=global

# Check Service Account permissions
gcloud projects get-iam-policy PROJECT_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount:mizoki-publisher@*"

Cleanup

To remove all resources created by this module:

terraform destroy

License

This module is provided as-is for MIZOKI Cloud Run deployment.

← All docsView source on GitHub →