Skip to content

fix(iac/aws): drop dead organizations:Describe{Account,Organization} grants from runtime trio #69

Description

@cristim

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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions