aws-cis-controls-assessment 1.0.6__tar.gz → 1.0.8__tar.gz

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 (87) hide show
  1. {aws_cis_controls_assessment-1.0.6/aws_cis_controls_assessment.egg-info → aws_cis_controls_assessment-1.0.8}/PKG-INFO +2 -1
  2. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/README.md +1 -0
  3. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/__init__.py +1 -1
  4. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_advanced_security.py +2 -2
  5. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_critical_security.py +33 -36
  6. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/reporters/html_reporter.py +547 -38
  7. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8/aws_cis_controls_assessment.egg-info}/PKG-INFO +2 -1
  8. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_controls_assessment.egg-info/SOURCES.txt +1 -0
  9. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/docs/README.md +1 -0
  10. aws_cis_controls_assessment-1.0.8/docs/html-report-improvements.md +422 -0
  11. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/docs/installation.md +78 -27
  12. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/docs/user-guide.md +7 -1
  13. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/LICENSE +0 -0
  14. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/MANIFEST.in +0 -0
  15. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/cli/__init__.py +0 -0
  16. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/cli/examples.py +0 -0
  17. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/cli/main.py +0 -0
  18. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/cli/utils.py +0 -0
  19. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/config/__init__.py +0 -0
  20. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/config/config_loader.py +0 -0
  21. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/config/rules/cis_controls_ig1.yaml +0 -0
  22. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/config/rules/cis_controls_ig2.yaml +0 -0
  23. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/config/rules/cis_controls_ig3.yaml +0 -0
  24. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/__init__.py +0 -0
  25. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/base_control.py +0 -0
  26. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/__init__.py +0 -0
  27. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_1_1.py +0 -0
  28. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_2_2.py +0 -0
  29. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_3_3.py +0 -0
  30. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_3_4.py +0 -0
  31. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_4_1.py +0 -0
  32. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_access_keys.py +0 -0
  33. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_backup_recovery.py +0 -0
  34. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_cloudtrail_logging.py +0 -0
  35. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_data_protection.py +0 -0
  36. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_iam_advanced.py +0 -0
  37. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_iam_governance.py +0 -0
  38. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_iam_policies.py +0 -0
  39. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_instance_optimization.py +0 -0
  40. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_network_enhancements.py +0 -0
  41. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_network_security.py +0 -0
  42. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_s3_enhancements.py +0 -0
  43. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_s3_security.py +0 -0
  44. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig1/control_vpc_security.py +0 -0
  45. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/__init__.py +0 -0
  46. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_3_10.py +0 -0
  47. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_3_11.py +0 -0
  48. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_5_2.py +0 -0
  49. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_advanced_encryption.py +0 -0
  50. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_codebuild_security.py +0 -0
  51. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_encryption_rest.py +0 -0
  52. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_encryption_transit.py +0 -0
  53. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_network_ha.py +0 -0
  54. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_remaining_encryption.py +0 -0
  55. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_remaining_rules.py +0 -0
  56. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig2/control_service_logging.py +0 -0
  57. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig3/__init__.py +0 -0
  58. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig3/control_12_8.py +0 -0
  59. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig3/control_13_1.py +0 -0
  60. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig3/control_3_14.py +0 -0
  61. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/controls/ig3/control_7_1.py +0 -0
  62. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/core/__init__.py +0 -0
  63. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/core/accuracy_validator.py +0 -0
  64. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/core/assessment_engine.py +0 -0
  65. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/core/audit_trail.py +0 -0
  66. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/core/aws_client_factory.py +0 -0
  67. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/core/error_handler.py +0 -0
  68. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/core/models.py +0 -0
  69. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/core/scoring_engine.py +0 -0
  70. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/reporters/__init__.py +0 -0
  71. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/reporters/base_reporter.py +0 -0
  72. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/reporters/csv_reporter.py +0 -0
  73. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_assessment/reporters/json_reporter.py +0 -0
  74. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_controls_assessment.egg-info/dependency_links.txt +0 -0
  75. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_controls_assessment.egg-info/entry_points.txt +0 -0
  76. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_controls_assessment.egg-info/requires.txt +0 -0
  77. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/aws_cis_controls_assessment.egg-info/top_level.txt +0 -0
  78. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/deprecation-package/aws_cis_assessment_deprecated/__init__.py +0 -0
  79. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/docs/assessment-logic.md +0 -0
  80. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/docs/cli-reference.md +0 -0
  81. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/docs/config-rule-mappings.md +0 -0
  82. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/docs/developer-guide.md +0 -0
  83. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/docs/troubleshooting.md +0 -0
  84. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/pyproject.toml +0 -0
  85. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/pytest.ini +0 -0
  86. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/requirements.txt +0 -0
  87. {aws_cis_controls_assessment-1.0.6 → aws_cis_controls_assessment-1.0.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aws-cis-controls-assessment
3
- Version: 1.0.6
3
+ Version: 1.0.8
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>
@@ -214,6 +214,7 @@ aws-cis-assess assess --output-format json
214
214
  ### Technical Documentation
215
215
  - **[Assessment Logic](docs/assessment-logic.md)**: How compliance assessments work
216
216
  - **[Config Rule Mappings](docs/config-rule-mappings.md)**: CIS Controls to AWS Config rule mappings
217
+ - **[HTML Report Improvements](docs/html-report-improvements.md)**: Enhanced HTML report features and customization
217
218
 
218
219
  ## 🤝 Support & Community
219
220
 
@@ -157,6 +157,7 @@ aws-cis-assess assess --output-format json
157
157
  ### Technical Documentation
158
158
  - **[Assessment Logic](docs/assessment-logic.md)**: How compliance assessments work
159
159
  - **[Config Rule Mappings](docs/config-rule-mappings.md)**: CIS Controls to AWS Config rule mappings
160
+ - **[HTML Report Improvements](docs/html-report-improvements.md)**: Enhanced HTML report features and customization
160
161
 
161
162
  ## 🤝 Support & Community
162
163
 
@@ -6,6 +6,6 @@ CIS Controls Implementation Groups (IG1, IG2, IG3). Implements 145 comprehensive
6
6
  across all implementation groups for complete security compliance assessment.
7
7
  """
8
8
 
9
- __version__ = "1.0.6"
9
+ __version__ = "1.0.8"
10
10
  __author__ = "AWS CIS Assessment Team"
11
11
  __description__ = "Production-ready AWS CIS Controls Compliance Assessment Framework"
@@ -68,8 +68,8 @@ class EC2ManagedInstanceAssociationComplianceStatusCheckAssessment(BaseConfigRul
68
68
  # Get association compliance status
69
69
  try:
70
70
  compliance_response = ssm_client.list_compliance_items(
71
- ResourceId=instance_id,
72
- ResourceType='ManagedInstance'
71
+ ResourceIds=[instance_id],
72
+ ResourceTypes=['ManagedInstance']
73
73
  )
74
74
 
75
75
  compliance_items = compliance_response.get('ComplianceItems', [])
@@ -32,24 +32,31 @@ class RootAccountHardwareMFAEnabledAssessment(BaseConfigRuleAssessment):
32
32
  try:
33
33
  iam_client = aws_factory.get_client('iam', region)
34
34
 
35
- # Get account summary which includes MFA device count
35
+ # Get account summary which includes MFA device count for root
36
36
  account_summary = iam_client.get_account_summary()
37
+ summary_map = account_summary.get('SummaryMap', {})
37
38
 
38
- # List MFA devices for root account (empty user name for root)
39
- mfa_devices = iam_client.list_mfa_devices()
40
-
41
- # Get virtual MFA devices to differentiate from hardware
42
- virtual_mfa_devices = iam_client.list_virtual_mfa_devices()
39
+ # Get virtual MFA devices to check if root has hardware MFA
40
+ # Virtual MFA devices can be listed without specifying a user
41
+ try:
42
+ virtual_mfa_devices = iam_client.list_virtual_mfa_devices()
43
+ virtual_mfa_list = virtual_mfa_devices.get('VirtualMFADevices', [])
44
+ except ClientError as e:
45
+ logger.warning(f"Could not list virtual MFA devices: {e}")
46
+ virtual_mfa_list = []
43
47
 
44
48
  return [{
45
49
  'account_id': aws_factory.account_id,
46
- 'account_summary': account_summary.get('SummaryMap', {}),
47
- 'mfa_devices': mfa_devices.get('MFADevices', []),
48
- 'virtual_mfa_devices': virtual_mfa_devices.get('VirtualMFADevices', [])
50
+ 'account_summary': summary_map,
51
+ 'virtual_mfa_devices': virtual_mfa_list
49
52
  }]
50
53
 
51
54
  except ClientError as e:
52
- logger.error(f"Error getting root account MFA configuration: {e}")
55
+ error_code = e.response.get('Error', {}).get('Code', '')
56
+ if error_code in ['AccessDenied', 'UnauthorizedOperation']:
57
+ logger.warning(f"Insufficient permissions to check root account MFA: {e}")
58
+ else:
59
+ logger.error(f"Error getting root account MFA configuration: {e}")
53
60
  return []
54
61
  except Exception as e:
55
62
  logger.error(f"Unexpected error in root account MFA check: {e}")
@@ -59,15 +66,15 @@ class RootAccountHardwareMFAEnabledAssessment(BaseConfigRuleAssessment):
59
66
  """Evaluate root account hardware MFA compliance."""
60
67
  try:
61
68
  account_summary = resource.get('account_summary', {})
62
- mfa_devices = resource.get('mfa_devices', [])
63
69
  virtual_mfa_devices = resource.get('virtual_mfa_devices', [])
70
+ account_id = resource.get('account_id', 'unknown')
64
71
 
65
72
  # Check if root account has any MFA devices
66
73
  account_mfa_enabled = account_summary.get('AccountMFAEnabled', 0)
67
74
 
68
75
  if account_mfa_enabled == 0:
69
76
  return ComplianceResult(
70
- resource_id=resource['account_id'],
77
+ resource_id=account_id,
71
78
  resource_type="AWS::IAM::Root",
72
79
  compliance_status=ComplianceStatus.NON_COMPLIANT,
73
80
  evaluation_reason="Root account does not have MFA enabled",
@@ -75,42 +82,32 @@ class RootAccountHardwareMFAEnabledAssessment(BaseConfigRuleAssessment):
75
82
  region=region
76
83
  )
77
84
 
78
- # Check if there are any MFA devices for root (empty UserName indicates root)
79
- root_mfa_devices = [device for device in mfa_devices if not device.get('UserName')]
80
-
81
- if not root_mfa_devices:
82
- return ComplianceResult(
83
- resource_id=resource['account_id'],
84
- resource_type="AWS::IAM::Root",
85
- compliance_status=ComplianceStatus.NON_COMPLIANT,
86
- evaluation_reason="Root account MFA is enabled but no MFA devices found",
87
- config_rule_name=self.rule_name,
88
- region=region
89
- )
90
-
91
- # Check if any of the root MFA devices are hardware (not virtual)
92
- virtual_mfa_serial_numbers = {device.get('SerialNumber') for device in virtual_mfa_devices}
93
-
94
- hardware_mfa_devices = [
95
- device for device in root_mfa_devices
96
- if device.get('SerialNumber') not in virtual_mfa_serial_numbers
85
+ # Check if root has a virtual MFA device
86
+ # Virtual MFA devices for root have SerialNumber like: arn:aws:iam::ACCOUNT_ID:mfa/root-account-mfa-device
87
+ root_virtual_mfa = [
88
+ device for device in virtual_mfa_devices
89
+ if 'root-account-mfa-device' in device.get('SerialNumber', '').lower()
90
+ or device.get('User', {}).get('Arn', '').endswith(':root')
97
91
  ]
98
92
 
99
- if not hardware_mfa_devices:
93
+ if root_virtual_mfa:
100
94
  return ComplianceResult(
101
- resource_id=resource['account_id'],
95
+ resource_id=account_id,
102
96
  resource_type="AWS::IAM::Root",
103
97
  compliance_status=ComplianceStatus.NON_COMPLIANT,
104
- evaluation_reason="Root account only has virtual MFA devices, hardware MFA required",
98
+ evaluation_reason="Root account has virtual MFA enabled, hardware MFA required for enhanced security",
105
99
  config_rule_name=self.rule_name,
106
100
  region=region
107
101
  )
108
102
 
103
+ # If MFA is enabled but no virtual MFA found, assume hardware MFA
104
+ # Note: We cannot definitively verify hardware MFA without root credentials,
105
+ # but if AccountMFAEnabled=1 and no virtual MFA exists, it's likely hardware
109
106
  return ComplianceResult(
110
- resource_id=resource['account_id'],
107
+ resource_id=account_id,
111
108
  resource_type="AWS::IAM::Root",
112
109
  compliance_status=ComplianceStatus.COMPLIANT,
113
- evaluation_reason=f"Root account has {len(hardware_mfa_devices)} hardware MFA device(s) enabled",
110
+ evaluation_reason="Root account has MFA enabled (likely hardware MFA - no virtual MFA detected)",
114
111
  config_rule_name=self.rule_name,
115
112
  region=region
116
113
  )