Repository navigation
fix(iac/aws): unblock deploy on rds:DescribeDBInstances and close audited grant gaps #1699
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: LeanerCloud/CUDly
Length of output: 207
🏁 Script executed:
Repository: LeanerCloud/CUDly
Length of output: 207
🌐 Web query:
AWS ELBv2 service authorization reference ModifyListenerAttributes SetIpAddressType SetSecurityGroups SetSubnets resource-level permissions resource types💡 Result:
In AWS Elastic Load Balancing V2 (ELBv2), the actions ModifyListenerAttributes, SetIpAddressType, SetSecurityGroups, and SetSubnets all support resource-level permissions [1]. This means you can restrict these actions to specific load balancer resources in your IAM policies by specifying the appropriate Amazon Resource Name (ARN) in the Resource element [1][2]. According to the official AWS Service Authorization Reference for ELBv2, these actions require the following resource types [1]: 1. ModifyListenerAttributes: Requires the listener resource type (arn:aws:elasticloadbalancing:region:account-id:listener/load-balancer-id/target-group-id/listener-id) or load balancer resource type depending on the specific configuration. 2. SetIpAddressType, SetSecurityGroups, and SetSubnets: These actions require the load balancer resource type (e.g., arn:aws:elasticloadbalancing:region:account-id:loadbalancer/app/load-balancer-name/load-balancer-id or arn:aws:elasticloadbalancing:region:account-id:loadbalancer/gwy/load-balancer-name/load-balancer-id) [1]. In AWS IAM policies, if an action supports resource-level permissions, you should avoid using a wildcard ("*") and instead specify the ARN of the specific load balancer or listener you wish to permit access to [3][2]. If you specify a resource that is not valid for the action, the request will fail [3]. These actions are classified with an "Write" access level [1][4].
Citations:
🏁 Script executed:
Repository: LeanerCloud/CUDly
Length of output: 24354
🏁 Script executed:
Repository: LeanerCloud/CUDly
Length of output: 14790
🏁 Script executed:
Repository: LeanerCloud/CUDly
Length of output: 50374
🌐 Web query:
site:docs.aws.amazon.com/service-authorization/latest/reference/list_elasticloadbalancingv2.html ModifyListenerAttributes SetIpAddressType SetSecurityGroups SetSubnets resource types💡 Result:
For AWS ELBv2 IAM actions, the required resource types are:
ModifyListenerAttributeslistener/app*,listener/gwy*,listener/net*SetIpAddressTypeloadbalancer/app/,loadbalancer/gwy/,loadbalancer/net/SetSecurityGroupsloadbalancer/app/,loadbalancer/net/SetSubnetsloadbalancer/app/,loadbalancer/gwy/,loadbalancer/net/SetSecurityGroupsadditionally supports theelasticloadbalancing:SecurityGroupcondition key;SetSubnetssupportselasticloadbalancing:Subnet. [1]🏁 Script executed:
Repository: LeanerCloud/CUDly
Length of output: 30667
Scope the ELB write permissions to deployment resources.
Use listener ARNs for
ModifyListenerAttributesand load-balancer ARNs for the threeSet*actions. Restrict them to thecudly-*deployment resources instead ofResource = "*".🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pre-existing hardening advice, not a defect this PR introduces. Deferring with reasons, tracked in #1703.
First, a correction in CodeRabbit's favour, because the opposite claim was made during review of this PR and it is wrong: ELB ARNs are not opaque and these actions can be prefix-scoped. The ARN is
arn:aws:elasticloadbalancing:<region>:<acct>:loadbalancer/app/<name>/<id>and the name is ours:aws_lb.main.name = local.name_prefix = "${var.stack_name}-fargate"(terraform/modules/compute/aws/fargate/main.tf:5,414), i.e.cudly-<env>-<hex>-fargate. Soloadbalancer/app/cudly-*/*andlistener/app/cudly-*/*would genuinely match. CodeRabbit's factual premise is correct and I am not disputing it.The reason to defer is different, and it is that scoping these four actions changes the blast radius by approximately nothing.
The statement these belong to is
ELBFargateinpolicy_compute.tf:250. It grants 19elasticloadbalancing:*actions onResource = "*", includingDeleteLoadBalancer,DeleteTargetGroup,DeleteListener,CreateLoadBalancer,ModifyLoadBalancerAttributesandModifyTargetGroup. That statement predates this PR and is untouched by it.ELBFargateSetAttributesexists only becausepolicy_compute.tfis at 5933 of 6144 characters and could not hold four more actions; it is a size-driven split ofELBFargate, which is exactly whatpolicy_compute_b.tf's file header describes. So the proposal is to scope 4 of 23 sibling actions while the other 19 — including every destructive one — keepResource = "*"in the adjacent file. An actor who can alreadyDeleteLoadBalanceron any load balancer in the account does not needSetSubnetson it. The scoped version would read as hardened without being hardened, which is a failure mode this PR is specifically about.The coherent change is to scope all 23 ELB actions together, in one statement, verified against live IAM. That is a hardening change to pre-existing grants and does not belong in a p0 outage fix where deploys have been down all session and the Fargate path cannot be exercised from here.
Two further notes, so the follow-up gets done correctly rather than quickly:
ModifyListenerAttributesand the threeSet*actions take different resource types (listenervsloadbalancer), so they cannot share oneResourcelist without one of the two legs silently matching nothing. CodeRabbit is right to call for splitting them; that is a detail worth not losing.listener/app/<name>/<lb-id>/<listener-id>), both AWS-assigned, so the pattern has to belistener/app/cudly-*/*/*and notlistener/app/cudly-*/*. A one-segment error there produces a grant that matches nothing and 403s on the nextaz_countchange — the precise failure this PR exists to fix (rds:DescribeDBInstanceswas granted onarn:aws:rds:*:*:db:cudly-*, the name matched, and production still returnedAccessDenied).Tracked in #1703 with the ARN formats above so the next person does not re-derive them. Not resolving this thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cristim, acknowledged.The finding is valid, but scoping only these four actions would not materially reduce the deploy role’s effective ELB permissions while
ELBFargateretains wildcard access for the related destructive actions.Deferring the complete ELB hardening to
#1703is appropriate for this outage-focused PR. The follow-up should scope all related ELB actions together and use separate statements for listener and load-balancer resource types. The listener pattern must uselistener/app/cudly-*/*/*.🐇
✏️ Learnings added
You are interacting with an AI system.