aws-cis-controls-assessment 1.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. aws_cis_assessment/__init__.py +11 -0
  2. aws_cis_assessment/cli/__init__.py +3 -0
  3. aws_cis_assessment/cli/examples.py +274 -0
  4. aws_cis_assessment/cli/main.py +1259 -0
  5. aws_cis_assessment/cli/utils.py +356 -0
  6. aws_cis_assessment/config/__init__.py +1 -0
  7. aws_cis_assessment/config/config_loader.py +328 -0
  8. aws_cis_assessment/config/rules/cis_controls_ig1.yaml +590 -0
  9. aws_cis_assessment/config/rules/cis_controls_ig2.yaml +412 -0
  10. aws_cis_assessment/config/rules/cis_controls_ig3.yaml +100 -0
  11. aws_cis_assessment/controls/__init__.py +1 -0
  12. aws_cis_assessment/controls/base_control.py +400 -0
  13. aws_cis_assessment/controls/ig1/__init__.py +239 -0
  14. aws_cis_assessment/controls/ig1/control_1_1.py +586 -0
  15. aws_cis_assessment/controls/ig1/control_2_2.py +231 -0
  16. aws_cis_assessment/controls/ig1/control_3_3.py +718 -0
  17. aws_cis_assessment/controls/ig1/control_3_4.py +235 -0
  18. aws_cis_assessment/controls/ig1/control_4_1.py +461 -0
  19. aws_cis_assessment/controls/ig1/control_access_keys.py +310 -0
  20. aws_cis_assessment/controls/ig1/control_advanced_security.py +512 -0
  21. aws_cis_assessment/controls/ig1/control_backup_recovery.py +510 -0
  22. aws_cis_assessment/controls/ig1/control_cloudtrail_logging.py +197 -0
  23. aws_cis_assessment/controls/ig1/control_critical_security.py +422 -0
  24. aws_cis_assessment/controls/ig1/control_data_protection.py +898 -0
  25. aws_cis_assessment/controls/ig1/control_iam_advanced.py +573 -0
  26. aws_cis_assessment/controls/ig1/control_iam_governance.py +493 -0
  27. aws_cis_assessment/controls/ig1/control_iam_policies.py +383 -0
  28. aws_cis_assessment/controls/ig1/control_instance_optimization.py +100 -0
  29. aws_cis_assessment/controls/ig1/control_network_enhancements.py +203 -0
  30. aws_cis_assessment/controls/ig1/control_network_security.py +672 -0
  31. aws_cis_assessment/controls/ig1/control_s3_enhancements.py +173 -0
  32. aws_cis_assessment/controls/ig1/control_s3_security.py +422 -0
  33. aws_cis_assessment/controls/ig1/control_vpc_security.py +235 -0
  34. aws_cis_assessment/controls/ig2/__init__.py +172 -0
  35. aws_cis_assessment/controls/ig2/control_3_10.py +698 -0
  36. aws_cis_assessment/controls/ig2/control_3_11.py +1330 -0
  37. aws_cis_assessment/controls/ig2/control_5_2.py +393 -0
  38. aws_cis_assessment/controls/ig2/control_advanced_encryption.py +355 -0
  39. aws_cis_assessment/controls/ig2/control_codebuild_security.py +263 -0
  40. aws_cis_assessment/controls/ig2/control_encryption_rest.py +382 -0
  41. aws_cis_assessment/controls/ig2/control_encryption_transit.py +382 -0
  42. aws_cis_assessment/controls/ig2/control_network_ha.py +467 -0
  43. aws_cis_assessment/controls/ig2/control_remaining_encryption.py +426 -0
  44. aws_cis_assessment/controls/ig2/control_remaining_rules.py +363 -0
  45. aws_cis_assessment/controls/ig2/control_service_logging.py +402 -0
  46. aws_cis_assessment/controls/ig3/__init__.py +49 -0
  47. aws_cis_assessment/controls/ig3/control_12_8.py +395 -0
  48. aws_cis_assessment/controls/ig3/control_13_1.py +467 -0
  49. aws_cis_assessment/controls/ig3/control_3_14.py +523 -0
  50. aws_cis_assessment/controls/ig3/control_7_1.py +359 -0
  51. aws_cis_assessment/core/__init__.py +1 -0
  52. aws_cis_assessment/core/accuracy_validator.py +425 -0
  53. aws_cis_assessment/core/assessment_engine.py +1266 -0
  54. aws_cis_assessment/core/audit_trail.py +491 -0
  55. aws_cis_assessment/core/aws_client_factory.py +313 -0
  56. aws_cis_assessment/core/error_handler.py +607 -0
  57. aws_cis_assessment/core/models.py +166 -0
  58. aws_cis_assessment/core/scoring_engine.py +459 -0
  59. aws_cis_assessment/reporters/__init__.py +8 -0
  60. aws_cis_assessment/reporters/base_reporter.py +454 -0
  61. aws_cis_assessment/reporters/csv_reporter.py +835 -0
  62. aws_cis_assessment/reporters/html_reporter.py +2162 -0
  63. aws_cis_assessment/reporters/json_reporter.py +561 -0
  64. aws_cis_controls_assessment-1.0.3.dist-info/METADATA +248 -0
  65. aws_cis_controls_assessment-1.0.3.dist-info/RECORD +77 -0
  66. aws_cis_controls_assessment-1.0.3.dist-info/WHEEL +5 -0
  67. aws_cis_controls_assessment-1.0.3.dist-info/entry_points.txt +2 -0
  68. aws_cis_controls_assessment-1.0.3.dist-info/licenses/LICENSE +21 -0
  69. aws_cis_controls_assessment-1.0.3.dist-info/top_level.txt +2 -0
  70. docs/README.md +94 -0
  71. docs/assessment-logic.md +766 -0
  72. docs/cli-reference.md +698 -0
  73. docs/config-rule-mappings.md +393 -0
  74. docs/developer-guide.md +858 -0
  75. docs/installation.md +299 -0
  76. docs/troubleshooting.md +634 -0
  77. docs/user-guide.md +487 -0
