aws-cis-controls-assessment 1.0.10__py3-none-any.whl → 1.1.0__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.
- aws_cis_assessment/__init__.py +2 -2
- aws_cis_assessment/config/rules/cis_controls_ig1.yaml +1 -1
- aws_cis_assessment/config/rules/cis_controls_ig2.yaml +599 -2
- aws_cis_assessment/controls/ig2/__init__.py +62 -1
- aws_cis_assessment/controls/ig2/control_4_5_6_access_configuration.py +2638 -0
- aws_cis_assessment/controls/ig2/control_8_audit_logging.py +984 -0
- aws_cis_assessment/core/assessment_engine.py +54 -0
- aws_cis_assessment/reporters/html_reporter.py +197 -35
- {aws_cis_controls_assessment-1.0.10.dist-info → aws_cis_controls_assessment-1.1.0.dist-info}/METADATA +160 -52
- {aws_cis_controls_assessment-1.0.10.dist-info → aws_cis_controls_assessment-1.1.0.dist-info}/RECORD +16 -14
- docs/cli-reference.md +1 -1
- docs/config-rule-mappings.md +423 -6
- {aws_cis_controls_assessment-1.0.10.dist-info → aws_cis_controls_assessment-1.1.0.dist-info}/WHEEL +0 -0
- {aws_cis_controls_assessment-1.0.10.dist-info → aws_cis_controls_assessment-1.1.0.dist-info}/entry_points.txt +0 -0
- {aws_cis_controls_assessment-1.0.10.dist-info → aws_cis_controls_assessment-1.1.0.dist-info}/licenses/LICENSE +0 -0
- {aws_cis_controls_assessment-1.0.10.dist-info → aws_cis_controls_assessment-1.1.0.dist-info}/top_level.txt +0 -0
|
@@ -161,6 +161,31 @@ from aws_cis_assessment.controls.ig2.control_aws_backup_ig2 import (
|
|
|
161
161
|
BackupReportPlanExistsCheckAssessment,
|
|
162
162
|
BackupRestoreTestingPlanExistsCheckAssessment
|
|
163
163
|
)
|
|
164
|
+
from aws_cis_assessment.controls.ig2.control_8_audit_logging import (
|
|
165
|
+
Route53QueryLoggingAssessment,
|
|
166
|
+
ALBAccessLogsEnabledAssessment,
|
|
167
|
+
CloudFrontAccessLogsEnabledAssessment,
|
|
168
|
+
CloudWatchLogRetentionCheckAssessment,
|
|
169
|
+
CloudTrailInsightsEnabledAssessment,
|
|
170
|
+
ConfigRecordingAllResourcesAssessment,
|
|
171
|
+
WAFLoggingEnabledAssessment
|
|
172
|
+
)
|
|
173
|
+
from aws_cis_assessment.controls.ig2.control_4_5_6_access_configuration import (
|
|
174
|
+
IAMMaxSessionDurationCheckAssessment,
|
|
175
|
+
SecurityGroupDefaultRulesCheckAssessment,
|
|
176
|
+
VPCDnsResolutionEnabledAssessment,
|
|
177
|
+
RDSDefaultAdminCheckAssessment,
|
|
178
|
+
EC2InstanceProfileLeastPrivilegeAssessment,
|
|
179
|
+
IAMServiceAccountInventoryCheckAssessment,
|
|
180
|
+
IAMAdminPolicyAttachedToRoleCheckAssessment,
|
|
181
|
+
SSOEnabledCheckAssessment,
|
|
182
|
+
IAMUserNoInlinePoliciesAssessment,
|
|
183
|
+
IAMAccessAnalyzerEnabledAssessment,
|
|
184
|
+
IAMPermissionBoundariesCheckAssessment,
|
|
185
|
+
OrganizationsSCPEnabledCheckAssessment,
|
|
186
|
+
CognitoUserPoolMFAEnabledAssessment,
|
|
187
|
+
VPNConnectionMFAEnabledAssessment
|
|
188
|
+
)
|
|
164
189
|
from aws_cis_assessment.controls.ig3.control_3_14 import (
|
|
165
190
|
APIGatewayExecutionLoggingEnabledAssessment, CloudTrailS3DataEventsEnabledAssessment,
|
|
166
191
|
MultiRegionCloudTrailEnabledAssessment, CloudTrailCloudWatchLogsEnabledAssessment
|
|
@@ -508,6 +533,35 @@ class AssessmentEngine:
|
|
|
508
533
|
'backup-vault-lock-check': BackupVaultLockCheckAssessment(),
|
|
509
534
|
'backup-report-plan-exists-check': BackupReportPlanExistsCheckAssessment(),
|
|
510
535
|
'backup-restore-testing-plan-exists-check': BackupRestoreTestingPlanExistsCheckAssessment(),
|
|
536
|
+
|
|
537
|
+
# Control 8.2 - Audit Log Management
|
|
538
|
+
'route53-query-logging-enabled': Route53QueryLoggingAssessment(),
|
|
539
|
+
'alb-access-logs-enabled': ALBAccessLogsEnabledAssessment(),
|
|
540
|
+
'cloudfront-access-logs-enabled': CloudFrontAccessLogsEnabledAssessment(),
|
|
541
|
+
'cloudwatch-log-retention-check': CloudWatchLogRetentionCheckAssessment(),
|
|
542
|
+
'cloudtrail-insights-enabled': CloudTrailInsightsEnabledAssessment(),
|
|
543
|
+
'config-recording-all-resources': ConfigRecordingAllResourcesAssessment(),
|
|
544
|
+
'waf-logging-enabled': WAFLoggingEnabledAssessment(),
|
|
545
|
+
|
|
546
|
+
# Control 4 - Secure Configuration
|
|
547
|
+
'iam-max-session-duration-check': IAMMaxSessionDurationCheckAssessment(),
|
|
548
|
+
'security-group-default-rules-check': SecurityGroupDefaultRulesCheckAssessment(),
|
|
549
|
+
'vpc-dns-resolution-enabled': VPCDnsResolutionEnabledAssessment(),
|
|
550
|
+
'rds-default-admin-check': RDSDefaultAdminCheckAssessment(),
|
|
551
|
+
'ec2-instance-profile-least-privilege': EC2InstanceProfileLeastPrivilegeAssessment(),
|
|
552
|
+
|
|
553
|
+
# Control 5 - Account Management
|
|
554
|
+
'iam-service-account-inventory-check': IAMServiceAccountInventoryCheckAssessment(),
|
|
555
|
+
'iam-admin-policy-attached-to-role-check': IAMAdminPolicyAttachedToRoleCheckAssessment(),
|
|
556
|
+
'sso-enabled-check': SSOEnabledCheckAssessment(),
|
|
557
|
+
'iam-user-no-inline-policies': IAMUserNoInlinePoliciesAssessment(),
|
|
558
|
+
|
|
559
|
+
# Control 6 - Access Control Management
|
|
560
|
+
'iam-access-analyzer-enabled': IAMAccessAnalyzerEnabledAssessment(),
|
|
561
|
+
'iam-permission-boundaries-check': IAMPermissionBoundariesCheckAssessment(),
|
|
562
|
+
'organizations-scp-enabled-check': OrganizationsSCPEnabledCheckAssessment(),
|
|
563
|
+
'cognito-user-pool-mfa-enabled': CognitoUserPoolMFAEnabledAssessment(),
|
|
564
|
+
'vpn-connection-mfa-enabled': VPNConnectionMFAEnabledAssessment(),
|
|
511
565
|
},
|
|
512
566
|
'IG3': {
|
|
513
567
|
# Control 3.14 - Sensitive Data Logging
|
|
@@ -70,6 +70,7 @@ class HTMLReporter(ReportGenerator):
|
|
|
70
70
|
"""
|
|
71
71
|
super().__init__(template_dir)
|
|
72
72
|
self.include_charts = include_charts
|
|
73
|
+
self._control_titles_cache = {} # Cache for control titles from YAML
|
|
73
74
|
logger.info(f"Initialized HTMLReporter with charts={include_charts}")
|
|
74
75
|
|
|
75
76
|
def generate_report(self, assessment_result: AssessmentResult,
|
|
@@ -1117,7 +1118,97 @@ class HTMLReporter(ReportGenerator):
|
|
|
1117
1118
|
text-decoration: underline;
|
|
1118
1119
|
}
|
|
1119
1120
|
|
|
1121
|
+
/* Remediation Section Styles */
|
|
1122
|
+
.remediation {
|
|
1123
|
+
margin-bottom: 40px;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
.remediation-list {
|
|
1127
|
+
display: flex;
|
|
1128
|
+
flex-direction: column;
|
|
1129
|
+
gap: 20px;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
.remediation-item {
|
|
1133
|
+
background: white;
|
|
1134
|
+
border: 1px solid #e0e0e0;
|
|
1135
|
+
border-radius: 8px;
|
|
1136
|
+
padding: 20px;
|
|
1137
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
1138
|
+
transition: box-shadow 0.2s;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
.remediation-item:hover {
|
|
1142
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
.remediation-header {
|
|
1146
|
+
display: flex;
|
|
1147
|
+
justify-content: space-between;
|
|
1148
|
+
align-items: flex-start;
|
|
1149
|
+
margin-bottom: 15px;
|
|
1150
|
+
padding-bottom: 15px;
|
|
1151
|
+
border-bottom: 2px solid #f0f0f0;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
.remediation-header h4 {
|
|
1155
|
+
margin: 0;
|
|
1156
|
+
color: #2c3e50;
|
|
1157
|
+
font-size: 1.1em;
|
|
1158
|
+
flex: 1;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
.remediation-badges {
|
|
1162
|
+
display: flex;
|
|
1163
|
+
gap: 10px;
|
|
1164
|
+
flex-shrink: 0;
|
|
1165
|
+
margin-left: 15px;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
.remediation-content {
|
|
1169
|
+
color: #555;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.remediation-content h5 {
|
|
1173
|
+
margin: 15px 0 10px 0;
|
|
1174
|
+
color: #2c3e50;
|
|
1175
|
+
font-size: 1em;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
.remediation-content ol {
|
|
1179
|
+
margin: 10px 0;
|
|
1180
|
+
padding-left: 25px;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
.remediation-content ol li {
|
|
1184
|
+
margin: 8px 0;
|
|
1185
|
+
line-height: 1.6;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
.remediation-content p {
|
|
1189
|
+
margin: 15px 0 5px 0;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
.remediation-content a {
|
|
1193
|
+
color: #3498db;
|
|
1194
|
+
text-decoration: none;
|
|
1195
|
+
font-weight: 500;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
.remediation-content a:hover {
|
|
1199
|
+
text-decoration: underline;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1120
1202
|
@media (max-width: 768px) {
|
|
1203
|
+
.remediation-header {
|
|
1204
|
+
flex-direction: column;
|
|
1205
|
+
gap: 10px;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
.remediation-badges {
|
|
1209
|
+
margin-left: 0;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1121
1212
|
.comparison-grid {
|
|
1122
1213
|
grid-template-columns: 1fr;
|
|
1123
1214
|
}
|
|
@@ -1331,13 +1422,51 @@ class HTMLReporter(ReportGenerator):
|
|
|
1331
1422
|
}});
|
|
1332
1423
|
}}
|
|
1333
1424
|
|
|
1334
|
-
// Search functionality
|
|
1425
|
+
// Search functionality for detailed findings
|
|
1335
1426
|
function searchFindings(searchTerm) {{
|
|
1336
|
-
const
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1427
|
+
const term = searchTerm.toLowerCase();
|
|
1428
|
+
const controlSections = document.querySelectorAll('.collapsible-content');
|
|
1429
|
+
|
|
1430
|
+
controlSections.forEach(function(section) {{
|
|
1431
|
+
const rows = section.querySelectorAll('.findings-table tbody tr');
|
|
1432
|
+
let visibleCount = 0;
|
|
1433
|
+
|
|
1434
|
+
rows.forEach(function(row) {{
|
|
1435
|
+
const cells = row.querySelectorAll('td');
|
|
1436
|
+
if (cells.length === 0) return;
|
|
1437
|
+
|
|
1438
|
+
// Search across: resource ID, resource type, region, evaluation reason, config rule name
|
|
1439
|
+
const resourceId = cells[0] ? cells[0].textContent.toLowerCase() : '';
|
|
1440
|
+
const resourceType = cells[1] ? cells[1].textContent.toLowerCase() : '';
|
|
1441
|
+
const region = cells[2] ? cells[2].textContent.toLowerCase() : '';
|
|
1442
|
+
const configRule = cells[4] ? cells[4].textContent.toLowerCase() : '';
|
|
1443
|
+
const evaluationReason = cells[5] ? cells[5].textContent.toLowerCase() : '';
|
|
1444
|
+
|
|
1445
|
+
const matches = resourceId.includes(term) ||
|
|
1446
|
+
resourceType.includes(term) ||
|
|
1447
|
+
region.includes(term) ||
|
|
1448
|
+
configRule.includes(term) ||
|
|
1449
|
+
evaluationReason.includes(term);
|
|
1450
|
+
|
|
1451
|
+
if (matches || term === '') {{
|
|
1452
|
+
row.style.display = '';
|
|
1453
|
+
visibleCount++;
|
|
1454
|
+
}} else {{
|
|
1455
|
+
row.style.display = 'none';
|
|
1456
|
+
}}
|
|
1457
|
+
}});
|
|
1458
|
+
|
|
1459
|
+
// Update the count in the collapsible button if it exists
|
|
1460
|
+
const collapsibleBtn = section.previousElementSibling;
|
|
1461
|
+
if (collapsibleBtn && collapsibleBtn.classList.contains('collapsible')) {{
|
|
1462
|
+
const originalText = collapsibleBtn.textContent.split('(')[0].trim();
|
|
1463
|
+
const totalCount = rows.length;
|
|
1464
|
+
if (term === '') {{
|
|
1465
|
+
collapsibleBtn.textContent = `${{originalText}} (${{totalCount}} findings)`;
|
|
1466
|
+
}} else {{
|
|
1467
|
+
collapsibleBtn.textContent = `${{originalText}} (${{visibleCount}} of ${{totalCount}} findings)`;
|
|
1468
|
+
}}
|
|
1469
|
+
}}
|
|
1341
1470
|
}});
|
|
1342
1471
|
}}
|
|
1343
1472
|
|
|
@@ -1851,13 +1980,19 @@ class HTMLReporter(ReportGenerator):
|
|
|
1851
1980
|
for step in remediation["remediation_steps"]:
|
|
1852
1981
|
steps_html += f"<li>{step}</li>"
|
|
1853
1982
|
|
|
1983
|
+
# Normalize priority and effort text to proper capitalization
|
|
1984
|
+
priority_text = remediation['priority'].capitalize()
|
|
1985
|
+
effort_text = remediation['estimated_effort'].capitalize()
|
|
1986
|
+
|
|
1854
1987
|
remediation_items += f"""
|
|
1855
1988
|
<div class="remediation-item">
|
|
1856
1989
|
<div class="remediation-header">
|
|
1857
|
-
<
|
|
1990
|
+
<div>
|
|
1991
|
+
<h4>{remediation['control_id']} - {remediation['config_rule_name']}</h4>
|
|
1992
|
+
</div>
|
|
1858
1993
|
<div class="remediation-badges">
|
|
1859
|
-
<span class="badge {remediation['priority_badge']}">{
|
|
1860
|
-
<span class="badge {remediation['effort_badge']}">{
|
|
1994
|
+
<span class="badge {remediation['priority_badge']}">{priority_text}</span>
|
|
1995
|
+
<span class="badge {remediation['effort_badge']}">{effort_text}</span>
|
|
1861
1996
|
</div>
|
|
1862
1997
|
</div>
|
|
1863
1998
|
<div class="remediation-content">
|
|
@@ -2168,17 +2303,7 @@ class HTMLReporter(ReportGenerator):
|
|
|
2168
2303
|
</div>
|
|
2169
2304
|
</div>
|
|
2170
2305
|
|
|
2171
|
-
|
|
2172
|
-
<strong>Which score should I use?</strong>
|
|
2173
|
-
<ul>
|
|
2174
|
-
<li><strong>Weighted Score:</strong> Use for security decision-making, risk prioritization, and remediation planning</li>
|
|
2175
|
-
<li><strong>AWS Config Style:</strong> Use for compliance reporting, audits, and simple stakeholder communication</li>
|
|
2176
|
-
<li><strong>Both:</strong> Track both metrics for comprehensive security program management</li>
|
|
2177
|
-
</ul>
|
|
2178
|
-
<p>
|
|
2179
|
-
<a href="#" onclick="toggleScoringDetails(); return false;">Learn more about scoring methodologies →</a>
|
|
2180
|
-
</p>
|
|
2181
|
-
</div>
|
|
2306
|
+
|
|
2182
2307
|
</div>
|
|
2183
2308
|
"""
|
|
2184
2309
|
|
|
@@ -2615,47 +2740,84 @@ class HTMLReporter(ReportGenerator):
|
|
|
2615
2740
|
options += f'<option value="{resource_type}">{resource_type}</option>'
|
|
2616
2741
|
return options
|
|
2617
2742
|
|
|
2743
|
+
def _load_control_titles(self) -> Dict[str, str]:
|
|
2744
|
+
"""Load control titles from YAML configuration files.
|
|
2745
|
+
|
|
2746
|
+
Returns:
|
|
2747
|
+
Dictionary mapping control IDs to their titles
|
|
2748
|
+
"""
|
|
2749
|
+
if self._control_titles_cache:
|
|
2750
|
+
return self._control_titles_cache
|
|
2751
|
+
|
|
2752
|
+
from aws_cis_assessment.config.config_loader import ConfigRuleLoader
|
|
2753
|
+
|
|
2754
|
+
try:
|
|
2755
|
+
loader = ConfigRuleLoader()
|
|
2756
|
+
all_controls = loader.get_all_controls()
|
|
2757
|
+
|
|
2758
|
+
# Build a map of control_id -> title
|
|
2759
|
+
# Since controls can appear in multiple IGs, we'll use the first title we find
|
|
2760
|
+
for unique_key, control in all_controls.items():
|
|
2761
|
+
control_id = control.control_id
|
|
2762
|
+
if control_id not in self._control_titles_cache and control.title:
|
|
2763
|
+
self._control_titles_cache[control_id] = control.title
|
|
2764
|
+
|
|
2765
|
+
logger.info(f"Loaded {len(self._control_titles_cache)} control titles from YAML")
|
|
2766
|
+
except Exception as e:
|
|
2767
|
+
logger.warning(f"Failed to load control titles from YAML: {e}")
|
|
2768
|
+
self._control_titles_cache = {}
|
|
2769
|
+
|
|
2770
|
+
return self._control_titles_cache
|
|
2771
|
+
|
|
2618
2772
|
def _format_control_display_name(self, control_id: str, config_rule_name: str, title: Optional[str] = None) -> str:
|
|
2619
|
-
"""Format control display name combining ID
|
|
2773
|
+
"""Format control display name combining ID and title.
|
|
2620
2774
|
|
|
2621
2775
|
Creates a human-readable display name that shows both the control identifier
|
|
2622
|
-
and the
|
|
2623
|
-
each control
|
|
2776
|
+
and the control title from the YAML configuration, making it easier for users
|
|
2777
|
+
to understand what each control is about without looking up documentation.
|
|
2624
2778
|
|
|
2625
2779
|
Args:
|
|
2626
2780
|
control_id: Control identifier (e.g., "1.5", "2.1")
|
|
2627
2781
|
config_rule_name: AWS Config rule name (e.g., "root-account-hardware-mfa-enabled")
|
|
2628
|
-
title: Optional human-readable title for the control
|
|
2782
|
+
title: Optional human-readable title for the control (if not provided, loads from YAML)
|
|
2629
2783
|
|
|
2630
2784
|
Returns:
|
|
2631
2785
|
Formatted string for display in the following formats:
|
|
2632
|
-
- With title: "{control_id}: {title}
|
|
2786
|
+
- With title: "{control_id}: {title}"
|
|
2633
2787
|
- Without title: "{control_id}: {config_rule_name}"
|
|
2634
2788
|
- Fallback (no rule name): "{control_id}"
|
|
2635
2789
|
|
|
2636
2790
|
Examples:
|
|
2637
|
-
>>> _format_control_display_name("1.
|
|
2638
|
-
"1.
|
|
2791
|
+
>>> _format_control_display_name("1.1", "eip-attached")
|
|
2792
|
+
"1.1: Establish and Maintain Detailed Enterprise Asset Inventory"
|
|
2639
2793
|
|
|
2640
|
-
>>> _format_control_display_name("
|
|
2641
|
-
"
|
|
2794
|
+
>>> _format_control_display_name("3.3", "s3-bucket-ssl-requests-only")
|
|
2795
|
+
"3.3: Configure Data Access Control Lists"
|
|
2642
2796
|
|
|
2643
2797
|
>>> _format_control_display_name("3.1", "")
|
|
2644
2798
|
"3.1"
|
|
2645
2799
|
|
|
2646
2800
|
Notes:
|
|
2647
|
-
-
|
|
2801
|
+
- Loads control titles from YAML configuration files
|
|
2802
|
+
- Gracefully handles missing titles by falling back to config_rule_name
|
|
2648
2803
|
- Used in both Implementation Groups and Detailed Findings sections
|
|
2649
2804
|
- Display names longer than 50 characters are truncated with tooltips
|
|
2650
2805
|
"""
|
|
2651
|
-
if not
|
|
2652
|
-
|
|
2653
|
-
|
|
2806
|
+
# Load control titles from YAML if not already loaded
|
|
2807
|
+
if not title:
|
|
2808
|
+
control_titles = self._load_control_titles()
|
|
2809
|
+
title = control_titles.get(control_id)
|
|
2654
2810
|
|
|
2811
|
+
# If we have a title, use it
|
|
2655
2812
|
if title:
|
|
2656
|
-
return f"{control_id}: {title}
|
|
2657
|
-
|
|
2813
|
+
return f"{control_id}: {title}"
|
|
2814
|
+
|
|
2815
|
+
# Fallback to config_rule_name if no title
|
|
2816
|
+
if config_rule_name:
|
|
2658
2817
|
return f"{control_id}: {config_rule_name}"
|
|
2818
|
+
|
|
2819
|
+
# Last resort: just the control_id
|
|
2820
|
+
return control_id
|
|
2659
2821
|
|
|
2660
2822
|
def _get_ig_badge_class(self, ig_name: str) -> str:
|
|
2661
2823
|
"""Get CSS class for IG badge styling.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aws-cis-controls-assessment
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Production-ready AWS CIS Controls compliance assessment framework with 145 comprehensive rules
|
|
5
5
|
Author-email: AWS CIS Assessment Team <security@example.com>
|
|
6
6
|
Maintainer-email: AWS CIS Assessment Team <security@example.com>
|
|
@@ -57,20 +57,22 @@ Dynamic: license-file
|
|
|
57
57
|
|
|
58
58
|
# AWS CIS Controls Compliance Assessment Framework
|
|
59
59
|
|
|
60
|
-
A production-ready, enterprise-grade framework for evaluating AWS account configurations against CIS Controls Implementation Groups (IG1, IG2, IG3) using AWS Config rule specifications. **100% CIS Controls coverage achieved** with
|
|
60
|
+
A production-ready, enterprise-grade framework for evaluating AWS account configurations against CIS Controls Implementation Groups (IG1, IG2, IG3) using AWS Config rule specifications. **100% CIS Controls coverage achieved** with 163 implemented rules (131 CIS Controls + 32 bonus security enhancements).
|
|
61
61
|
|
|
62
62
|
> **Production Status**: This framework is production-ready and actively deployed in enterprise environments. It provides comprehensive point-in-time compliance assessments while we recommend [AWS Config](https://aws.amazon.com/config/) for ongoing continuous compliance monitoring and automated remediation.
|
|
63
63
|
|
|
64
64
|
## 🎯 Key Features
|
|
65
65
|
|
|
66
|
-
- **✅ Complete Coverage**:
|
|
66
|
+
- **✅ Complete Coverage**: 163 total rules implemented (131 CIS Controls + 32 bonus)
|
|
67
67
|
- **✅ Dual Scoring System**: Both weighted and AWS Config-style scoring methodologies
|
|
68
|
+
- **✅ Enhanced HTML Reports**: Control names, working search, improved remediation display
|
|
68
69
|
- **✅ Enterprise Ready**: Production-tested with enterprise-grade architecture
|
|
69
70
|
- **✅ Performance Optimized**: Handles large-scale assessments efficiently
|
|
70
71
|
- **✅ Multi-Format Reports**: JSON, HTML, and CSV with detailed remediation guidance
|
|
71
72
|
- **✅ No AWS Config Required**: Direct AWS API calls based on Config rule specifications
|
|
72
|
-
- **✅ Bonus Security Rules**: 5 additional security enhancements beyond CIS requirements
|
|
73
73
|
- **✅ AWS Backup Controls**: 6 comprehensive backup infrastructure controls (3 IG1 + 3 IG2)
|
|
74
|
+
- **✅ Audit Logging Controls**: 7 comprehensive audit log management controls (CIS Control 8)
|
|
75
|
+
- **✅ Access & Configuration Controls**: 14 comprehensive identity, access, and secure configuration controls (CIS Controls 4, 5, 6)
|
|
74
76
|
|
|
75
77
|
## 🚀 Quick Start
|
|
76
78
|
|
|
@@ -89,7 +91,7 @@ pip install -e .
|
|
|
89
91
|
### Basic Usage
|
|
90
92
|
|
|
91
93
|
```bash
|
|
92
|
-
# Run complete assessment (all
|
|
94
|
+
# Run complete assessment (all 163 rules) - defaults to us-east-1
|
|
93
95
|
aws-cis-assess assess --aws-profile my-aws-profile
|
|
94
96
|
|
|
95
97
|
# Assess multiple regions
|
|
@@ -117,12 +119,12 @@ aws-cis-assess assess --output-format json
|
|
|
117
119
|
- Data Protection and Encryption (8 rules)
|
|
118
120
|
- Network Security Controls (20 rules)
|
|
119
121
|
- Logging and Monitoring (13 rules)
|
|
120
|
-
- Backup and Recovery (17 rules) - **
|
|
122
|
+
- Backup and Recovery (17 rules) - **6 AWS Backup service controls (3 IG1 + 3 IG2)**
|
|
121
123
|
- Security Services Integration (5 rules)
|
|
122
124
|
- Configuration Management (9 rules)
|
|
123
125
|
- Vulnerability Management (5 rules)
|
|
124
126
|
|
|
125
|
-
### IG2 - Enhanced Security (+
|
|
127
|
+
### IG2 - Enhanced Security (+74 Rules) ✅
|
|
126
128
|
**100% Coverage Achieved**
|
|
127
129
|
- Advanced Encryption at Rest (6 rules)
|
|
128
130
|
- Certificate Management (2 rules)
|
|
@@ -133,7 +135,11 @@ aws-cis-assess assess --output-format json
|
|
|
133
135
|
- Network Segmentation (5 rules)
|
|
134
136
|
- Auto-scaling Security (1 rule)
|
|
135
137
|
- Enhanced Access Controls (8 rules)
|
|
136
|
-
- AWS Backup Advanced Controls (3 rules) - **
|
|
138
|
+
- AWS Backup Advanced Controls (3 rules) - **Vault lock, reporting, restore testing**
|
|
139
|
+
- Audit Log Management (7 rules) - **Control 8 comprehensive logging coverage**
|
|
140
|
+
- Secure Configuration (5 rules) - **Control 4: session duration, security groups, VPC DNS, RDS admin, EC2 least privilege**
|
|
141
|
+
- Account Management (4 rules) - **Control 5: service account docs, admin policies, SSO, inline policies**
|
|
142
|
+
- Access Control Management (5 rules) - **Control 6: Access Analyzer, permission boundaries, SCPs, Cognito MFA, VPN MFA**
|
|
137
143
|
|
|
138
144
|
### IG3 - Advanced Security (+1 Rule) ✅
|
|
139
145
|
**100% Coverage Achieved**
|
|
@@ -141,19 +147,82 @@ aws-cis-assess assess --output-format json
|
|
|
141
147
|
- Critical for preventing application-layer attacks
|
|
142
148
|
- Required for high-security environments
|
|
143
149
|
|
|
144
|
-
### Bonus Security Rules (+
|
|
150
|
+
### Bonus Security Rules (+32 Rules) ✅
|
|
145
151
|
**Additional Value Beyond CIS Requirements**
|
|
146
152
|
- Enhanced logging security (`cloudwatch-log-group-encrypted`)
|
|
147
153
|
- Network security enhancement (`incoming-ssh-disabled`)
|
|
148
154
|
- Data streaming encryption (`kinesis-stream-encrypted`)
|
|
149
155
|
- Network access control (`restricted-incoming-traffic`)
|
|
150
156
|
- Message queue encryption (`sqs-queue-encrypted-kms`)
|
|
157
|
+
- Route 53 DNS query logging (`route53-query-logging-enabled`)
|
|
158
|
+
- Plus 26 additional security enhancements
|
|
159
|
+
- Application Load Balancer access logs (`alb-access-logs-enabled`)
|
|
160
|
+
- CloudFront distribution access logs (`cloudfront-access-logs-enabled`)
|
|
161
|
+
- WAF web ACL logging (`waf-logging-enabled`)
|
|
162
|
+
|
|
163
|
+
### 🔍 CIS Control 8: Audit Log Management (13 Rules)
|
|
164
|
+
**Comprehensive Audit Logging Coverage**
|
|
165
|
+
|
|
166
|
+
Control 8 focuses on collecting, alerting, reviewing, and retaining audit logs of events that could help detect, understand, or recover from an attack. Our implementation provides comprehensive coverage across AWS services:
|
|
167
|
+
|
|
168
|
+
**DNS Query Logging**
|
|
169
|
+
- `route53-query-logging-enabled`: Validates Route 53 hosted zones have query logging enabled to track DNS queries for security investigations
|
|
170
|
+
|
|
171
|
+
**Load Balancer & CDN Logging**
|
|
172
|
+
- `alb-access-logs-enabled`: Ensures Application Load Balancers capture access logs for traffic analysis
|
|
173
|
+
- `elb-logging-enabled`: Validates Classic Load Balancers have access logging enabled
|
|
174
|
+
- `cloudfront-access-logs-enabled`: Ensures CloudFront distributions log content delivery requests
|
|
175
|
+
|
|
176
|
+
**Log Retention & Management**
|
|
177
|
+
- `cloudwatch-log-retention-check`: Validates log groups have appropriate retention periods (minimum 90 days)
|
|
178
|
+
- `cw-loggroup-retention-period-check`: Additional log retention validation
|
|
179
|
+
|
|
180
|
+
**CloudTrail Monitoring**
|
|
181
|
+
- `cloudtrail-insights-enabled`: Enables anomaly detection for unusual API activity
|
|
182
|
+
|
|
183
|
+
**Configuration Tracking**
|
|
184
|
+
- `config-recording-all-resources`: Ensures AWS Config tracks all resource configuration changes
|
|
185
|
+
|
|
186
|
+
**Application Security Logging**
|
|
187
|
+
- `waf-logging-enabled`: Validates WAF web ACLs capture firewall events
|
|
188
|
+
- `wafv2-logging-enabled`: Ensures WAFv2 web ACLs have logging enabled
|
|
189
|
+
|
|
190
|
+
**Database & Service Logging**
|
|
191
|
+
- `rds-logging-enabled`: Validates RDS instances have appropriate logging enabled
|
|
192
|
+
- `elasticsearch-logs-to-cloudwatch`: Ensures Elasticsearch domains send logs to CloudWatch
|
|
193
|
+
- `codebuild-project-logging-enabled`: Validates CodeBuild projects capture build logs
|
|
194
|
+
- `redshift-cluster-configuration-check`: Ensures Redshift clusters have audit logging enabled
|
|
195
|
+
|
|
196
|
+
### 🔐 CIS Controls 4, 5, 6: Access & Configuration Controls (14 Rules)
|
|
197
|
+
**Comprehensive Identity, Access Management, and Secure Configuration Coverage**
|
|
198
|
+
|
|
199
|
+
These controls focus on secure configuration of enterprise assets, account management, and access control management. Our implementation provides comprehensive coverage across AWS IAM, networking, and identity services:
|
|
200
|
+
|
|
201
|
+
**Control 4 - Secure Configuration (5 rules)**
|
|
202
|
+
- `iam-max-session-duration-check`: Validates IAM role session duration does not exceed 12 hours to limit credential exposure
|
|
203
|
+
- `security-group-default-rules-check`: Ensures default security groups have no inbound or outbound rules to prevent unintended access
|
|
204
|
+
- `vpc-dns-resolution-enabled`: Validates VPC DNS settings (enableDnsHostnames and enableDnsSupport) are properly configured
|
|
205
|
+
- `rds-default-admin-check`: Ensures RDS instances don't use default admin usernames (postgres, admin, root, mysql, administrator)
|
|
206
|
+
- `ec2-instance-profile-least-privilege`: Validates EC2 instance profile permissions follow least privilege principles
|
|
207
|
+
|
|
208
|
+
**Control 5 - Account Management (4 rules)**
|
|
209
|
+
- `iam-service-account-inventory-check`: Validates service accounts have required documentation tags (Purpose, Owner, LastReviewed)
|
|
210
|
+
- `iam-admin-policy-attached-to-role-check`: Ensures administrative policies are attached to roles, not directly to users
|
|
211
|
+
- `sso-enabled-check`: Validates AWS IAM Identity Center is configured and enabled for centralized identity management
|
|
212
|
+
- `iam-user-no-inline-policies`: Ensures IAM users don't have inline policies (only managed policies or group memberships)
|
|
213
|
+
|
|
214
|
+
**Control 6 - Access Control Management (5 rules)**
|
|
215
|
+
- `iam-access-analyzer-enabled`: Validates IAM Access Analyzer is enabled in all active regions for external access detection
|
|
216
|
+
- `iam-permission-boundaries-check`: Ensures permission boundaries are configured for roles with elevated privileges
|
|
217
|
+
- `organizations-scp-enabled-check`: Validates AWS Organizations Service Control Policies are enabled and in use
|
|
218
|
+
- `cognito-user-pool-mfa-enabled`: Ensures Cognito user pools have MFA enabled for enhanced authentication security
|
|
219
|
+
- `vpn-connection-mfa-enabled`: Validates Client VPN endpoints require MFA authentication
|
|
151
220
|
|
|
152
221
|
## 🏗️ Production Architecture
|
|
153
222
|
|
|
154
223
|
### Core Components
|
|
155
224
|
- **Assessment Engine**: Orchestrates compliance evaluations across all AWS regions
|
|
156
|
-
- **Control Assessments**:
|
|
225
|
+
- **Control Assessments**: 149 individual rule implementations with robust error handling
|
|
157
226
|
- **Scoring Engine**: Calculates compliance scores and generates executive metrics
|
|
158
227
|
- **Reporting System**: Multi-format output with detailed remediation guidance
|
|
159
228
|
- **Resource Management**: Optimized for enterprise-scale deployments with memory management
|
|
@@ -249,48 +318,87 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
249
318
|
|
|
250
319
|
---
|
|
251
320
|
|
|
252
|
-
**Framework Version**: 1.0
|
|
253
|
-
**CIS Controls Coverage**:
|
|
321
|
+
**Framework Version**: 1.1.0 (in development)
|
|
322
|
+
**CIS Controls Coverage**: 151/151 rules (100%) + 9 bonus rules
|
|
254
323
|
**Production Status**: ✅ Ready for immediate enterprise deployment
|
|
255
324
|
**Last Updated**: January 2026
|
|
256
325
|
|
|
257
|
-
## 🆕 What's New in Version 1.0
|
|
258
|
-
|
|
259
|
-
###
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
**
|
|
263
|
-
1. **
|
|
264
|
-
- Ensures
|
|
265
|
-
-
|
|
266
|
-
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
-
|
|
271
|
-
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
- Checks
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
326
|
+
## 🆕 What's New in Version 1.1.0
|
|
327
|
+
|
|
328
|
+
### Access & Configuration Controls (CIS Controls 4, 5, 6)
|
|
329
|
+
Fourteen new controls added to assess identity, access management, and secure configuration:
|
|
330
|
+
|
|
331
|
+
**Control 4 - Secure Configuration (5 rules)**:
|
|
332
|
+
1. **iam-max-session-duration-check** - Validates IAM role session duration does not exceed 12 hours
|
|
333
|
+
- Ensures temporary credentials have limited exposure window
|
|
334
|
+
- Checks MaxSessionDuration property on all IAM roles
|
|
335
|
+
- Compliant if session duration ≤ 43200 seconds (12 hours)
|
|
336
|
+
|
|
337
|
+
2. **security-group-default-rules-check** - Ensures default security groups have no rules
|
|
338
|
+
- Validates default security groups are restricted (no inbound/outbound rules)
|
|
339
|
+
- Prevents unintended access through default security groups
|
|
340
|
+
- Encourages use of custom security groups with explicit rules
|
|
341
|
+
|
|
342
|
+
3. **vpc-dns-resolution-enabled** - Validates VPC DNS configuration
|
|
343
|
+
- Checks both enableDnsHostnames and enableDnsSupport are enabled
|
|
344
|
+
- Ensures proper DNS resolution within VPCs
|
|
345
|
+
- Required for many AWS services to function correctly
|
|
346
|
+
|
|
347
|
+
4. **rds-default-admin-check** - Ensures RDS instances don't use default admin usernames
|
|
348
|
+
- Detects default usernames: postgres, admin, root, mysql, administrator, sa
|
|
349
|
+
- Case-insensitive detection
|
|
350
|
+
- Reduces risk of credential guessing attacks
|
|
351
|
+
|
|
352
|
+
5. **ec2-instance-profile-least-privilege** - Validates EC2 instance profile permissions
|
|
353
|
+
- Checks for overly permissive policies (AdministratorAccess, PowerUserAccess)
|
|
354
|
+
- Detects wildcard permissions (Action: "*", Resource: "*")
|
|
355
|
+
- Ensures least privilege principle for EC2 workloads
|
|
356
|
+
|
|
357
|
+
**Control 5 - Account Management (4 rules)**:
|
|
358
|
+
6. **iam-service-account-inventory-check** - Validates service account documentation
|
|
359
|
+
- Ensures service accounts have required tags: Purpose, Owner, LastReviewed
|
|
360
|
+
- Identifies service accounts by naming convention or tags
|
|
361
|
+
- Supports compliance and access review processes
|
|
362
|
+
|
|
363
|
+
7. **iam-admin-policy-attached-to-role-check** - Ensures admin policies on roles, not users
|
|
364
|
+
- Detects administrative policies attached directly to IAM users
|
|
365
|
+
- Encourages role-based access with temporary credentials
|
|
366
|
+
- Improves audit trail and access management
|
|
367
|
+
|
|
368
|
+
8. **sso-enabled-check** - Validates AWS IAM Identity Center (SSO) is configured
|
|
369
|
+
- Checks for SSO instance existence
|
|
370
|
+
- Encourages centralized identity management
|
|
371
|
+
- Supports integration with corporate identity providers
|
|
372
|
+
|
|
373
|
+
9. **iam-user-no-inline-policies** - Ensures IAM users don't have inline policies
|
|
374
|
+
- Detects inline policies attached to users
|
|
375
|
+
- Encourages use of managed policies for reusability
|
|
376
|
+
- Simplifies policy management and auditing
|
|
377
|
+
|
|
378
|
+
**Control 6 - Access Control Management (5 rules)**:
|
|
379
|
+
10. **iam-access-analyzer-enabled** - Validates Access Analyzer in all regions
|
|
380
|
+
- Ensures IAM Access Analyzer is enabled regionally
|
|
381
|
+
- Detects resources shared with external entities
|
|
382
|
+
- Provides continuous monitoring for unintended access
|
|
383
|
+
|
|
384
|
+
11. **iam-permission-boundaries-check** - Validates permission boundaries for elevated roles
|
|
385
|
+
- Identifies roles with elevated privileges
|
|
386
|
+
- Checks for permission boundary configuration
|
|
387
|
+
- Prevents privilege escalation in delegated administration
|
|
388
|
+
|
|
389
|
+
12. **organizations-scp-enabled-check** - Validates Service Control Policies are in use
|
|
390
|
+
- Checks account is part of AWS Organizations
|
|
391
|
+
- Verifies SCPs are enabled (FeatureSet includes ALL)
|
|
392
|
+
- Ensures custom SCPs exist beyond default FullAWSAccess
|
|
393
|
+
|
|
394
|
+
13. **cognito-user-pool-mfa-enabled** - Ensures Cognito user pools have MFA
|
|
395
|
+
- Validates MfaConfiguration is 'ON' or 'OPTIONAL'
|
|
396
|
+
- Supports both SMS and TOTP authentication methods
|
|
397
|
+
- Enhances authentication security for applications
|
|
398
|
+
|
|
399
|
+
14. **vpn-connection-mfa-enabled** - Validates Client VPN endpoints require MFA
|
|
400
|
+
- Checks VPN authentication options for MFA requirement
|
|
401
|
+
- Supports Active Directory, SAML, and certificate-based MFA
|
|
402
|
+
- Ensures secure remote access to AWS resources
|
|
403
|
+
|
|
404
|
+
These controls complement the existing audit logging and backup controls by providing comprehensive coverage of identity, access management, and secure configuration practices. Total rules: 163 (149 previous + 14 new). See [Config Rule Mappings](docs/config-rule-mappings.md) for detailed documentation.
|