Harden WIF credential staging and release checks - #13
Conversation
google-github-actions/auth writes the credential file 0600. The R2A container runs as the non-root udx user, so the read-only bind mount fails with 'Configured GCP credential file could not be read'. Temporarily chmod 0644 for the duration of the container run and restore the original mode on exit.
There was a problem hiding this comment.
Pull request overview
This PR hardens the action’s handling of Google Workload Identity (WIF) credentials by staging a readable copy in a runner-private temp directory (instead of chmod-ing the caller’s credentials file), and tightens release/CI guardrails to ensure runtime changes are always paired with a semantic version bump and matching release notes.
Changes:
- Stage a temporary, readable copy of the GCP credentials under a private
mktemp -ddirectory and mount that copy into the R2A container; clean up on exit. - Enforce (in PR CI) that any changes to
action.ymlorbin/must increasepackage.json’s semantic version, supported by full git history checkout. - Update release/validation docs, changelog, tests, and release notifications to reflect immutable patch-tag canaries and the new credential-staging behavior.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
action.yml |
Copies GCP credentials into a runner-private temp dir with readable mode and mounts the copy into the container; cleans up via EXIT trap. |
tests/run-merge-tests.sh |
Adds assertions ensuring credential staging is present and caller credential chmod is not used. |
README.md |
Updates authentication/state ownership docs to describe staging a private credential copy. |
package.json |
Bumps version to 1.0.5 for the runtime change. |
CHANGELOG.md |
Adds v1.0.5 entry describing the WIF credential staging fix. |
docs/validation.md |
Documents CI behavior including actionlint and version-bump requirement for runtime changes. |
docs/releasing.md |
Clarifies CI/version/changelog coupling and promotes immutable patch tags for caller canaries. |
AGENTS.md |
Reinforces release-worthiness of action.yml/bin/ runtime changes and required version/changelog updates. |
.github/workflows/ci.yml |
Adds PR-only runtime-change version-bump enforcement and sets fetch-depth: 0; runs actionlint job. |
.github/workflows/publish-release.yml |
Updates Slack handoff text to instruct canary testing with the immutable released tag. |
.rabbit/repo.yaml |
Refreshes rabbit.ci-generated repo config to include the new fix branches. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
tests/run-merge-tests.sh:118
- These assertions use
grep -cwith basic-regex patterns that include regex metacharacters (notably.inrabbit-gcp-credentials.XXXXXX) and extra escaping, which can make the checks less strict and more brittle than intended. Using fixed-string matching (grep -F) makes the contract tests exact and avoids accidental matches.
assert_eq "$(grep -c 'mktemp -d "\${RUNNER_TEMP:-/tmp}/rabbit-gcp-credentials.XXXXXX"' "$PROJECT_ROOT/action.yml")" "1" "Action stages GCP credentials in a private temporary directory"
assert_eq "$(grep -c 'install -m 0644 -- "\$GCP_CREDENTIALS_PATH" "\$gcp_credentials_copy"' "$PROJECT_ROOT/action.yml")" "1" "Action mounts a readable credential copy"
assert_eq "$(grep -c 'rm -rf "\$gcp_credentials_dir"' "$PROJECT_ROOT/action.yml")" "1" "Action removes the staged GCP credential copy"
assert_eq "$(grep -c 'chmod 0644 "\$GCP_CREDENTIALS_PATH"' "$PROJECT_ROOT/action.yml" || true)" "0" "Action leaves the caller GCP credential mode unchanged"
andypotanin
left a comment
There was a problem hiding this comment.
Verified end to end on udx/www.wpcloud.io: the caller-side chmod equivalent produced a full green production apply (run 33249972630). The staged-copy approach here is the right fix for the shared-runner exposure and ownership concerns raised on #12.
Summary
Validation
This PR targets fix/wif-credential-readable. Merge it into PR #12 before PR #12 is merged to production.