sraverify 0.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.
Files changed (261) hide show
  1. sraverify/__init__.py +36 -0
  2. sraverify/checks/__init__.py +56 -0
  3. sraverify/checks/accessanalyzer/SRA_IAA_1.py +188 -0
  4. sraverify/checks/accessanalyzer/SRA_IAA_2.py +162 -0
  5. sraverify/checks/accessanalyzer/SRA_IAA_3.py +260 -0
  6. sraverify/checks/accessanalyzer/SRA_IAA_4.py +207 -0
  7. sraverify/checks/accessanalyzer/__init__.py +3 -0
  8. sraverify/checks/cloudtrail/SRA-CT-1.py +220 -0
  9. sraverify/checks/cloudtrail/SRA-CT-10.py +229 -0
  10. sraverify/checks/cloudtrail/SRA-CT-11.py +242 -0
  11. sraverify/checks/cloudtrail/SRA-CT-12.py +163 -0
  12. sraverify/checks/cloudtrail/SRA-CT-13.py +279 -0
  13. sraverify/checks/cloudtrail/SRA-CT-2.py +218 -0
  14. sraverify/checks/cloudtrail/SRA-CT-3.py +196 -0
  15. sraverify/checks/cloudtrail/SRA-CT-4.py +161 -0
  16. sraverify/checks/cloudtrail/SRA-CT-5.py +200 -0
  17. sraverify/checks/cloudtrail/SRA-CT-6.py +161 -0
  18. sraverify/checks/cloudtrail/SRA-CT-7.py +194 -0
  19. sraverify/checks/cloudtrail/SRA-CT-8.py +226 -0
  20. sraverify/checks/cloudtrail/SRA-CT-9.py +226 -0
  21. sraverify/checks/cloudtrail/__init__.py +3 -0
  22. sraverify/checks/config/SRA-CONFIG-1.py +197 -0
  23. sraverify/checks/config/__init__.py +3 -0
  24. sraverify/core/__init__.py +3 -0
  25. sraverify/core/check.py +227 -0
  26. sraverify/core/logging.py +37 -0
  27. sraverify/core/session.py +47 -0
  28. sraverify/lib/__init__.py +4 -0
  29. sraverify/lib/audit_info.py +37 -0
  30. sraverify/lib/banner.py +42 -0
  31. sraverify/lib/check_loader.py +80 -0
  32. sraverify/lib/org_mgmt_checker.py +86 -0
  33. sraverify/lib/outputs.py +46 -0
  34. sraverify/lib/progress.py +75 -0
  35. sraverify/lib/regions.py +27 -0
  36. sraverify/lib/session.py +23 -0
  37. sraverify/main.py +350 -0
  38. sraverify/services/__init__.py +3 -0
  39. sraverify/services/accessanalyzer/__init__.py +15 -0
  40. sraverify/services/accessanalyzer/base.py +123 -0
  41. sraverify/services/accessanalyzer/checks/__init__.py +3 -0
  42. sraverify/services/accessanalyzer/checks/sra_accessanalyzer_01.py +82 -0
  43. sraverify/services/accessanalyzer/checks/sra_accessanalyzer_02.py +82 -0
  44. sraverify/services/accessanalyzer/checks/sra_accessanalyzer_03.py +103 -0
  45. sraverify/services/accessanalyzer/checks/sra_accessanalyzer_04.py +139 -0
  46. sraverify/services/accessanalyzer/client.py +123 -0
  47. sraverify/services/account/__init__.py +9 -0
  48. sraverify/services/account/base.py +56 -0
  49. sraverify/services/account/checks/__init__.py +1 -0
  50. sraverify/services/account/checks/sra_account_01.py +65 -0
  51. sraverify/services/account/checks/sra_account_02.py +63 -0
  52. sraverify/services/account/checks/sra_account_03.py +63 -0
  53. sraverify/services/account/client.py +51 -0
  54. sraverify/services/auditmanager/__init__.py +10 -0
  55. sraverify/services/auditmanager/base.py +72 -0
  56. sraverify/services/auditmanager/checks/__init__.py +1 -0
  57. sraverify/services/auditmanager/checks/sra_auditmanager_01.py +58 -0
  58. sraverify/services/auditmanager/checks/sra_auditmanager_02.py +80 -0
  59. sraverify/services/auditmanager/client.py +58 -0
  60. sraverify/services/cloudtrail/__init__.py +33 -0
  61. sraverify/services/cloudtrail/base.py +167 -0
  62. sraverify/services/cloudtrail/checks/__init__.py +1 -0
  63. sraverify/services/cloudtrail/checks/sra_cloudtrail_01.py +83 -0
  64. sraverify/services/cloudtrail/checks/sra_cloudtrail_02.py +99 -0
  65. sraverify/services/cloudtrail/checks/sra_cloudtrail_03.py +94 -0
  66. sraverify/services/cloudtrail/checks/sra_cloudtrail_04.py +92 -0
  67. sraverify/services/cloudtrail/checks/sra_cloudtrail_05.py +106 -0
  68. sraverify/services/cloudtrail/checks/sra_cloudtrail_06.py +93 -0
  69. sraverify/services/cloudtrail/checks/sra_cloudtrail_07.py +96 -0
  70. sraverify/services/cloudtrail/checks/sra_cloudtrail_08.py +145 -0
  71. sraverify/services/cloudtrail/checks/sra_cloudtrail_09.py +167 -0
  72. sraverify/services/cloudtrail/checks/sra_cloudtrail_10.py +162 -0
  73. sraverify/services/cloudtrail/checks/sra_cloudtrail_11.py +178 -0
  74. sraverify/services/cloudtrail/checks/sra_cloudtrail_12.py +77 -0
  75. sraverify/services/cloudtrail/checks/sra_cloudtrail_13.py +120 -0
  76. sraverify/services/cloudtrail/client.py +118 -0
  77. sraverify/services/config/__init__.py +25 -0
  78. sraverify/services/config/base.py +249 -0
  79. sraverify/services/config/checks/__init__.py +1 -0
  80. sraverify/services/config/checks/sra_config_01.py +123 -0
  81. sraverify/services/config/checks/sra_config_02.py +156 -0
  82. sraverify/services/config/checks/sra_config_03.py +149 -0
  83. sraverify/services/config/checks/sra_config_04.py +104 -0
  84. sraverify/services/config/checks/sra_config_05.py +104 -0
  85. sraverify/services/config/checks/sra_config_06.py +194 -0
  86. sraverify/services/config/checks/sra_config_07.py +162 -0
  87. sraverify/services/config/checks/sra_config_08.py +185 -0
  88. sraverify/services/config/checks/sra_config_09.py +177 -0
  89. sraverify/services/config/client.py +264 -0
  90. sraverify/services/ec2/__init__.py +8 -0
  91. sraverify/services/ec2/base.py +75 -0
  92. sraverify/services/ec2/checks/__init__.py +1 -0
  93. sraverify/services/ec2/checks/sra_ec2_01.py +83 -0
  94. sraverify/services/ec2/client.py +63 -0
  95. sraverify/services/firewallmanager/__init__.py +23 -0
  96. sraverify/services/firewallmanager/base.py +48 -0
  97. sraverify/services/firewallmanager/checks/__init__.py +1 -0
  98. sraverify/services/firewallmanager/checks/sra_firewallmanager_01.py +75 -0
  99. sraverify/services/firewallmanager/checks/sra_firewallmanager_02.py +57 -0
  100. sraverify/services/firewallmanager/checks/sra_firewallmanager_03.py +51 -0
  101. sraverify/services/firewallmanager/checks/sra_firewallmanager_04.py +51 -0
  102. sraverify/services/firewallmanager/checks/sra_firewallmanager_05.py +51 -0
  103. sraverify/services/firewallmanager/checks/sra_firewallmanager_06.py +51 -0
  104. sraverify/services/firewallmanager/checks/sra_firewallmanager_07.py +51 -0
  105. sraverify/services/firewallmanager/checks/sra_firewallmanager_08.py +61 -0
  106. sraverify/services/firewallmanager/checks/sra_firewallmanager_09.py +61 -0
  107. sraverify/services/firewallmanager/checks/sra_firewallmanager_10.py +71 -0
  108. sraverify/services/firewallmanager/client.py +40 -0
  109. sraverify/services/guardduty/__init__.py +58 -0
  110. sraverify/services/guardduty/base.py +207 -0
  111. sraverify/services/guardduty/checks/__init__.py +3 -0
  112. sraverify/services/guardduty/checks/sra_guardduty_01.py +51 -0
  113. sraverify/services/guardduty/checks/sra_guardduty_02.py +80 -0
  114. sraverify/services/guardduty/checks/sra_guardduty_03.py +77 -0
  115. sraverify/services/guardduty/checks/sra_guardduty_04.py +84 -0
  116. sraverify/services/guardduty/checks/sra_guardduty_05.py +84 -0
  117. sraverify/services/guardduty/checks/sra_guardduty_06.py +84 -0
  118. sraverify/services/guardduty/checks/sra_guardduty_07.py +85 -0
  119. sraverify/services/guardduty/checks/sra_guardduty_08.py +83 -0
  120. sraverify/services/guardduty/checks/sra_guardduty_09.py +84 -0
  121. sraverify/services/guardduty/checks/sra_guardduty_10.py +83 -0
  122. sraverify/services/guardduty/checks/sra_guardduty_11.py +93 -0
  123. sraverify/services/guardduty/checks/sra_guardduty_12.py +83 -0
  124. sraverify/services/guardduty/checks/sra_guardduty_13.py +90 -0
  125. sraverify/services/guardduty/checks/sra_guardduty_14.py +136 -0
  126. sraverify/services/guardduty/checks/sra_guardduty_15.py +94 -0
  127. sraverify/services/guardduty/checks/sra_guardduty_16.py +94 -0
  128. sraverify/services/guardduty/checks/sra_guardduty_17.py +91 -0
  129. sraverify/services/guardduty/checks/sra_guardduty_18.py +91 -0
  130. sraverify/services/guardduty/checks/sra_guardduty_19.py +91 -0
  131. sraverify/services/guardduty/checks/sra_guardduty_20.py +111 -0
  132. sraverify/services/guardduty/checks/sra_guardduty_21.py +112 -0
  133. sraverify/services/guardduty/checks/sra_guardduty_22.py +111 -0
  134. sraverify/services/guardduty/checks/sra_guardduty_23.py +154 -0
  135. sraverify/services/guardduty/checks/sra_guardduty_24.py +111 -0
  136. sraverify/services/guardduty/checks/sra_guardduty_25.py +111 -0
  137. sraverify/services/guardduty/client.py +107 -0
  138. sraverify/services/inspector/__init__.py +29 -0
  139. sraverify/services/inspector/base.py +233 -0
  140. sraverify/services/inspector/checks/__init__.py +3 -0
  141. sraverify/services/inspector/checks/sra_inspector_01.py +69 -0
  142. sraverify/services/inspector/checks/sra_inspector_02.py +68 -0
  143. sraverify/services/inspector/checks/sra_inspector_03.py +68 -0
  144. sraverify/services/inspector/checks/sra_inspector_04.py +70 -0
  145. sraverify/services/inspector/checks/sra_inspector_05.py +69 -0
  146. sraverify/services/inspector/checks/sra_inspector_06.py +115 -0
  147. sraverify/services/inspector/checks/sra_inspector_07.py +109 -0
  148. sraverify/services/inspector/checks/sra_inspector_08.py +69 -0
  149. sraverify/services/inspector/checks/sra_inspector_09.py +69 -0
  150. sraverify/services/inspector/checks/sra_inspector_10.py +69 -0
  151. sraverify/services/inspector/checks/sra_inspector_11.py +69 -0
  152. sraverify/services/inspector/client.py +99 -0
  153. sraverify/services/macie/__init__.py +27 -0
  154. sraverify/services/macie/base.py +271 -0
  155. sraverify/services/macie/checks/__init__.py +1 -0
  156. sraverify/services/macie/checks/sra_macie_01.py +100 -0
  157. sraverify/services/macie/checks/sra_macie_02.py +102 -0
  158. sraverify/services/macie/checks/sra_macie_03.py +152 -0
  159. sraverify/services/macie/checks/sra_macie_04.py +120 -0
  160. sraverify/services/macie/checks/sra_macie_05.py +85 -0
  161. sraverify/services/macie/checks/sra_macie_06.py +124 -0
  162. sraverify/services/macie/checks/sra_macie_07.py +138 -0
  163. sraverify/services/macie/checks/sra_macie_08.py +82 -0
  164. sraverify/services/macie/checks/sra_macie_09.py +103 -0
  165. sraverify/services/macie/checks/sra_macie_10.py +81 -0
  166. sraverify/services/macie/client.py +220 -0
  167. sraverify/services/s3/__init__.py +16 -0
  168. sraverify/services/s3/base.py +69 -0
  169. sraverify/services/s3/checks/__init__.py +1 -0
  170. sraverify/services/s3/checks/sra_s3_01.py +89 -0
  171. sraverify/services/s3/checks/sra_s3_02.py +89 -0
  172. sraverify/services/s3/checks/sra_s3_03.py +88 -0
  173. sraverify/services/s3/checks/sra_s3_04.py +88 -0
  174. sraverify/services/s3/client.py +52 -0
  175. sraverify/services/securityhub/__init__.py +27 -0
  176. sraverify/services/securityhub/base.py +349 -0
  177. sraverify/services/securityhub/checks/__init__.py +1 -0
  178. sraverify/services/securityhub/checks/sra_securityhub_01.py +115 -0
  179. sraverify/services/securityhub/checks/sra_securityhub_02.py +114 -0
  180. sraverify/services/securityhub/checks/sra_securityhub_03.py +136 -0
  181. sraverify/services/securityhub/checks/sra_securityhub_04.py +75 -0
  182. sraverify/services/securityhub/checks/sra_securityhub_05.py +102 -0
  183. sraverify/services/securityhub/checks/sra_securityhub_06.py +113 -0
  184. sraverify/services/securityhub/checks/sra_securityhub_07.py +121 -0
  185. sraverify/services/securityhub/checks/sra_securityhub_08.py +113 -0
  186. sraverify/services/securityhub/checks/sra_securityhub_09.py +100 -0
  187. sraverify/services/securityhub/checks/sra_securityhub_10.py +94 -0
  188. sraverify/services/securityhub/checks/sra_securityhub_11.py +73 -0
  189. sraverify/services/securityhub/client.py +249 -0
  190. sraverify/services/securityincidentresponse/__init__.py +13 -0
  191. sraverify/services/securityincidentresponse/base.py +95 -0
  192. sraverify/services/securityincidentresponse/checks/__init__.py +1 -0
  193. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_01.py +77 -0
  194. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_02.py +72 -0
  195. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_03.py +86 -0
  196. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_04.py +117 -0
  197. sraverify/services/securityincidentresponse/checks/sra_securityincidentresponse_05.py +55 -0
  198. sraverify/services/securityincidentresponse/client.py +71 -0
  199. sraverify/services/securitylake/__init__.py +39 -0
  200. sraverify/services/securitylake/base.py +461 -0
  201. sraverify/services/securitylake/checks/__init__.py +1 -0
  202. sraverify/services/securitylake/checks/sra_securitylake_01.py +98 -0
  203. sraverify/services/securitylake/checks/sra_securitylake_02.py +133 -0
  204. sraverify/services/securitylake/checks/sra_securitylake_03.py +116 -0
  205. sraverify/services/securitylake/checks/sra_securitylake_04.py +72 -0
  206. sraverify/services/securitylake/checks/sra_securitylake_05.py +116 -0
  207. sraverify/services/securitylake/checks/sra_securitylake_06.py +104 -0
  208. sraverify/services/securitylake/checks/sra_securitylake_07.py +108 -0
  209. sraverify/services/securitylake/checks/sra_securitylake_08.py +107 -0
  210. sraverify/services/securitylake/checks/sra_securitylake_09.py +107 -0
  211. sraverify/services/securitylake/checks/sra_securitylake_10.py +106 -0
  212. sraverify/services/securitylake/checks/sra_securitylake_11.py +109 -0
  213. sraverify/services/securitylake/checks/sra_securitylake_12.py +108 -0
  214. sraverify/services/securitylake/checks/sra_securitylake_13.py +108 -0
  215. sraverify/services/securitylake/checks/sra_securitylake_14.py +72 -0
  216. sraverify/services/securitylake/checks/sra_securitylake_15.py +120 -0
  217. sraverify/services/securitylake/checks/sra_securitylake_16.py +104 -0
  218. sraverify/services/securitylake/checks/sra_securitylake_17.py +103 -0
  219. sraverify/services/securitylake/client.py +247 -0
  220. sraverify/services/shield/__init__.py +33 -0
  221. sraverify/services/shield/base.py +199 -0
  222. sraverify/services/shield/checks/__init__.py +1 -0
  223. sraverify/services/shield/checks/sra_shield_01.py +68 -0
  224. sraverify/services/shield/checks/sra_shield_02.py +77 -0
  225. sraverify/services/shield/checks/sra_shield_03.py +84 -0
  226. sraverify/services/shield/checks/sra_shield_04.py +84 -0
  227. sraverify/services/shield/checks/sra_shield_05.py +84 -0
  228. sraverify/services/shield/checks/sra_shield_06.py +84 -0
  229. sraverify/services/shield/checks/sra_shield_07.py +84 -0
  230. sraverify/services/shield/checks/sra_shield_08.py +69 -0
  231. sraverify/services/shield/checks/sra_shield_09.py +86 -0
  232. sraverify/services/shield/checks/sra_shield_10.py +100 -0
  233. sraverify/services/shield/checks/sra_shield_11.py +71 -0
  234. sraverify/services/shield/checks/sra_shield_12.py +130 -0
  235. sraverify/services/shield/checks/sra_shield_13.py +112 -0
  236. sraverify/services/shield/checks/sra_shield_14.py +111 -0
  237. sraverify/services/shield/client.py +214 -0
  238. sraverify/services/waf/__init__.py +21 -0
  239. sraverify/services/waf/base.py +100 -0
  240. sraverify/services/waf/checks/__init__.py +1 -0
  241. sraverify/services/waf/checks/sra_waf_01.py +63 -0
  242. sraverify/services/waf/checks/sra_waf_02.py +82 -0
  243. sraverify/services/waf/checks/sra_waf_03.py +123 -0
  244. sraverify/services/waf/checks/sra_waf_04.py +94 -0
  245. sraverify/services/waf/checks/sra_waf_05.py +94 -0
  246. sraverify/services/waf/checks/sra_waf_06.py +91 -0
  247. sraverify/services/waf/checks/sra_waf_07.py +94 -0
  248. sraverify/services/waf/checks/sra_waf_08.py +66 -0
  249. sraverify/services/waf/checks/sra_waf_09.py +95 -0
  250. sraverify/services/waf/client.py +109 -0
  251. sraverify/utils/__init__.py +3 -0
  252. sraverify/utils/banner.py +65 -0
  253. sraverify/utils/outputs.py +57 -0
  254. sraverify/utils/progress.py +97 -0
  255. sraverify-0.1.0.dist-info/LICENSE +175 -0
  256. sraverify-0.1.0.dist-info/METADATA +516 -0
  257. sraverify-0.1.0.dist-info/NOTICE +1 -0
  258. sraverify-0.1.0.dist-info/RECORD +261 -0
  259. sraverify-0.1.0.dist-info/WHEEL +5 -0
  260. sraverify-0.1.0.dist-info/entry_points.txt +2 -0
  261. sraverify-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,120 @@
