Skip to content

fix(gcp/gke): grant workload SA access to the admin password secret - #504

Merged
cristim merged 1 commit into
mainfrom
fix/480-gke-admin-secret-reader
Oct 5, 2026
Merged

cristim merged 1 commit into
mainfrom
fix/480-gke-admin-secret-reader

Conversation

@cristim

@cristim cristim commented Oct 5, 2026

Copy link
Copy Markdown
Member

Summary

Grant the GKE workload service account access to the admin password secret it is already given as ADMIN_PASSWORD_SECRET.

Why

The module passed the secret name to the pod but had no IAM binding on it, so a GKE deployment would hit PermissionDenied resolving the admin password at startup (same failure as the Cloud Run dev outage, #476/#479). The app also writes to it: buildAdminPasswordSyncCallback calls PutSecret, which is AddSecretVersion on GCP (internal/secrets/gcp_resolver.go), so both roles are needed.

Change

  • gke module: admin_password_reader (roles/secretmanager.secretAccessor) and admin_password_writer (roles/secretmanager.secretVersionAdder) for google_service_account.workload, no project argument (full projects/<number>/secrets/<id> name; setting it force-replaces the binding each apply).
  • New enable_admin_password_writer variable (default false), same gate and semantics as Cloud Run (name is known after apply).
  • environments/gcp/compute.tf sets it to true for the gke module call.

Verification

  • terraform fmt -check, terraform init -backend=false && terraform validate pass for the gke module and terraform/environments/gcp.
  • scripts/check-gcp-secret-scope.sh (CI "GCP Secret Manager grant scope") and scripts/test-gcp-secret-scope.sh pass locally.
  • No plan or apply was run. GKE is not deployed anywhere today.

Closes #480

The pod gets ADMIN_PASSWORD_SECRET but the module had no binding on it, so startup would hit PermissionDenied. Add secretAccessor and secretVersionAdder (the app reads the secret and adds a version on admin password change), mirroring the Cloud Run module and omitting project. Closes #480.
@cristim cristim added priority/p2 Backlog-worthy severity/medium Moderate harm urgency/this-sprint Within the current sprint triaged Item has been triaged impact/few Limited audience effort/xs Trivial / one-liner type/bug Defect labels Oct 5, 2026
@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

This review includes 3 billable files and costs up to $0.75.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Or wait 59 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available. Your 50 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: LeanerCloud/cloud-commitments-platform/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: f997334e-cfdf-4c2b-ab13-e200da49aff7
📥 Commits

Reviewing files that changed from the base of the PR and between ce7aa68 and 9f20c2d.

📒 Files selected for processing (3)
  • terraform/environments/gcp/compute.tf
  • terraform/modules/compute/gcp/gke/main.tf
  • terraform/modules/compute/gcp/gke/variables.tf
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@cristim
cristim merged commit 60a9445 into main Oct 5, 2026
25 checks passed
IAmJSD added a commit that referenced this pull request Oct 26, 2026
…rry (#1213)

* sec(ci): refuse authoritative GCP IAM policies in the secret scope guard

check-gcp-secret-scope.sh finds Secret Manager roles by their text, but an
authoritative google_{project,folder,organization}_iam_policy can take its
policy_data from file(), a variable with no in-tree default or a module
output, so the role it grants never appears in a scanned file and the guard
reported such configurations clean. Fail closed instead: any non-comment
mention of those types, or of data "google_iam_policy", now exits 2, as the
guard already does for the JSON encoding.

CI's terraform fmt check now covers iac/ as well as terraform/, so every
root the guard scans is held to the layout its block tracking was written
for. The self-test reads SCAN_ROOTS and fails if a root has no fmt step.

Closes #150

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* sec(ci): allowlist the roles a per-secret Secret Manager grant may carry

check-gcp-secret-scope.sh exempted a per-secret binding's `role =` line for
any roles/secretmanager.* name, so widening a per-secret grant to
roles/secretmanager.admin (the #504 review's mutation) still exited 0. Inside
a per-secret IAM resource every `role =` line must now name
roles/secretmanager.secretAccessor or roles/secretmanager.secretVersionAdder
as a literal, matched case-sensitively. Any other role there, including one
from another service such as roles/owner or a reference the guard cannot
resolve, is a finding unless waived with a reason. Those two are the only
roles the repo grants per secret and the only ones the issue names.

Inline policy_data role lines on a per-secret _iam_policy get the same check.
One built from data "google_iam_policy" already exits 2 after #150; one fed
from file() or a variable remains out of reach and is listed under
LIMITATIONS.

Closes #505

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/xs Trivial / one-liner impact/few Limited audience priority/p2 Backlog-worthy severity/medium Moderate harm triaged Item has been triaged type/bug Defect urgency/this-sprint Within the current sprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(gcp/gke): workload SA has no read access to the admin password secret it is given

1 participant