Repository navigation
chore(iac): low findings from the 2026-09-02 audit: CFN host param, GCP KMS key, dev CORS #324
Description
Summary
Three low-severity Terraform and CloudFormation findings from the 2026-09-02 audit, grouped because each is a few-line change in the IaC tree and none is tracked elsewhere. Each item is independently actionable; keep the location and scenario with it if splitting any out.
-
CloudFormation WIF template makes the operator keep the issuer URL and its condition-key host in sync by hand (
A13b-014)- Location:
iac/federation/aws-target/cloudformation/template.yaml:20-28(OIDCIssuerHostparameter),:265-267(condition keys) at 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd - What:
OIDCIssuerHostis a second free-text parameter whose own description says it must equalOIDCIssuerURLminushttps://and that keeping them in sync is the operator's job. Its twoAllowedPatterns constrain shape only. The Terraform sibling derives the host in one line:iac/federation/aws-target/terraform/main.tf:22(trimsuffix(trimprefix(var.oidc_issuer_url, "https://"), "/")). - Failure scenario: the two values disagree by a trailing slash or a tenant-ID typo. IAM never populates
<host>:aud/<host>:subfor the incoming token,StringEqualsfails, and everyAssumeRoleWithWebIdentityis denied. It fails closed, but after the stack reports success, with no diagnostic naming the mismatch. - Fix: remove
OIDCIssuerHostand derive it as!Select [1, !Split ["https://", !Ref OIDCIssuerURL]]so one input cannot contradict the other.aws-cfn-deploy.sh.tmplpasses the parameter today (see chore(scripts): generate-federation-iac.go iacData has drifted out of sync with the templates it renders #153), so drop it from the parameter overrides in the same change.
- Location:
-
GCP OIDC signing key is explicitly unprotected where its AWS twin was given create_before_destroy (
A13c-024)- Location:
terraform/modules/compute/gcp/cloud-run/signing-key.tf:24-38at 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd - What:
google_kms_crypto_key.signingsetsdestroy_scheduled_duration = "86400s"with the comment "tests redeploy often" and an explicitlifecycle { prevent_destroy = false }(Terraform's default, so the line states rather than changes the posture).modules/compute/aws/lambda/signing-key.tf:19-27carriescreate_before_destroy = truewith a seven-line rationale citing fix(oidc): provision EC P-256 signing keys in Terraform to match ES256 code (follow-up to #882) cloud-commitments-cli#1480: replacing the OIDC signing key destroy-first breaks client-assertion JWT minting. The GCP key has neither mechanism. - Failure scenario: a ForceNew change on the key (
purpose,version_template.algorithm, or the key ring'slocationviavar.region) in a production project schedules the live signing key for destruction with a one-day window, and every federated target cloud rejects assertions until the new JWKS propagates. - Fix: make
prevent_destroyanddestroy_scheduled_durationmodule inputs so production gets the protective values and only test environments opt out, and addcreate_before_destroy = trueto match the AWS twin.
- Location:
-
A live Lambda Function URL hostname is hand-maintained in a tracked tfvars file (
A13c-017)- Location:
terraform/environments/aws/github-dev.tfvars:31-34at 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd;terraform/.gitignore:12-16ignores*.tfvarsthen re-admits!github-*.tfvars - What: the Function URL ID is server-assigned and only known after apply, so
lambda_allowed_originscarries it pasted by hand, and the comment three lines above says to update it whenever dev is redeployed. The endpoint is a public URL, not a credential. - Failure scenario: a redeploy that reissues the URL silently invalidates the CORS allowlist. The failure surfaces as a browser CORS error, not as a Terraform diff.
- Fix: supply the origin from the deploy workflow via
TF_VAR_lambda_allowed_origins, reading the previous apply'sfunction_urloutput, instead of committing the host. sec(iac): flip dev/staging/prod to AWS_IAM + enable CloudFront OAC (runtime cut-over for #424) #16 (CloudFront cut-over) would replace this origin with a stable domain and make the item moot; fix here only if sec(iac): flip dev/staging/prod to AWS_IAM + enable CloudFront OAC (runtime cut-over for #424) #16 stays parked.
- Location:
Found by the 2026-09-02 codebase audit, findings A13b-014, A13c-024, A13c-017, reported by one reviewer and independently confirmed by a second. Full report: docs/audits/codebase-audit-2026-09-02.md.
Activity