Skip to content

ci: migrate GCP auth to keyless Workload Identity Federation#456

Open
tsavo-at-pieces wants to merge 2 commits into
mainfrom
harden/ci-wif
Open

ci: migrate GCP auth to keyless Workload Identity Federation#456
tsavo-at-pieces wants to merge 2 commits into
mainfrom
harden/ci-wif

Conversation

@tsavo-at-pieces

Copy link
Copy Markdown
Contributor

Summary

Migrates this repo's CI from a static GCP service-account key to keyless Workload Identity Federation (WIF), as part of the org-wide incident remediation.

The static key behind the GCP_CREDENTIALS secret (SA github-actions@integration-server-326115.iam.gserviceaccount.com) was leaked and deleted, so the push-build job's GCS uploads are currently broken. This restores them keylessly.

What changed

  • build.yaml auth stepgoogle-github-actions/auth@v3 using workload_identity_provider + service_account (no credentials_json), matching the builds_server reference (PRs 🧩 Refactor 🧩 #19/Fix: Resolve more errors so the cli runs #20).
  • Added permissions: { id-token: write, contents: read } to the push-build job (required for OIDC token minting).
  • Fixed undeclared project_id input bug: the auth step referenced ${{ inputs.project_id }}, but project_id was never declared as a workflow input (only deploy was), so it silently resolved to empty. Now pinned to integration-server-326115 — the home project of the CI SA and the app-releases-production / app-releases-staging GCS buckets.
  • Removed the now-unused credentials_json secret from build.yaml and the GCP_CREDENTIALS pass-through from staging.yaml and release.yaml.

GCP backing changes (already applied)

  • Repo-scoped roles/iam.workloadIdentityUser binding added on the CI SA for principalSet://.../attribute.repository/pieces-app/cli-agent (provider projects/497784144587/.../github-pool/providers/github-provider).
  • No runtime SA needed — CI only does GCS uploads via gsutil (no Cloud Run / Artifact Registry / image deploy).

The GCP_CREDENTIALS repo secret is intentionally left in place (not deleted) and can be removed once this is verified.

Test plan

  • Trigger Staging (push to main/feat-headless) and confirm the push-build job authenticates via WIF and gcloud info shows the impersonated SA.
  • Confirm gsutil cp uploads to gs://app-releases-staging/... succeed.
  • Cut a tag to exercise Release → production bucket uploads.

Made with Cursor

Replace the static GCP service-account key (GCP_CREDENTIALS) with keyless
Workload Identity Federation, per the org-wide incident remediation. The
static key behind GCP_CREDENTIALS was leaked and deleted, breaking CI.

- build.yaml: auth step now uses google-github-actions/auth@v3 with
  workload_identity_provider + service_account (no credentials_json), and
  adds id-token: write / contents: read permissions to the push-build job.
- Fix undeclared `project_id` input: the auth step referenced
  ${{ inputs.project_id }} which was never declared (resolved to empty).
  Pin project_id to integration-server-326115 (home of the CI SA and the
  app-releases-* GCS buckets).
- Drop the now-unused credentials_json secret from build.yaml and remove
  the GCP_CREDENTIALS pass-through from staging.yaml and release.yaml.

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings June 15, 2026 19:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates the repo’s CI GCP authentication from a static service-account key to keyless Workload Identity Federation (OIDC) to restore GCS uploads in the build pipeline.

Changes:

  • Switches the build workflow’s GCP auth step to google-github-actions/auth@v3 using workload_identity_provider + service_account (no JSON key).
  • Removes the credentials_json/GCP_CREDENTIALS pass-through from staging and release workflow callers.
  • Adds explicit job permissions intended to enable OIDC token minting for the upload job.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
.github/workflows/staging.yaml Stops passing GCP_CREDENTIALS into the reusable build workflow.
.github/workflows/release.yaml Stops passing GCP_CREDENTIALS into the reusable build workflow.
.github/workflows/build.yaml Updates Google auth to WIF (OIDC) and adds job permissions for the GCP upload job.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 14 to 18
secrets:
access_token: ${{ secrets.GITHUB_TOKEN }}
pypi_token: ${{ secrets.PYPI_TOKEN }}
pypi_test_token: ${{ secrets.PYPI_TEST_TOKEN }}
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
Comment on lines 13 to 17
secrets:
access_token: ${{ secrets.GITHUB_TOKEN }}
pypi_token: ${{ secrets.PYPI_TOKEN }}
pypi_test_token: ${{ secrets.PYPI_TEST_TOKEN }}
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
Comment on lines +348 to +350
permissions:
id-token: write
contents: read
The reusable build.yaml requests id-token: write for WIF auth, but a
called workflow's token is capped by the caller. staging.yaml and
release.yaml had no permissions block on the build job, so id-token
defaulted to none and push-build OIDC auth would fail with
"requesting 'id-token: write', but is only allowed 'id-token: none'".

Add permissions: { id-token: write, contents: read } to the calling job
in both, matching the builds_client/builds_server pattern.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants