Summary
A scheduled ladder run computes its usage baseline through GetOnDemandSeries, which calls costexplorer.GetCostAndUsage under the ambient Lambda or Fargate execution role. None of the IaC flavors that encode CUDly's runtime IAM grant ce:GetCostAndUsage: the Cost Explorer statement lists only the six Reservation and Savings Plans actions. Every ladder run therefore fails its baseline with AccessDenied and is recorded as Errored with no plan produced. scripts/check-aws-iam-parity.sh cannot catch this because it compares the templates against each other, never against the SDK calls the Go code makes, so a uniform omission passes.
Location
terraform/modules/compute/aws/lambda/main.tf:381-386 at 3c0f8ac
terraform/modules/compute/aws/fargate/main.tf:373-378
cloudformation/stacks/CUDly/template.yaml:423-428
- caller:
providers/aws/recommendations/ondemand_series.go:182 via providers/aws/ladder/factory.go:85 (onDemandSeriesAdapter) and internal/api/handler_ladder.go:306 (GetUsageBaseline); wired at internal/server/app.go:570
Failure scenario
An operator enables a ladder config on a Lambda or Fargate deployment provisioned from any of the three templates. The scheduled ladder task runs GetUsageBaseline, the GetCostAndUsage call returns AccessDeniedException, and the run ends Errored. No ladder plan is ever produced on a stock deployment. The only ce:* wildcard in the tree is the permissions-boundary ceiling in policy_boundary.tf:163, which caps but never grants.
Evidence
Action = [
"ce:GetReservationUtilization",
"ce:GetReservationPurchaseRecommendation",
"ce:GetReservationCoverage",
"ce:GetSavingsPlansPurchaseRecommendation",
"ce:GetSavingsPlansUtilization",
"ce:GetSavingsPlansCoverage",
]
Suggested fix
Add ce:GetCostAndUsage to the runtime Cost Explorer statement in the Lambda and Fargate modules and the CloudFormation template, and add a guard (a Go test or an extension of check-aws-iam-parity.sh) asserting that every ce: action the SDK code calls appears in each flavor.
Found by the 2026-09-02 codebase audit, finding A13-001, reported by one reviewer and independently confirmed by a second. Full report: docs/audits/codebase-audit-2026-09-02.md.
Summary
A scheduled ladder run computes its usage baseline through
GetOnDemandSeries, which callscostexplorer.GetCostAndUsageunder the ambient Lambda or Fargate execution role. None of the IaC flavors that encode CUDly's runtime IAM grantce:GetCostAndUsage: the Cost Explorer statement lists only the six Reservation and Savings Plans actions. Every ladder run therefore fails its baseline with AccessDenied and is recorded as Errored with no plan produced.scripts/check-aws-iam-parity.shcannot catch this because it compares the templates against each other, never against the SDK calls the Go code makes, so a uniform omission passes.Location
terraform/modules/compute/aws/lambda/main.tf:381-386at 3c0f8acterraform/modules/compute/aws/fargate/main.tf:373-378cloudformation/stacks/CUDly/template.yaml:423-428providers/aws/recommendations/ondemand_series.go:182viaproviders/aws/ladder/factory.go:85(onDemandSeriesAdapter) andinternal/api/handler_ladder.go:306(GetUsageBaseline); wired atinternal/server/app.go:570Failure scenario
An operator enables a ladder config on a Lambda or Fargate deployment provisioned from any of the three templates. The scheduled ladder task runs
GetUsageBaseline, theGetCostAndUsagecall returns AccessDeniedException, and the run ends Errored. No ladder plan is ever produced on a stock deployment. The onlyce:*wildcard in the tree is the permissions-boundary ceiling inpolicy_boundary.tf:163, which caps but never grants.Evidence
Suggested fix
Add
ce:GetCostAndUsageto the runtime Cost Explorer statement in the Lambda and Fargate modules and the CloudFormation template, and add a guard (a Go test or an extension ofcheck-aws-iam-parity.sh) asserting that everyce:action the SDK code calls appears in each flavor.Found by the 2026-09-02 codebase audit, finding
A13-001, reported by one reviewer and independently confirmed by a second. Full report:docs/audits/codebase-audit-2026-09-02.md.