Repository navigation
sec(iac/gcp): fail closed on Cloud Run scheduled-task auth mode - #385
Conversation
terraform/modules/compute/gcp/cloud-run derived SCHEDULED_TASK_AUTH_MODE
from whether a Cloud Scheduler job was enabled:
scheduled_task_auth_mode = (var.enable_scheduled_tasks ||
var.enable_ri_exchange_schedule) ? "oidc" : "disabled"
That conflates "does Terraform create a scheduler" with "does the app
authenticate /api/scheduled/*". The service is reachable from the open
internet independently of the scheduler flags whenever
var.allow_unauthenticated = true (its default) or ingress is
INGRESS_TRAFFIC_ALL, so a tfvars flip that disables both schedulers
silently turns off request auth on money-path handlers (ri_exchange,
ladder_run, fire_scheduled_purchases) on an already-public service. All
three GCP envs currently set enable_scheduled_tasks = true, so this has
not fired in prod, but nothing guarded against it firing.
terraform/modules/compute/gcp/gke already fixed the identical defect for
its own Cloud Run analogue (kubernetes ingress) by falling back to a
fail-closed override variable instead of a bare "disabled" literal. Port
the same fix: when neither scheduler is enabled, fall back to the new
var.scheduled_task_auth_mode_override (default "oidc"). With no scheduler
SA, that means an empty SCHEDULED_TASK_OIDC_SUBJECTS, which
internal/server/scheduledauth's configureOIDC rejects at startup
(ErrConfigInvalid) rather than booting the app with /api/scheduled/*
unauthenticated. "disabled" now requires an explicit, deliberate opt-in.
Regression test: terraform/modules/compute/gcp/cloud_run_scheduled_task_auth_test.go
asserts main.tf no longer derives the bare ... ? "oidc" : "disabled" form,
does fall back to var.scheduled_task_auth_mode_override, and that the new
variable defaults to "oidc" with the same three-value validation the Go
validator accepts. Confirmed it fails against the pre-fix main.tf/variables.tf
(git stash of the fix) and passes after.
Closes #123
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: LeanerCloud/cloud-commitments-platform/.coderabbit.yaml Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (3)
Included review availability: This review used your included allowance. 2 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 4 reviews per hour. 📝 WalkthroughWalkthroughThe Cloud Run module now defaults scheduled-task authentication to ChangesCloud Run scheduled-task authentication
Priority: ⬆️ High Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix · Severity of issue fixed: High Merge Risk: ⚪ Minimal · up to Disabling both schedulers no longer implicitly disables scheduled-task authentication. No actionable merge-blocking risk remains after normal checks. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (2 skipped: 2 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
|
|
Independent adversarial review + local verification: MERGE at ef64fd1. Cloud Run's scheduled-task auth mode now falls back to an explicit, validated override defaulting to oidc (the same set scheduledauth.New accepts) instead of 'disabled'; scheduler oidc_token blocks untouched; all three envs keep enable_scheduled_tasks so no plan diff; with both schedulers off, startup now fails rather than serving /api/scheduled/* unauthenticated. Test fails pre-fix (3 assertions); fmt/validate/tflint clean. |
Summary
terraform/modules/compute/gcp/cloud-runderivedSCHEDULED_TASK_AUTH_MODEfrom whether a Cloud Scheduler job was enabled, falling back to a bare"disabled"whenever bothvar.enable_scheduled_tasksandvar.enable_ri_exchange_schedulewere false.Root cause
That conflates "does Terraform create a Cloud Scheduler job" with "does the application authenticate requests to
/api/scheduled/*". The Cloud Run service is reachable from the open internet independently of the scheduler flags whenevervar.allow_unauthenticated = true(the module default) oringress = INGRESS_TRAFFIC_ALL, so a tfvars flip that disables both schedulers (a rollout, or a cost-saving change) silently turns off request authentication on money-path handlers (ri_exchange,ladder_run,fire_scheduled_purchases) while the service stays publicly reachable.Verified against current
main: all three GCP environments (github-dev.tfvars,github-staging.tfvars,github-prod.tfvars) currently setenable_scheduled_tasks = true, so this has not fired in any live environment, but nothing in the code prevented it.terraform/modules/compute/gcp/gkealready fixed the identical defect for its own ingress path (seegke/main.tf:35-48andgke/variables.tf:270-289,scheduled_task_auth_mode_override), so this PR ports the same, already-reviewed fix to the Cloud Run module instead of inventing a different approach.Fix
cloud-run/main.tf:scheduled_task_auth_modenow falls back tovar.scheduled_task_auth_mode_overrideinstead of the bare"disabled"literal when neither scheduler is enabled.cloud-run/variables.tf: newscheduled_task_auth_mode_overridevariable, default"oidc", validated to"oidc" | "bearer" | "disabled"(the exact setinternal/server/scheduledauthaccepts).This fails closed by construction rather than by an explicit plan-time guard: with the override left at its default
"oidc"and no scheduler SA,SCHEDULED_TASK_OIDC_SUBJECTSis empty, andinternal/server/scheduledauth.configureOIDC(internal/server/scheduledauth/validator.go:157) returnsErrConfigInvalidat startup rather than letting the app boot with/api/scheduled/*unauthenticated. Setting the override to"disabled"is now a deliberate, explicit opt-in (local-dev / dry-run), never a side effect of flipping an unrelated feature flag.No environment tfvars changes are needed: none of the three GCP envs sets this new variable, so all three keep their current behavior (
enable_scheduled_tasks = truestill forces"oidc"unconditionally, as before) and only gain the fail-closed fallback for the untested "both schedulers off" path.Regression test
terraform/modules/compute/gcp/cloud_run_scheduled_task_auth_test.go(new) asserts:main.tfno longer derives... ? "oidc" : "disabled"directly from the scheduler flags.main.tfdoes fall back tovar.scheduled_task_auth_mode_override.variables.tfdeclares that variable, defaulting to"oidc", with the three-value validation.Proved it fails pre-fix:
git stashof themain.tf/variables.tfchanges, rango test ./terraform/modules/compute/gcp/... -run TestCloudRunScheduledTaskAuth -vand the test failed on all three assertions. Restored the fix and both tests in the package pass.Verification
terraform fmt -check -diff terraform/modules/compute/gcp/cloud-run/: clean.terraform init -backend=false && terraform validateinterraform/modules/compute/gcp/cloud-run/:Success! The configuration is valid.terraform init -backend=false && terraform validateinterraform/environments/gcp/(the module's real consumer):Success! The configuration is valid.tflintinterraform/modules/compute/gcp/cloud-run/: no findings.GOWORK=off GOTOOLCHAIN=go1.26.6 go test ./terraform/modules/compute/gcp/... -v: 2/2 pass.GOWORK=off GOTOOLCHAIN=go1.26.6 go vet ./terraform/modules/compute/gcp/...: clean.gofmt -lon the new test file: no output.Never ran
terraform plan/applyagainst real infra, per this project's convention.Closes #123
Summary by CodeRabbit