scripts/generate-federation-iac.go is a standalone dev tool for rendering
the same templates the runtime API (GET /api/federation/iac,
internal/api/handler_federation.go) renders. Its own doc comment says:
iacData mirrors internal/api/handler_federation.go:federationIaCData.
Keep in sync with any template variable changes.
It has not been kept in sync. iacData is missing several fields that
internal/iacfiles/templates/aws-wif.tfvars.tmpl and
aws-cfn-deploy.sh.tmpl already reference:
CUDlyAPIURL — referenced by the {{if .CUDlyAPIURL}} auto-registration
block at the bottom of aws-wif.tfvars.tmpl (and other tfvars templates).
ContactEmail — referenced inside that same block.
OIDCIssuerHost — referenced by aws-cfn-deploy.sh.tmpl's
--parameter-overrides.
Reproduce (pre-existing on main, unrelated to any in-flight PR):
go run scripts/generate-federation-iac.go \
--target aws --source gcp \
--account-name "prod-aws" --account-id "123456789012" \
--output -
Error: render internal/iacfiles/templates/aws-wif.tfvars.tmpl: template: iac:24:19: executing "iac" at <.CUDlyAPIURL>: can't evaluate field CUDlyAPIURL in type main.iacData
The default (tfvars) and --format bundle output for --target aws (any
non-aws --source) are currently unusable — text/template errors out
executing the struct field reference. --format cf-params still works
(that template doesn't reference the missing fields).
Not a security issue — this is a developer-facing tool
(//go:build ignore, run via go run, never reachable from customer
traffic), and its output is unusable rather than silently wrong. Filing so
it doesn't stay silently broken.
Suggested fix
Superseded in part by LeanerCloud/cloud-commitments-cli#1709. That issue tracks the missing iacData
fields as a current breakage on main, with a wider field list
(SourceAccountID as well) and an end-to-end render test. Add the fields
there, not here.
What remains for this issue once LeanerCloud/cloud-commitments-cli#1709 lands: fix the doc comment. "Keep in
sync with any template variable changes" claims an invariant nothing
enforces, which is how the drift went unnoticed in the first place. Say what
is true instead, and point at whatever coverage LeanerCloud/cloud-commitments-cli#1709 adds as the thing that
actually holds the two in step.
Not doing:
Remedy simplified (2026-08-03): the two new flags and the reflection sync
test were dropped, leaving the doc-comment correction. Note also corrected
the same day: an earlier revision of this section claimed no test could cover
the script because it is //go:build ignore. That is true of a test that
imports the struct, but LeanerCloud/cloud-commitments-cli#1709 shows an end-to-end test that executes
the script covers the same drift, so the coverage half of the original
remedy was right and this section was wrong to drop it outright.
Found while working on LeanerCloud/cloud-commitments-cli#1640 (internal/iacfiles/templates/aws-wif.tfvars.tmpl
now also references {{.OIDCSubjectClaim}}, which I added to iacData in
that PR — but the pre-existing missing fields above are unrelated to that
change and out of its scope).
Findings from the 2026-09-02 codebase audit
Added by an automated audit of 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd (tip of origin/main). Each item below was reported by one reviewer and independently confirmed by a second that did not write it. Full report: docs/audits/codebase-audit-2026-09-02.md.
A14-028 (low)
This drift is also load-bearing on a test's rationale, so the two should be closed together. TestGenerator_CrossAccountDoesNotRequireSubjectClaim (scripts/generate_federation_iac_test.go:434-446) asserts only on stderr, with a comment explaining that the invocation "currently fails for an unrelated pre-existing reason: iacData is missing the SourceAccountID / CUDlyAPIURL / ContactEmail / OIDCIssuerHost fields ... so no tfvars path of this script renders on main today". Three of those four now exist (SourceAccountID at generate-federation-iac.go:119, CUDlyAPIURL and ContactEmail at :141-142) and generate-federation-iac_test.go:40 renders tfvars successfully, so the justification is stale and the test currently passes whatever exit code the aws-to-aws path returns, including a regression that breaks it outright. Once the remaining OIDCIssuerHost gap is closed here, the test should assert res.exitCode == 0 and lose the rationale. (audit finding A14-028)
scripts/generate-federation-iac.gois a standalone dev tool for renderingthe same templates the runtime API (
GET /api/federation/iac,internal/api/handler_federation.go) renders. Its own doc comment says:It has not been kept in sync.
iacDatais missing several fields thatinternal/iacfiles/templates/aws-wif.tfvars.tmplandaws-cfn-deploy.sh.tmplalready reference:CUDlyAPIURL— referenced by the{{if .CUDlyAPIURL}}auto-registrationblock at the bottom of
aws-wif.tfvars.tmpl(and other tfvars templates).ContactEmail— referenced inside that same block.OIDCIssuerHost— referenced byaws-cfn-deploy.sh.tmpl's--parameter-overrides.Reproduce (pre-existing on
main, unrelated to any in-flight PR):The default (tfvars) and
--format bundleoutput for--target aws(anynon-
aws--source) are currently unusable —text/templateerrors outexecuting the struct field reference.
--format cf-paramsstill works(that template doesn't reference the missing fields).
Not a security issue — this is a developer-facing tool
(
//go:build ignore, run viago run, never reachable from customertraffic), and its output is unusable rather than silently wrong. Filing so
it doesn't stay silently broken.
Suggested fix
Superseded in part by LeanerCloud/cloud-commitments-cli#1709. That issue tracks the missing
iacDatafields as a current breakage on
main, with a wider field list(
SourceAccountIDas well) and an end-to-end render test. Add the fieldsthere, not here.
What remains for this issue once LeanerCloud/cloud-commitments-cli#1709 lands: fix the doc comment. "Keep in
sync with any template variable changes" claims an invariant nothing
enforces, which is how the drift went unnoticed in the first place. Say what
is true instead, and point at whatever coverage LeanerCloud/cloud-commitments-cli#1709 adds as the thing that
actually holds the two in step.
Not doing:
--cudly-api-url,--contact-email).--account-name/--account-idexist because the output is meaninglesswithout them; these are optional in every template that references them.
Add a flag when someone needs to set one.
covers the drift by rendering every
--target/--sourcecombination andasserting it succeeds, which catches a missing field without coupling the
tool's struct to
internal/api's.Remedy simplified (2026-08-03): the two new flags and the reflection sync
test were dropped, leaving the doc-comment correction. Note also corrected
the same day: an earlier revision of this section claimed no test could cover
the script because it is
//go:build ignore. That is true of a test thatimports the struct, but LeanerCloud/cloud-commitments-cli#1709 shows an end-to-end test that executes
the script covers the same drift, so the coverage half of the original
remedy was right and this section was wrong to drop it outright.
Found while working on LeanerCloud/cloud-commitments-cli#1640 (
internal/iacfiles/templates/aws-wif.tfvars.tmplnow also references
{{.OIDCSubjectClaim}}, which I added toiacDatainthat PR — but the pre-existing missing fields above are unrelated to that
change and out of its scope).
Findings from the 2026-09-02 codebase audit
Added by an automated audit of
3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd(tip oforigin/main). Each item below was reported by one reviewer and independently confirmed by a second that did not write it. Full report:docs/audits/codebase-audit-2026-09-02.md.A14-028 (low)
This drift is also load-bearing on a test's rationale, so the two should be closed together.
TestGenerator_CrossAccountDoesNotRequireSubjectClaim(scripts/generate_federation_iac_test.go:434-446) asserts only on stderr, with a comment explaining that the invocation "currently fails for an unrelated pre-existing reason: iacData is missing the SourceAccountID / CUDlyAPIURL / ContactEmail / OIDCIssuerHost fields ... so no tfvars path of this script renders on main today". Three of those four now exist (SourceAccountIDat generate-federation-iac.go:119,CUDlyAPIURLandContactEmailat :141-142) and generate-federation-iac_test.go:40 renders tfvars successfully, so the justification is stale and the test currently passes whatever exit code the aws-to-aws path returns, including a regression that breaks it outright. Once the remainingOIDCIssuerHostgap is closed here, the test should assertres.exitCode == 0and lose the rationale. (audit finding A14-028)