@@ -377,6 +377,7 @@ def analyze(self, ecs_data: Dict[str, Any]) -> Dict[str, Any]:
377377 # Run security checks (will be implemented in subsequent subtasks)
378378 self ._analyze_cluster_security (cluster_data )
379379 self ._analyze_logging_security (cluster_data )
380+ self ._analyze_cluster_iam_security (cluster_data )
380381 self ._analyze_enhanced_cluster_security (container_instances )
381382 self ._analyze_capacity_providers (capacity_providers )
382383
@@ -876,6 +877,155 @@ def _analyze_logging_security(self, cluster: Dict[str, Any]) -> None:
876877 ],
877878 )
878879
880+ def _analyze_cluster_iam_security (self , cluster : Dict [str , Any ]) -> None :
881+ """
882+ Analyze cluster-level IAM security configurations.
883+
884+ Checks:
885+ - Service-linked role existence and configuration
886+ - Cluster-level IAM permissions
887+
888+ Args:
889+ cluster: Cluster data dictionary
890+ """
891+ cluster_name = cluster .get ("clusterName" , "unknown" )
892+
893+ # Check for ECS service-linked role
894+ # The service-linked role is automatically created when you use ECS,
895+ # but we should verify it exists and recommend checking its configuration
896+ # Note: We can't directly query IAM from the cluster data, but we can
897+ # provide guidance on verifying the service-linked role exists
898+
899+ # Check if cluster has any configuration that would require service-linked role
900+ # Service-linked roles are required for:
901+ # - ECS service discovery
902+ # - ECS Exec
903+ # - Load balancer integration
904+ # - Auto Scaling
905+
906+ configuration = cluster .get ("configuration" , {})
907+ exec_config = configuration .get ("executeCommandConfiguration" , {})
908+
909+ # If ECS Exec is configured, service-linked role is critical
910+ if exec_config :
911+ self ._add_recommendation (
912+ title = "🟡 Verify ECS Service-Linked Role Configuration" ,
913+ severity = "Medium" ,
914+ category = "IAM" ,
915+ resource = cluster_name ,
916+ issue = (
917+ f"Cluster { cluster_name } has ECS Exec configured, which requires the "
918+ "AWSServiceRoleForECS service-linked role. While this role is typically "
919+ "created automatically, it's important to verify it exists and has the "
920+ "correct permissions."
921+ ),
922+ recommendation = (
923+ "Verify that the AWSServiceRoleForECS service-linked role exists in your "
924+ "account and has the necessary permissions. This role is required for ECS "
925+ "to manage resources on your behalf, including ECS Exec, service discovery, "
926+ "and load balancer integration."
927+ ),
928+ remediation_steps = [
929+ "# Check if the service-linked role exists:" ,
930+ "aws iam get-role --role-name AWSServiceRoleForECS" ,
931+ "" ,
932+ "# If the role doesn't exist, create it:" ,
933+ "aws iam create-service-linked-role --aws-service-name ecs.amazonaws.com" ,
934+ "" ,
935+ "# Verify the role has the correct managed policy attached:" ,
936+ "aws iam list-attached-role-policies --role-name AWSServiceRoleForECS" ,
937+ "# Expected policy: AmazonECSServiceRolePolicy" ,
938+ "" ,
939+ "# Review the role's trust relationship:" ,
940+ (
941+ "aws iam get-role --role-name AWSServiceRoleForECS "
942+ "--query 'Role.AssumeRolePolicyDocument'"
943+ ),
944+ ],
945+ documentation_links = [
946+ "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/"
947+ "using-service-linked-roles.html" ,
948+ "https://docs.aws.amazon.com/IAM/latest/UserGuide/"
949+ "using-service-linked-roles.html" ,
950+ ],
951+ )
952+
953+ # Check for capacity providers which also require service-linked role
954+ capacity_provider_arns = cluster .get ("capacityProviders" , [])
955+ if capacity_provider_arns :
956+ self ._add_recommendation (
957+ title = "🟡 Verify Service-Linked Role for Capacity Providers" ,
958+ severity = "Medium" ,
959+ category = "IAM" ,
960+ resource = cluster_name ,
961+ issue = (
962+ f"Cluster { cluster_name } uses capacity providers, which require the "
963+ "AWSServiceRoleForECS service-linked role for Auto Scaling integration. "
964+ "Ensure this role exists and has proper permissions."
965+ ),
966+ recommendation = (
967+ "Verify the service-linked role exists and can manage Auto Scaling groups "
968+ "on behalf of ECS. Without proper permissions, capacity providers may fail "
969+ "to scale your cluster."
970+ ),
971+ remediation_steps = [
972+ "# Verify service-linked role exists:" ,
973+ "aws iam get-role --role-name AWSServiceRoleForECS" ,
974+ "" ,
975+ "# Check the role can access Auto Scaling:" ,
976+ "aws iam list-attached-role-policies --role-name AWSServiceRoleForECS" ,
977+ "" ,
978+ "# If using custom capacity providers, verify additional permissions:" ,
979+ "# - autoscaling:CreateAutoScalingGroup" ,
980+ "# - autoscaling:UpdateAutoScalingGroup" ,
981+ "# - autoscaling:DeleteAutoScalingGroup" ,
982+ "# - autoscaling:DescribeAutoScalingGroups" ,
983+ ],
984+ documentation_links = [
985+ "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/"
986+ "using-service-linked-roles.html" ,
987+ "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/"
988+ "asg-capacity-providers.html#asg-capacity-providers-iam" ,
989+ ],
990+ )
991+
992+ # Provide general IAM best practices recommendation
993+ self ._add_recommendation (
994+ title = "🟢 Review Cluster IAM Configuration" ,
995+ severity = "Low" ,
996+ category = "IAM" ,
997+ resource = cluster_name ,
998+ issue = (
999+ "Regular review of IAM configurations is a security best practice. "
1000+ "Ensure that all IAM roles and policies follow the principle of least privilege."
1001+ ),
1002+ recommendation = (
1003+ "Periodically review IAM roles and policies associated with this cluster, "
1004+ "including service-linked roles, task roles, and execution roles. Remove any "
1005+ "unnecessary permissions and ensure compliance with your organization's "
1006+ "security policies."
1007+ ),
1008+ remediation_steps = [
1009+ "# Review service-linked role:" ,
1010+ "aws iam get-role --role-name AWSServiceRoleForECS" ,
1011+ "" ,
1012+ "# List all roles used by tasks in this cluster:" ,
1013+ f"aws ecs list-services --cluster { cluster_name } " ,
1014+ "# Then describe each service to see task and execution roles" ,
1015+ "" ,
1016+ "# Use IAM Access Analyzer to identify unused permissions:" ,
1017+ "aws accessanalyzer list-analyzers" ,
1018+ "" ,
1019+ "# Review IAM policy simulator for specific permissions:" ,
1020+ "# https://policysim.aws.amazon.com/" ,
1021+ ],
1022+ documentation_links = [
1023+ "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html" ,
1024+ "https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html" ,
1025+ "https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html" ,
1026+ ],
1027+ )
1028+
8791029 def _generate_summary (self ) -> Dict [str , Any ]:
8801030 """
8811031 Generate summary statistics.
0 commit comments