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
- Creates a Workload Identity Pool and Provider for GitHub OIDC
- Sets up a dedicated Service Account for SDK publishing
- Grants Artifact Registry writer permissions on Python and NPM repositories
- Implements branch/tag restrictions for enhanced security
- Outputs ready-to-use values for GitHub secrets
Prerequisites
- Google Cloud Project with billing enabled
- Terraform installed (>= 1.0)
gcloudCLI configured with appropriate permissions- GitHub repository for CI/CD workflows
- Existing Artifact Registry repositories (or set
create_repos = true)
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:
- Go to Settings → Secrets and variables → Actions
- 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 fromterraform output wif_provider-GCP_WIF_SA_EMAIL: Output fromterraform 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
- Branch Protection: By default, only
mainbranch and specific tag patterns can authenticate - Repository Scoping: Authentication is restricted to the specified GitHub repository
- Least Privilege: Service Account only has write access to specified Artifact Registry repositories
- No Keys: Uses OIDC tokens instead of service account keys
Troubleshooting
Authentication Failures
- Verify the GitHub Actions workflow has
id-token: writepermission - Check that the repository and branch/tag match the configured restrictions
- Ensure all required APIs are enabled in your GCP project
Permission Errors
- Verify the Service Account has the correct IAM roles
- Check that Artifact Registry repositories exist (or set
create_repos = true) - 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.