From 0746c6242200d674b04f37ed41204675559753bf Mon Sep 17 00:00:00 2001 From: Alexanderamiri Date: Fri, 30 Oct 2026 10:37:22 +0100 Subject: [PATCH] fix(iam): scope DenyNoTag to security groups so apps can create their task SG #156 gives every app its own security group, created by the team CI role. The developer boundary's DenyNoTag denied ec2:CreateSecurityGroup on Resource "*" unless aws:RequestTag/team matches. AWS also authorizes that action against the VPC, where request tags are never in the context, so the IfExists deny always fired (frosting deploy 41034182549: explicit deny, DenyNoTag, on vpc/...). Teams never created SGs before, so it went unseen. Scope the statement to security-group resources. The tag is still required on the SG itself (IAM simulator: SG without team tag is still denied). Co-Authored-By: Claude Opus 5.5 --- terraform/platform/iam/boundary.tf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/terraform/platform/iam/boundary.tf b/terraform/platform/iam/boundary.tf index f9ccf9b..c5ba24c 100644 --- a/terraform/platform/iam/boundary.tf +++ b/terraform/platform/iam/boundary.tf @@ -217,11 +217,13 @@ locals { # -- REQUEST TAG ENFORCEMENT -- # SGs use IDs in ARNs so DenyBadName can't enforce naming. # Require team tag on create — Terraform default_tags handles this. + # Only the SG resource: CreateSecurityGroup is also authorized against + # the VPC, where request tags are never present, so "*" denied it always. { Sid = "DenyNoTag" Effect = "Deny" Action = "ec2:CreateSecurityGroup" - Resource = "*" + Resource = "arn:aws:ec2:*:*:security-group/*" Condition = { StringNotEqualsIfExists = { "aws:RequestTag/team" = "$${aws:PrincipalTag/team}"