Summary
The PR LeanerCloud/cloud-commitments-cli#1219 (INF-02 IAM action drift fix) reconciles the AWS IAM action lists across the CloudFormation stack, the Terraform lambda/fargate modules, and the federation CFN/TF/CLI templates by taking the union of pre-existing grants so no customer-impacting revocation happens in the same PR. This is the right call while the parity gate ships.
It leaves two grants in the runtime trio's org_discovery policy that the application code never calls:
organizations:DescribeAccount -- granted by cloudformation/stacks/CUDly/template.yaml:479 and terraform/modules/compute/aws/{lambda,fargate}/main.tf:{260,471}. No caller anywhere in providers/aws/ or internal/accounts/.
organizations:DescribeOrganization -- granted by the same three files (cloudformation/stacks/CUDly/template.yaml:480 and the TF modules). No caller anywhere in providers/aws/ or internal/accounts/.
The only organizations: API the code calls is ListAccounts:
$ grep -rnE "organizations\." providers/aws/ internal/ --include="*.go" | grep -v _test.go | grep -E "(Describe|List)"
providers/aws/provider.go:43: ListAccounts(ctx context.Context, ...)
providers/aws/provider.go:283: paginator: organizations.NewListAccountsPaginator(orgClient, &organizations.ListAccountsInput{}),
internal/accounts/org_discovery.go:24: ListAccounts(ctx context.Context, ...)
internal/accounts/org_discovery.go:42: paginator := organizations.NewListAccountsPaginator(client, &organizations.ListAccountsInput{})
Why now
INF-02 reconciled DescribeAccount (existing in CFN) and DescribeOrganization (existing in TF lambda) into both files to make the parity gate pass. Now that the parity gate is in place, the next step is to drop the dead grants from both sides at once -- the gate will keep them aligned.
Acceptance criteria
- Remove
organizations:DescribeAccount and organizations:DescribeOrganization from the AccountDiscovery statement in cloudformation/stacks/CUDly/template.yaml.
- Remove
organizations:DescribeAccount and organizations:DescribeOrganization from the org_discovery aws_iam_role_policy in terraform/modules/compute/aws/lambda/main.tf and terraform/modules/compute/aws/fargate/main.tf.
scripts/check-aws-iam-parity.sh passes.
- No regression:
internal/accounts/... org discovery tests still pass.
Scope
Runtime trio only (CUDly's own deployment). Does NOT touch the federation cross-account flavors -- those already only grant ListAccounts + DescribeOrganization (no DescribeAccount), and customer-deployed roles are out of scope for revocation in this issue.
Out of scope
- Federation role least-privilege passes.
- The runtime
organizations:ListAccounts grant is real (used by internal/accounts/org_discovery.go:42) -- keep it.
Risk
Minimal. Both actions are unused; removal is a pure least-privilege win behind the parity gate. If a future feature wires up DescribeAccount / DescribeOrganization, that PR will re-add the actions through the same gate.
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.
A13b-013 (low)
The scope note here says the federation flavors already only grant ListAccounts + DescribeOrganization and are out of scope for revocation. Worth recording that DescribeOrganization is dead there too, for the same reason it is dead in the runtime trio: grep -rn "DescribeOrganization" --include='*.go' returns nothing at this commit, and ListAccounts is the only organizations API the code calls (providers/aws/provider.go:283-286). The customer-facing sites are iac/federation/aws-cross-account/cloudformation/template.yaml:138 and its Terraform twin at terraform/main.tf:157, plus the hub Lambda's AccountDiscovery statement. A customer who enables org discovery is granting CUDly the organization's management-account ID, master email and feature set for no call. Not asking to widen this issue, just so the follow-up least-privilege pass has the exact sites. (audit finding A13b-013)
Summary
The PR LeanerCloud/cloud-commitments-cli#1219 (INF-02 IAM action drift fix) reconciles the AWS IAM action lists across the CloudFormation stack, the Terraform lambda/fargate modules, and the federation CFN/TF/CLI templates by taking the union of pre-existing grants so no customer-impacting revocation happens in the same PR. This is the right call while the parity gate ships.
It leaves two grants in the runtime trio's
org_discoverypolicy that the application code never calls:organizations:DescribeAccount-- granted bycloudformation/stacks/CUDly/template.yaml:479andterraform/modules/compute/aws/{lambda,fargate}/main.tf:{260,471}. No caller anywhere inproviders/aws/orinternal/accounts/.organizations:DescribeOrganization-- granted by the same three files (cloudformation/stacks/CUDly/template.yaml:480and the TF modules). No caller anywhere inproviders/aws/orinternal/accounts/.The only
organizations:API the code calls isListAccounts:Why now
INF-02 reconciled
DescribeAccount(existing in CFN) andDescribeOrganization(existing in TF lambda) into both files to make the parity gate pass. Now that the parity gate is in place, the next step is to drop the dead grants from both sides at once -- the gate will keep them aligned.Acceptance criteria
organizations:DescribeAccountandorganizations:DescribeOrganizationfrom theAccountDiscoverystatement incloudformation/stacks/CUDly/template.yaml.organizations:DescribeAccountandorganizations:DescribeOrganizationfrom theorg_discoveryaws_iam_role_policyinterraform/modules/compute/aws/lambda/main.tfandterraform/modules/compute/aws/fargate/main.tf.scripts/check-aws-iam-parity.shpasses.internal/accounts/...org discovery tests still pass.Scope
Runtime trio only (CUDly's own deployment). Does NOT touch the federation cross-account flavors -- those already only grant
ListAccounts+DescribeOrganization(noDescribeAccount), and customer-deployed roles are out of scope for revocation in this issue.Out of scope
organizations:ListAccountsgrant is real (used byinternal/accounts/org_discovery.go:42) -- keep it.Risk
Minimal. Both actions are unused; removal is a pure least-privilege win behind the parity gate. If a future feature wires up
DescribeAccount/DescribeOrganization, that PR will re-add the actions through the same gate.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.A13b-013 (low)
The scope note here says the federation flavors already only grant
ListAccounts+DescribeOrganizationand are out of scope for revocation. Worth recording thatDescribeOrganizationis dead there too, for the same reason it is dead in the runtime trio:grep -rn "DescribeOrganization" --include='*.go'returns nothing at this commit, andListAccountsis the only organizations API the code calls (providers/aws/provider.go:283-286). The customer-facing sites areiac/federation/aws-cross-account/cloudformation/template.yaml:138and its Terraform twin atterraform/main.tf:157, plus the hub Lambda'sAccountDiscoverystatement. A customer who enables org discovery is granting CUDly the organization's management-account ID, master email and feature set for no call. Not asking to widen this issue, just so the follow-up least-privilege pass has the exact sites. (audit finding A13b-013)