@@ -0,0 +1,231 @@
1
+ """Control 2.2: Ensure Authorized Software is Currently Supported assessments."""
2
+
3
+ from typing import Dict, List, Any
4
+ import logging
5
+ from botocore.exceptions import ClientError
6
+
7
+ from aws_cis_assessment.controls.base_control import BaseConfigRuleAssessment
8
+ from aws_cis_assessment.core.models import ComplianceResult, ComplianceStatus
9
+ from aws_cis_assessment.core.aws_client_factory import AWSClientFactory
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class ElasticBeanstalkManagedUpdatesEnabledAssessment(BaseConfigRuleAssessment):
15
+ """Assessment for elastic-beanstalk-managed-updates-enabled Config rule."""
16
+
17
+ def __init__(self):
18
+ """Initialize Elastic Beanstalk managed updates assessment."""
19
+ super().__init__(
20
+ rule_name="elastic-beanstalk-managed-updates-enabled",
21
+ control_id="2.2",
22
+ resource_types=["AWS::ElasticBeanstalk::Environment"]
23
+ )
24
+
25
+ def _get_resources(self, aws_factory: AWSClientFactory, resource_type: str, region: str) -> List[Dict[str, Any]]:
26
+ """Get all Elastic Beanstalk environments in the region."""
27
+ if resource_type != "AWS::ElasticBeanstalk::Environment":
28
+ return []
29
+
30
+ try:
31
+ eb_client = aws_factory.get_client('elasticbeanstalk', region)
32
+
33
+ response = aws_factory.aws_api_call_with_retry(
34
+ lambda: eb_client.describe_environments()
35
+ )
36
+
37
+ environments = []
38
+ for env in response.get('Environments', []):
39
+ if env.get('Status') not in ['Terminated', 'Terminating']:
40
+ environments.append({
41
+ 'EnvironmentId': env.get('EnvironmentId'),
42
+ 'EnvironmentName': env.get('EnvironmentName'),
43
+ 'ApplicationName': env.get('ApplicationName'),
44
+ 'Status': env.get('Status'),
45
+ 'PlatformArn': env.get('PlatformArn')
46
+ })
47
+
48
+ logger.debug(f"Found {len(environments)} Elastic Beanstalk environments in region {region}")
49
+ return environments
50
+
51
+ except ClientError as e:
52
+ logger.error(f"Error retrieving Elastic Beanstalk environments in region {region}: {e}")
53
+ raise
54
+ except Exception as e:
55
+ logger.error(f"Unexpected error retrieving Elastic Beanstalk environments in region {region}: {e}")
56
+ raise
57
+
58
+ def _evaluate_resource_compliance(self, resource: Dict[str, Any], aws_factory: AWSClientFactory, region: str) -> ComplianceResult:
59
+ """Evaluate if Elastic Beanstalk environment has managed updates enabled."""
60
+ env_id = resource.get('EnvironmentId', 'unknown')
61
+ env_name = resource.get('EnvironmentName', 'unknown')
62
+
63
+ try:
64
+ eb_client = aws_factory.get_client('elasticbeanstalk', region)
65
+
66
+ # Get configuration settings for the environment
67
+ response = aws_factory.aws_api_call_with_retry(
68
+ lambda: eb_client.describe_configuration_settings(
69
+ ApplicationName=resource.get('ApplicationName'),
70
+ EnvironmentName=env_name
71
+ )
72
+ )
73
+
74
+ managed_updates_enabled = False
75
+ update_level = None
76
+
77
+ for config in response.get('ConfigurationSettings', []):
78
+ for option in config.get('OptionSettings', []):
79
+ if (option.get('Namespace') == 'aws:elasticbeanstalk:managedactions' and
80
+ option.get('OptionName') == 'ManagedActionsEnabled'):
81
+ managed_updates_enabled = option.get('Value', '').lower() == 'true'
82
+ elif (option.get('Namespace') == 'aws:elasticbeanstalk:managedactions:platformupdate' and
83
+ option.get('OptionName') == 'UpdateLevel'):
84
+ update_level = option.get('Value')
85
+
86
+ if managed_updates_enabled:
87
+ compliance_status = ComplianceStatus.COMPLIANT
88
+ evaluation_reason = f"Environment {env_name} has managed platform updates enabled"
89
+ if update_level:
90
+ evaluation_reason += f" (Update level: {update_level})"
91
+ else:
92
+ compliance_status = ComplianceStatus.NON_COMPLIANT
93
+ evaluation_reason = f"Environment {env_name} does not have managed platform updates enabled"
94
+
95
+ except ClientError as e:
96
+ error_code = e.response.get('Error', {}).get('Code', '')
97
+ if error_code in ['AccessDenied', 'UnauthorizedOperation']:
98
+ compliance_status = ComplianceStatus.ERROR
99
+ evaluation_reason = f"Insufficient permissions to check managed updates for environment {env_name}"
100
+ else:
101
+ compliance_status = ComplianceStatus.ERROR
102
+ evaluation_reason = f"Error checking managed updates for environment {env_name}: {str(e)}"
103
+ except Exception as e:
104
+ compliance_status = ComplianceStatus.ERROR
105
+ evaluation_reason = f"Unexpected error checking managed updates for environment {env_name}: {str(e)}"
106
+
107
+ return ComplianceResult(
108
+ resource_id=env_id,
109
+ resource_type="AWS::ElasticBeanstalk::Environment",
110
+ compliance_status=compliance_status,
111
+ evaluation_reason=evaluation_reason,
112
+ config_rule_name=self.rule_name,
113
+ region=region
114
+ )
115
+
116
+ def _get_rule_remediation_steps(self) -> List[str]:
117
+ """Get specific remediation steps for Elastic Beanstalk managed updates."""
118
+ return [
119
+ "Identify Elastic Beanstalk environments without managed platform updates enabled",
120
+ "For each environment, enable managed platform updates:",
121
+ " 1. Go to the Elastic Beanstalk console",
122
+ " 2. Select the environment",
123
+ " 3. Go to Configuration > Managed platform updates",
124
+ " 4. Enable managed platform updates",
125
+ " 5. Configure update level (patch or minor)",
126
+ " 6. Set maintenance window preferences",
127
+ "Use AWS CLI: aws elasticbeanstalk put-configuration-template with managed actions enabled",
128
+ "Monitor platform update notifications and apply updates during maintenance windows"
129
+ ]
130
+
131
+
132
+ class ECSFargateLatestPlatformVersionAssessment(BaseConfigRuleAssessment):
133
+ """Assessment for ecs-fargate-latest-platform-version Config rule."""
134
+
135
+ def __init__(self):
136
+ """Initialize ECS Fargate platform version assessment."""
137
+ super().__init__(
138
+ rule_name="ecs-fargate-latest-platform-version",
139
+ control_id="2.2",
140
+ resource_types=["AWS::ECS::Service"]
141
+ )
142
+
143
+ def _get_resources(self, aws_factory: AWSClientFactory, resource_type: str, region: str) -> List[Dict[str, Any]]:
144
+ """Get all ECS services using Fargate in the region."""
145
+ if resource_type != "AWS::ECS::Service":
146
+ return []
147
+
148
+ try:
149
+ ecs_client = aws_factory.get_client('ecs', region)
150
+
151
+ # Get all clusters
152
+ clusters_response = aws_factory.aws_api_call_with_retry(
153
+ lambda: ecs_client.list_clusters()
154
+ )
155
+
156
+ services = []
157
+ for cluster_arn in clusters_response.get('clusterArns', []):
158
+ # Get services in each cluster
159
+ services_response = aws_factory.aws_api_call_with_retry(
160
+ lambda: ecs_client.list_services(cluster=cluster_arn)
161
+ )
162
+
163
+ if services_response.get('serviceArns'):
164
+ # Get detailed service information
165
+ services_detail = aws_factory.aws_api_call_with_retry(
166
+ lambda: ecs_client.describe_services(
167
+ cluster=cluster_arn,
168
+ services=services_response['serviceArns']
169
+ )
170
+ )
171
+
172
+ for service in services_detail.get('services', []):
173
+ # Only include Fargate services
174
+ if service.get('launchType') == 'FARGATE' or 'FARGATE' in service.get('capacityProviderStrategy', []):
175
+ services.append({
176
+ 'ServiceArn': service.get('serviceArn'),
177
+ 'ServiceName': service.get('serviceName'),
178
+ 'ClusterArn': cluster_arn,
179
+ 'LaunchType': service.get('launchType'),
180
+ 'PlatformVersion': service.get('platformVersion'),
181
+ 'TaskDefinition': service.get('taskDefinition'),
182
+ 'Status': service.get('status')
183
+ })
184
+
185
+ logger.debug(f"Found {len(services)} ECS Fargate services in region {region}")
186
+ return services
187
+
188
+ except ClientError as e:
189
+ logger.error(f"Error retrieving ECS services in region {region}: {e}")
190
+ raise
191
+ except Exception as e:
192
+ logger.error(f"Unexpected error retrieving ECS services in region {region}: {e}")
193
+ raise
194
+
195
+ def _evaluate_resource_compliance(self, resource: Dict[str, Any], aws_factory: AWSClientFactory, region: str) -> ComplianceResult:
196
+ """Evaluate if ECS Fargate service uses the latest platform version."""
197
+ service_arn = resource.get('ServiceArn', 'unknown')
198
+ service_name = resource.get('ServiceName', 'unknown')
199
+ platform_version = resource.get('PlatformVersion', 'LATEST')
200
+
201
+ # LATEST is the recommended setting as it automatically uses the most recent platform version
202
+ if platform_version == 'LATEST':
203
+ compliance_status = ComplianceStatus.COMPLIANT
204
+ evaluation_reason = f"ECS service {service_name} uses LATEST platform version"
205
+ else:
206
+ compliance_status = ComplianceStatus.NON_COMPLIANT
207
+ evaluation_reason = f"ECS service {service_name} uses specific platform version {platform_version} instead of LATEST"
208
+
209
+ return ComplianceResult(
210
+ resource_id=service_arn,
211
+ resource_type="AWS::ECS::Service",
212
+ compliance_status=compliance_status,
213
+ evaluation_reason=evaluation_reason,
214
+ config_rule_name=self.rule_name,
215
+ region=region
216
+ )
217
+
218
+ def _get_rule_remediation_steps(self) -> List[str]:
219
+ """Get specific remediation steps for ECS Fargate platform versions."""
220
+ return [
221
+ "Identify ECS Fargate services not using the LATEST platform version",
222
+ "For each service, update to use LATEST platform version:",
223
+ " 1. Go to the ECS console",
224
+ " 2. Select the cluster and service",
225
+ " 3. Update the service configuration",
226
+ " 4. Set Platform version to LATEST",
227
+ " 5. Deploy the updated service",
228
+ "Use AWS CLI: aws ecs update-service --cluster <cluster> --service <service> --platform-version LATEST",
229
+ "Monitor service deployments to ensure successful updates",
230
+ "Set up automated deployment pipelines to use LATEST platform version by default"
231
+ ]