1
+ """
2
+ SRA-MACIE-04: Checks that findings are being exported to S3 in the log archive account are encrypted at rest.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.macie.base import MacieCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_MACIE_04(MacieCheck):
10
+ """Check if Macie findings exported to S3 are encrypted at rest using KMS."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-MACIE-04"
16
+ self.check_name = "Checks that findings are being exported to S3 in the log archive account are encrypted at rest"
17
+ self.description = (
18
+ "This check verifies whether all Macie findings that are being exported to a S3 bucket within the Log Archive account "
19
+ "are encrypted using KMS key. Macie findings are sensitive in natures and should be encrypted to prevent from unauthorized disclosure."
20
+ )
21
+ self.severity = "HIGH"
22
+ self.account_type = "application"
23
+ self.check_logic = "Check validates using get-classification-export-configuration that kms key exists. PASS if KMS ARN returned."
24
+ self.resource_type = "AWS::Macie::Session"
25
+
26
+ def execute(self) -> List[Dict[str, Any]]:
27
+ """
28
+ Execute the check.
29
+
30
+ Returns:
31
+ List of findings
32
+ """
33
+ findings = []
34
+
35
+ for region in self.regions:
36
+ # Get classification export configuration using the base class method with caching
37
+ export_config = self.get_classification_export_configuration(region)
38
+
39
+ # Check if the API call was successful
40
+ if not export_config:
41
+ findings.append(
42
+ self.create_finding(
43
+ status="FAIL",
44
+ region=region,
45
+ resource_id=f"macie2/{self.account_id}/{region}",
46
+ checked_value="KMS encryption for S3 bucket",
47
+ actual_value="Failed to retrieve Macie classification export configuration",
48
+ remediation="Ensure Macie is enabled and you have the necessary permissions to call the Macie GetClassificationExportConfiguration API"
49
+ )
50
+ )
51
+ continue
52
+
53
+ # Check if export configuration exists
54
+ configuration = export_config.get('configuration', {})
55
+ if not configuration:
56
+ findings.append(
57
+ self.create_finding(
58
+ status="FAIL",
59
+ region=region,
60
+ resource_id=f"macie2/{self.account_id}/{region}",
61
+ checked_value="KMS encryption for S3 bucket",
62
+ actual_value="Macie findings export configuration not found",
63
+ remediation=(
64
+ f"Configure Macie to export findings to a S3 bucket with KMS encryption in region {region} using the AWS CLI command: "
65
+ f"aws macie2 put-classification-export-configuration --s3-destination bucketName=your-bucket-name,kmsKeyArn=arn:aws:kms:{region}:{self.account_id}:key/your-key-id --region {region}"
66
+ )
67
+ )
68
+ )
69
+ continue
70
+
71
+ # Check if S3 destination exists
72
+ s3_destination = configuration.get('s3Destination', {})
73
+ if not s3_destination:
74
+ findings.append(
75
+ self.create_finding(
76
+ status="FAIL",
77
+ region=region,
78
+ resource_id=f"macie2/{self.account_id}/{region}",
79
+ checked_value="KMS encryption for S3 bucket",
80
+ actual_value="S3 destination not found in Macie findings export configuration",
81
+ remediation=(
82
+ f"Configure Macie to export findings to a S3 bucket with KMS encryption in region {region} using the AWS CLI command: "
83
+ f"aws macie2 put-classification-export-configuration --s3-destination bucketName=your-bucket-name,kmsKeyArn=arn:aws:kms:{region}:{self.account_id}:key/your-key-id --region {region}"
84
+ )
85
+ )
86
+ )
87
+ continue
88
+
89
+ # Get bucket name and KMS key ARN
90
+ bucket_name = s3_destination.get('bucketName', '')
91
+ kms_key_arn = s3_destination.get('kmsKeyArn', '')
92
+
93
+ # Check if KMS key ARN exists
94
+ if kms_key_arn:
95
+ findings.append(
96
+ self.create_finding(
97
+ status="PASS",
98
+ region=region,
99
+ resource_id=f"macie2/{self.account_id}/{region}",
100
+ checked_value="KMS encryption for S3 bucket",
101
+ actual_value=f"Macie findings exported to S3 bucket '{bucket_name}' are encrypted using KMS key '{kms_key_arn}' in region {region}",
102
+ remediation="No remediation needed"
103
+ )
104
+ )
105
+ else:
106
+ findings.append(
107
+ self.create_finding(
108
+ status="FAIL",
109
+ region=region,
110
+ resource_id=f"macie2/{self.account_id}/{region}",
111
+ checked_value="KMS encryption for S3 bucket",
112
+ actual_value=f"Macie findings exported to S3 bucket '{bucket_name}' are not encrypted using KMS in region {region}",
113
+ remediation=(
114
+ f"Configure Macie to export findings to a S3 bucket with KMS encryption in region {region} using the AWS CLI command: "
115
+ f"aws macie2 put-classification-export-configuration --s3-destination bucketName={bucket_name},kmsKeyArn=arn:aws:kms:{region}:{self.account_id}:key/your-key-id --region {region}"
116
+ )
117
+ )
118
+ )
119
+
120
+ return findings
@@ -0,0 +1,85 @@
1
+ """
2
+ SRA-MACIE-05: Macie administration for the AWS Organization has a delegated administrator.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.macie.base import MacieCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_MACIE_05(MacieCheck):
10
+ """Check if Macie administration for the AWS Organization has a delegated administrator."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-MACIE-05"
16
+ self.check_name = "Macie administration for the AWS Organization has a delegated administrator"
17
+ self.description = (
18
+ "This check verifies whether Macie service administration for the AWS Organization is delegated out to AWS Organization management account."
19
+ )
20
+ self.severity = "HIGH"
21
+ self.account_type = "management"
22
+ self.check_logic = "Check validates that a delegated administrator exists for Macie. PASS if macie2 get-administrator-account returns a valid administrator account"
23
+ self.resource_type = "AWS::Macie::Session"
24
+
25
+ def execute(self) -> List[Dict[str, Any]]:
26
+ """
27
+ Execute the check.
28
+
29
+ Returns:
30
+ List of findings
31
+ """
32
+ findings = []
33
+
34
+ for region in self.regions:
35
+ # Get Macie administrator account using the base class method with caching
36
+ admin_account = self.get_macie_administrator_account(region)
37
+
38
+ # Check if the API call was successful and returned an administrator
39
+ if not admin_account or 'administrator' not in admin_account:
40
+ findings.append(
41
+ self.create_finding(
42
+ status="FAIL",
43
+ region=region,
44
+ resource_id=f"macie2/{self.account_id}/{region}",
45
+ checked_value="Administrator account for Macie",
46
+ actual_value=f"No administrator account found for Macie in region {region}",
47
+ remediation=(
48
+ f"Enable Macie and register a delegated administrator for Macie in region {region} using the AWS CLI command: "
49
+ f"aws macie2 enable-organization-admin-account --admin-account-id your-audit-account-id --region {region}"
50
+ )
51
+ )
52
+ )
53
+ continue
54
+
55
+ # Check if administrator account exists and is enabled
56
+ admin_account_id = admin_account.get('administrator', {}).get('accountId')
57
+ relation_status = admin_account.get('administrator', {}).get('relationshipStatus')
58
+
59
+ if admin_account_id and relation_status == 'Enabled':
60
+ findings.append(
61
+ self.create_finding(
62
+ status="PASS",
63
+ region=region,
64
+ resource_id=f"macie2/{self.account_id}/administrator/{admin_account_id}/{region}",
65
+ checked_value="Administrator account for Macie",
66
+ actual_value=f"Macie has an administrator account: {admin_account_id} with status: {relation_status} in region {region}",
67
+ remediation="No remediation needed"
68
+ )
69
+ )
70
+ else:
71
+ findings.append(
72
+ self.create_finding(
73
+ status="FAIL",
74
+ region=region,
75
+ resource_id=f"macie2/{self.account_id}/{region}",
76
+ checked_value="Administrator account for Macie",
77
+ actual_value=f"Administrator account found for Macie in region {region} but status is not Enabled: {relation_status}",
78
+ remediation=(
79
+ f"Enable Macie and register a delegated administrator for Macie in region {region} using the AWS CLI command: "
80
+ f"aws macie2 enable-organization-admin-account --admin-account-id your-audit-account-id --region {region}"
81
+ )
82
+ )
83
+ )
84
+
85
+ return findings
@@ -0,0 +1,124 @@
1
+ """
2
+ SRA-MACIE-06: Macie delegated admin account is the Security Tooling (Audit) account.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.macie.base import MacieCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_MACIE_06(MacieCheck):
10
+ """Check if Macie delegated admin account is the Security Tooling (Audit) account."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-MACIE-06"
16
+ self.check_name = "Macie delegated admin account is the Security Tooling (Audit) account"
17
+ self.description = (
18
+ "This check verifies whether Macie delegated admin account is the audit account of your AWS organization. "
19
+ "audit account is dedicated to operating security services, monitoring AWS accounts, and automating security "
20
+ "alerting and response. Macie provides sensitive data discovery service."
21
+ )
22
+ self.severity = "HIGH"
23
+ self.account_type = "management"
24
+ self.check_logic = "Check validates that the administrator account for Macie is the --audit-account. Check PASS if macie2 get-administrator-account account ID == audit account passed via —audit-account flag"
25
+ self.resource_type = "AWS::Macie::Session"
26
+
27
+ def execute(self) -> List[Dict[str, Any]]:
28
+ """
29
+ Execute the check.
30
+
31
+ Returns:
32
+ List of findings
33
+ """
34
+ findings = []
35
+
36
+ # Check if audit accounts are provided
37
+ audit_accounts = []
38
+ if hasattr(self, '_audit_accounts') and self._audit_accounts:
39
+ audit_accounts = self._audit_accounts
40
+
41
+ if not audit_accounts:
42
+ for region in self.regions:
43
+ findings.append(
44
+ self.create_finding(
45
+ status="FAIL",
46
+ region=region,
47
+ resource_id=f"macie2/{self.account_id}/{region}",
48
+ checked_value="Administrator account is Audit account",
49
+ actual_value="Audit Account ID not provided",
50
+ remediation="Provide the Audit account IDs using --audit-account flag"
51
+ )
52
+ )
53
+ return findings
54
+
55
+ for region in self.regions:
56
+ # Get Macie administrator account using the base class method with caching
57
+ admin_account = self.get_macie_administrator_account(region)
58
+
59
+ # Check if the API call was successful and returned an administrator
60
+ if not admin_account or 'administrator' not in admin_account:
61
+ findings.append(
62
+ self.create_finding(
63
+ status="FAIL",
64
+ region=region,
65
+ resource_id=f"macie2/{self.account_id}/{region}",
66
+ checked_value="Administrator account is Audit account",
67
+ actual_value=f"No administrator account found for Macie in region {region}",
68
+ remediation=(
69
+ f"Enable Macie and register the Audit account ({', '.join(audit_accounts)}) as a delegated administrator for Macie in region {region} using the AWS CLI command: "
70
+ f"aws macie2 enable-organization-admin-account --admin-account-id {audit_accounts[0]} --region {region}"
71
+ )
72
+ )
73
+ )
74
+ continue
75
+
76
+ # Check if administrator account exists and is enabled
77
+ admin_account_id = admin_account.get('administrator', {}).get('accountId')
78
+ relation_status = admin_account.get('administrator', {}).get('relationshipStatus')
79
+
80
+ if not admin_account_id or relation_status != 'Enabled':
81
+ findings.append(
82
+ self.create_finding(
83
+ status="FAIL",
84
+ region=region,
85
+ resource_id=f"macie2/{self.account_id}/{region}",
86
+ checked_value="Administrator account is Audit account",
87
+ actual_value=f"Administrator account found for Macie in region {region} but status is not Enabled: {relation_status}",
88
+ remediation=(
89
+ f"Enable Macie and register the Audit account ({', '.join(audit_accounts)}) as a delegated administrator for Macie in region {region} using the AWS CLI command: "
90
+ f"aws macie2 enable-organization-admin-account --admin-account-id {audit_accounts[0]} --region {region}"
91
+ )
92
+ )
93
+ )
94
+ continue
95
+
96
+ # Check if administrator account is the Audit account
97
+ if admin_account_id in audit_accounts:
98
+ findings.append(
99
+ self.create_finding(
100
+ status="PASS",
101
+ region=region,
102
+ resource_id=f"macie2/{self.account_id}/administrator/{admin_account_id}/{region}",
103
+ checked_value="Administrator account is Audit account",
104
+ actual_value=f"Macie administrator account {admin_account_id} is one of the specified Audit accounts in region {region}",
105
+ remediation="No remediation needed"
106
+ )
107
+ )
108
+ else:
109
+ findings.append(
110
+ self.create_finding(
111
+ status="FAIL",
112
+ region=region,
113
+ resource_id=f"macie2/{self.account_id}/administrator/{admin_account_id}/{region}",
114
+ checked_value="Administrator account is Audit account",
115
+ actual_value=f"Macie administrator account {admin_account_id} is not one of the specified Audit accounts ({', '.join(audit_accounts)}) in region {region}",
116
+ remediation=(
117
+ f"Disable the current administrator and enable the Audit account ({', '.join(audit_accounts)}) as a delegated administrator for Macie in region {region} using the AWS CLI commands: "
118
+ f"aws macie2 disable-organization-admin-account --admin-account-id {admin_account_id} --region {region} && "
119
+ f"aws macie2 enable-organization-admin-account --admin-account-id {audit_accounts[0]} --region {region}"
120
+ )
121
+ )
122
+ )
123
+
124
+ return findings
@@ -0,0 +1,138 @@
1
+ """
2
+ SRA-MACIE-07: All active member accounts have relationship with delegated admin account enabled.
3
+ """
4
+ from typing import List, Dict, Any, Set
5
+ from sraverify.services.macie.base import MacieCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_MACIE_07(MacieCheck):
10
+ """Check if all active member accounts have relationship with delegated admin account enabled."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-MACIE-07"
16
+ self.check_name = "All active member accounts have relationship with delegated admin account enabled"
17
+ self.description = (
18
+ "This check verifies whether all active members accounts of the AWS Organization have Macie member relationship "
19
+ "enabled with Macie delegated admin account. Amazon Macie is a data security service that discovers sensitive data "
20
+ "by using machine learning and pattern matching, provides visibility into data security risks, and enables automated "
21
+ "protection against those risks."
22
+ )
23
+ self.severity = "HIGH"
24
+ self.account_type = "audit"
25
+ self.check_logic = "Check runs organizations list-accounts AND macie2 list-members. Check PASS if macie2 list-members includes all members of the AWS organization minus the audit account."
26
+ self.resource_type = "AWS::Macie::Session"
27
+
28
+ def execute(self) -> List[Dict[str, Any]]:
29
+ """
30
+ Execute the check.
31
+
32
+ Returns:
33
+ List of findings
34
+ """
35
+ findings = []
36
+
37
+ # Check if audit accounts are provided
38
+ audit_accounts = []
39
+ if hasattr(self, '_audit_accounts') and self._audit_accounts:
40
+ audit_accounts = self._audit_accounts
41
+
42
+ for region in self.regions:
43
+ # Get organization members using the base class method with caching
44
+ org_members = self.get_organization_members(region)
45
+
46
+ # Check if the API call was successful
47
+ if not org_members:
48
+ findings.append(
49
+ self.create_finding(
50
+ status="FAIL",
51
+ region=region,
52
+ resource_id=f"organization/{self.account_id}",
53
+ checked_value="All active member accounts have Macie relationship enabled",
54
+ actual_value="Failed to retrieve AWS Organization members",
55
+ remediation="Ensure you have the necessary permissions to call the Organizations ListAccounts API"
56
+ )
57
+ )
58
+ continue
59
+
60
+ # Get Macie members using the base class method with caching
61
+ macie_members = self.get_macie_members(region)
62
+
63
+ # Check if the API call was successful
64
+ if macie_members is None:
65
+ findings.append(
66
+ self.create_finding(
67
+ status="FAIL",
68
+ region=region,
69
+ resource_id=f"macie2/{self.account_id}",
70
+ checked_value="All active member accounts have Macie relationship enabled",
71
+ actual_value="Failed to retrieve Macie members",
72
+ remediation="Ensure you have the necessary permissions to call the Macie ListMembers API"
73
+ )
74
+ )
75
+ continue
76
+
77
+ # Filter active organization members
78
+ active_org_members = [
79
+ member for member in org_members
80
+ if member.get('Status') == 'ACTIVE'
81
+ ]
82
+
83
+ # Create sets of account IDs for comparison
84
+ active_org_account_ids = {member.get('Id') for member in active_org_members}
85
+ macie_member_account_ids = {member.get('accountId') for member in macie_members}
86
+
87
+ # Remove the current account (delegated admin) from the set of accounts to check
88
+ if self.account_id in active_org_account_ids:
89
+ active_org_account_ids.remove(self.account_id)
90
+
91
+ # Remove audit accounts from the set of accounts to check if provided
92
+ for audit_account in audit_accounts:
93
+ if audit_account in active_org_account_ids:
94
+ active_org_account_ids.remove(audit_account)
95
+
96
+ # Find accounts that are not Macie members
97
+ missing_accounts = active_org_account_ids - macie_member_account_ids
98
+
99
+ # Find accounts that are Macie members but not enabled
100
+ not_enabled_accounts = []
101
+ for member in macie_members:
102
+ if member.get('accountId') in active_org_account_ids and member.get('relationshipStatus') != 'Enabled':
103
+ not_enabled_accounts.append(member.get('accountId'))
104
+
105
+ if not missing_accounts and not not_enabled_accounts:
106
+ findings.append(
107
+ self.create_finding(
108
+ status="PASS",
109
+ region=region,
110
+ resource_id=f"macie2/{self.account_id}/{region}",
111
+ checked_value="All active member accounts have Macie relationship enabled",
112
+ actual_value=f"All {len(active_org_account_ids)} active member accounts have Macie relationship enabled in region {region}",
113
+ remediation="No remediation needed"
114
+ )
115
+ )
116
+ else:
117
+ missing_accounts_str = ", ".join(missing_accounts) if missing_accounts else "None"
118
+ not_enabled_accounts_str = ", ".join(not_enabled_accounts) if not_enabled_accounts else "None"
119
+
120
+ findings.append(
121
+ self.create_finding(
122
+ status="FAIL",
123
+ region=region,
124
+ resource_id=f"macie2/{self.account_id}/{region}",
125
+ checked_value="All active member accounts have Macie relationship enabled",
126
+ actual_value=(
127
+ f"Not all active member accounts have Macie relationship enabled in region {region}. "
128
+ f"Missing accounts: {missing_accounts_str}. "
129
+ f"Accounts with relationship not enabled: {not_enabled_accounts_str}."
130
+ ),
131
+ remediation=(
132
+ f"Enable Macie for all member accounts in region {region} using the AWS CLI command: "
133
+ f"aws macie2 create-member --account account_details --region {region}"
134
+ )
135
+ )
136
+ )
137
+
138
+ return findings
@@ -0,0 +1,82 @@
1
+ """
2
+ SRA-MACIE-08: Macie AutoEnable configuration is enabled for new member accounts.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.macie.base import MacieCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_MACIE_08(MacieCheck):
10
+ """Check if Macie AutoEnable configuration is enabled for new member accounts."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-MACIE-08"
16
+ self.check_name = "Macie AutoEnable configuration is enabled for new member accounts"
17
+ self.description = (
18
+ "This check verifies whether auto-enablement configuration for Macie is enabled for member accounts of the AWS Organization. "
19
+ "This ensures that all existing and new member accounts will have Macie monitoring."
20
+ )
21
+ self.severity = "MEDIUM"
22
+ self.account_type = "audit"
23
+ self.check_logic = "Check runs macie2 describe-organization-configuration. PASS if autoenable = True"
24
+ self.resource_type = "AWS::Macie::Session"
25
+
26
+ def execute(self) -> List[Dict[str, Any]]:
27
+ """
28
+ Execute the check.
29
+
30
+ Returns:
31
+ List of findings
32
+ """
33
+ findings = []
34
+
35
+ for region in self.regions:
36
+ # Get organization configuration using the base class method with caching
37
+ org_config = self.get_organization_configuration(region)
38
+
39
+ # Check if the API call was successful
40
+ if not org_config:
41
+ findings.append(
42
+ self.create_finding(
43
+ status="FAIL",
44
+ region=region,
45
+ resource_id=f"macie2/{self.account_id}/{region}",
46
+ checked_value="autoEnable: true",
47
+ actual_value="Failed to retrieve Macie organization configuration",
48
+ remediation="Ensure Macie is enabled and you have the necessary permissions to call the Macie DescribeOrganizationConfiguration API"
49
+ )
50
+ )
51
+ continue
52
+
53
+ # Check if auto-enable is enabled
54
+ auto_enable = org_config.get('autoEnable', False)
55
+
56
+ if auto_enable:
57
+ findings.append(
58
+ self.create_finding(
59
+ status="PASS",
60
+ region=region,
61
+ resource_id=f"macie2/{self.account_id}/{region}",
62
+ checked_value="autoEnable: true",
63
+ actual_value=f"Macie AutoEnable configuration is enabled for new member accounts in region {region}",
64
+ remediation="No remediation needed"
65
+ )
66
+ )
67
+ else:
68
+ findings.append(
69
+ self.create_finding(
70
+ status="FAIL",
71
+ region=region,
72
+ resource_id=f"macie2/{self.account_id}/{region}",
73
+ checked_value="autoEnable: true",
74
+ actual_value=f"Macie AutoEnable configuration is not enabled for new member accounts in region {region}",
75
+ remediation=(
76
+ f"Enable Macie AutoEnable configuration for new member accounts in region {region} using the AWS CLI command: "
77
+ f"aws macie2 update-organization-configuration --auto-enable --region {region}"
78
+ )
79
+ )
80
+ )
81
+
82
+ return findings
@@ -0,0 +1,103 @@
1
+ """
2
+ SRA-MACIE-09: All active member accounts have Macie enabled.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.macie.base import MacieCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_MACIE_09(MacieCheck):
10
+ """Check if all active member accounts have Macie enabled."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-MACIE-09"
16
+ self.check_name = "All active member accounts have Macie enabled"
17
+ self.description = (
18
+ "This check verifies whether all active members accounts of the AWS Organization have Macie enabled. "
19
+ "Amazon Macie is a data security service that discovers sensitive data by using machine learning and pattern matching, "
20
+ "provides visibility into data security risks, and enables automated protection against those risks."
21
+ )
22
+ self.severity = "HIGH"
23
+ self.account_type = "audit"
24
+ self.check_logic = "Check runs macie2 list-members, PASS if 'relationshipStatus': 'Enabled' for all members"
25
+ self.resource_type = "AWS::Macie::Session"
26
+
27
+ def execute(self) -> List[Dict[str, Any]]:
28
+ """
29
+ Execute the check.
30
+
31
+ Returns:
32
+ List of findings
33
+ """
34
+ findings = []
35
+
36
+ for region in self.regions:
37
+ # Get Macie members using the base class method with caching
38
+ macie_members = self.get_macie_members(region)
39
+
40
+ # Check if the API call was successful
41
+ if macie_members is None:
42
+ findings.append(
43
+ self.create_finding(
44
+ status="FAIL",
45
+ region=region,
46
+ resource_id=f"macie2/{self.account_id}/{region}",
47
+ checked_value="All member accounts have Macie enabled",
48
+ actual_value="Failed to retrieve Macie members",
49
+ remediation="Ensure you have the necessary permissions to call the Macie ListMembers API"
50
+ )
51
+ )
52
+ continue
53
+
54
+ # Check if there are any members
55
+ if not macie_members:
56
+ findings.append(
57
+ self.create_finding(
58
+ status="FAIL",
59
+ region=region,
60
+ resource_id=f"macie2/{self.account_id}/{region}",
61
+ checked_value="All member accounts have Macie enabled",
62
+ actual_value="No Macie members found",
63
+ remediation=f"Enable Macie for member accounts in region {region} using the AWS CLI command: aws macie2 create-member --account account_details --region {region}"
64
+ )
65
+ )
66
+ continue
67
+
68
+ # Check if all members have Macie enabled
69
+ disabled_members = [
70
+ member for member in macie_members
71
+ if member.get('relationshipStatus') != 'Enabled'
72
+ ]
73
+
74
+ if not disabled_members:
75
+ findings.append(
76
+ self.create_finding(
77
+ status="PASS",
78
+ region=region,
79
+ resource_id=f"macie2/{self.account_id}/{region}",
80
+ checked_value="All member accounts have Macie enabled",
81
+ actual_value=f"All {len(macie_members)} member accounts have Macie enabled in region {region}",
82
+ remediation="No remediation needed"
83
+ )
84
+ )
85
+ else:
86
+ disabled_account_ids = [member.get('accountId', 'Unknown') for member in disabled_members]
87
+ disabled_accounts_str = ", ".join(disabled_account_ids)
88
+
89
+ findings.append(
90
+ self.create_finding(
91
+ status="FAIL",
92
+ region=region,
93
+ resource_id=f"macie2/{self.account_id}/{region}",
94
+ checked_value="All member accounts have Macie enabled",
95
+ actual_value=f"{len(disabled_members)} out of {len(macie_members)} member accounts do not have Macie enabled in region {region}: {disabled_accounts_str}",
96
+ remediation=(
97
+ f"Enable Macie for all member accounts in region {region} using the AWS CLI command: "
98
+ f"aws macie2 enable-macie --region {region}"
99
+ )
100
+ )
101
+ )
102
+
103
+ return findings