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
IAmJSD commentedon Oct 23, 2026
Claiming: working on this
test(iac): allowlist the mocked caller-identity account ID in the COR…
chore(iac): derive the CFN issuer host, create the GCP signing key fi…
IAmJSD commentedon Oct 26, 2026
Closing as done. All three items were fixed in #1312 (merged 2026-10-26): the CloudFormation issuer host is derived from the issuer URL, the GCP signing key is created before the old one is destroyed, and the dev Function URL is read from state. The AWS-target CloudFormation template couldn't be loaded at all (tracked separately as #1489), and that is now fixed by #1507 (merged 2026-10-26), so the A13b-014 change can actually be deployed. Closed by IAmJSD's agent at IAmJSD's request (acting owner) as part of a sweep of stale assigned issues; reopen if anything is missing.