Skip to content

Google Cloud Platform

All repos authenticate to GCP using Workload Identity Federation -- keyless, short-lived tokens with no service account JSON keys.

Architecture

flowchart TB
    subgraph github["GitHub Actions (Stig-Johnny/*)"]
        workflow["Workflow Job"]
    end

    subgraph gcp["Google Cloud Platform"]
        subgraph wif["Workload Identity Pool: github-actions"]
            provider["Provider: github<br/>Condition: repository_owner == 'Stig-Johnny'"]
        end

        sa["Service Account<br/>github-actions@invotek-github-infra"]

        subgraph perms["Permissions"]
            billing["Billing User"]
            firebase["Firebase Admin"]
            serviceusage["Service Usage Admin"]
        end
    end

    workflow -->|"OIDC Token"| provider
    provider -->|"Impersonate"| sa
    sa --> perms

Resources

Resource Value
GCP Project invotek-github-infra
Project Number 1090472687120
Billing Account 015BBC-422A59-EB7AF4
Service Account github-actions@invotek-github-infra.iam.gserviceaccount.com
WIF Provider projects/1090472687120/locations/global/workloadIdentityPools/github-actions/providers/github

GitHub Secrets

Set on each repo that needs GCP access:

Secret Value
GCP_WORKLOAD_IDENTITY_PROVIDER WIF Provider path (see above)
GCP_SERVICE_ACCOUNT Service account email
GCP_BILLING_ACCOUNT Billing account ID

Configured on: nutri-e, cutie, star-rewards

Service Account Roles

Role Scope Purpose
roles/billing.user Billing Account Link new projects to billing
roles/firebase.admin invotek-github-infra Manage Firebase resources
roles/firebase.admin cuti-e Cuti-E Firebase
roles/firebase.admin claude-memory-mcp Memory MCP Firebase
roles/firebase.admin reward-e-app Reward-E Firebase
roles/serviceusage.serviceUsageAdmin invotek-github-infra Enable APIs

Firebase Projects

Project ID App Region Bundle ID
reward-e-app Reward-E europe-west1 no.invotek.RewardE
cuti-e Cuti-E us-central1 com.invotek.Cuti-E

Usage in Workflows

jobs:
  deploy:
    runs-on: [self-hosted, Linux]
    permissions:
      id-token: write   # Required for OIDC
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: google-github-actions/auth@v2
        with:
          workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
          service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
      - uses: google-github-actions/setup-gcloud@v2
      - run: gcloud projects list

Adding GCP to a New Repo

gh secret set GCP_WORKLOAD_IDENTITY_PROVIDER \
  --repo Stig-Johnny/NEW_REPO \
  --body "projects/1090472687120/locations/global/workloadIdentityPools/github-actions/providers/github"

gh secret set GCP_SERVICE_ACCOUNT \
  --repo Stig-Johnny/NEW_REPO \
  --body "github-actions@invotek-github-infra.iam.gserviceaccount.com"

gh secret set GCP_BILLING_ACCOUNT \
  --repo Stig-Johnny/NEW_REPO \
  --body "015BBC-422A59-EB7AF4"

Security

  • No long-lived secrets -- WIF uses short-lived tokens (1 hour)
  • Scoped to owner -- Only repos under Stig-Johnny can authenticate
  • Immutable identifiers -- Uses repository_id (survives renames)
  • Audit logging -- All authentications logged in Cloud Audit Logs

Troubleshooting

Error Solution
"Unable to generate access token" Verify repo is under Stig-Johnny; check secrets; ensure permissions: id-token: write
"Permission denied on billing" SA can only link projects, not manage billing settings
"Firebase project not found" Grant roles/firebase.admin on the target project
"Cannot create projects without parent" Create projects manually with user credentials, then grant SA Firebase admin