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,99 @@
1
+ """
2
+ SRA-CLOUDTRAIL-02: Organization CloudTrail KMS Encryption.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.cloudtrail.base import CloudTrailCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_CLOUDTRAIL_02(CloudTrailCheck):
10
+ """Check if organization trails are encrypted with KMS."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-CLOUDTRAIL-02"
16
+ self.check_name = "Organization trail is encrypted with KMS"
17
+ self.account_type = "management"
18
+ self.severity = "MEDIUM"
19
+ self.description = (
20
+ "This check verifies that your organization trail is encrypted with a KMS key. "
21
+ "Log files delivered by CloudTrail to your bucket should be encrypted by using SSE-KMS. "
22
+ "This is selected by default in the console but can be altered by users. With SSE-KMS "
23
+ "you create and manage the KMS key yourself with the ability to manage permissions on "
24
+ "who can use the key. For a user to read log files they must have read permissions to "
25
+ "the bucket and have permissions that allows decrypt permission on the key applied by "
26
+ "the KMS key policy."
27
+ )
28
+ self.check_logic = (
29
+ "Check if organization trails have KmsKeyId configured."
30
+ )
31
+
32
+ def execute(self) -> List[Dict[str, Any]]:
33
+ """
34
+ Execute the check.
35
+
36
+ Returns:
37
+ List of findings
38
+ """
39
+ findings = []
40
+
41
+ # Get organization trails
42
+ org_trails = self.get_organization_trails()
43
+
44
+ if not org_trails:
45
+ findings.append(
46
+ self.create_finding(
47
+ status="FAIL",
48
+ region="global",
49
+ resource_id=f"organization/{self.account_id}",
50
+ checked_value="KmsKeyId: not empty",
51
+ actual_value="No organization trails found",
52
+ remediation=(
53
+ "Create an organization trail with KMS encryption in the management account using the AWS CLI command: "
54
+ f"aws cloudtrail create-trail --name org-trail --is-organization-trail --s3-bucket-name cloudtrail-logs-{self.account_id} "
55
+ f"--kms-key-id arn:aws:kms:{self.regions[0] if self.regions else 'us-east-1'}:{self.account_id}:key/YOUR_KMS_KEY_ID "
56
+ f"--is-multi-region-trail --region {self.regions[0] if self.regions else 'us-east-1'}"
57
+ )
58
+ )
59
+ )
60
+ return findings
61
+
62
+ # Check each organization trail for KMS encryption
63
+ for trail in org_trails:
64
+ trail_name = trail.get('Name', 'Unknown')
65
+ trail_arn = trail.get('TrailARN', 'Unknown')
66
+ kms_key_id = trail.get('KmsKeyId', '')
67
+ home_region = trail.get('HomeRegion', 'Unknown')
68
+
69
+ if kms_key_id:
70
+ # Trail is encrypted with KMS
71
+ findings.append(
72
+ self.create_finding(
73
+ status="PASS",
74
+ region="global",
75
+ resource_id=trail_arn,
76
+ checked_value="KmsKeyId: not empty",
77
+ actual_value=f"Organization trail '{trail_name}' is encrypted with KMS key: {kms_key_id}",
78
+ remediation="No remediation needed"
79
+ )
80
+ )
81
+ else:
82
+ # Trail is not encrypted with KMS
83
+ findings.append(
84
+ self.create_finding(
85
+ status="FAIL",
86
+ region="global",
87
+ resource_id=trail_arn,
88
+ checked_value="KmsKeyId: not empty",
89
+ actual_value=f"Organization trail '{trail_name}' is not encrypted with KMS",
90
+ remediation=(
91
+ f"Update the organization trail '{trail_name}' to use KMS encryption using the AWS CLI command: "
92
+ f"aws cloudtrail update-trail --name {trail_name} "
93
+ f"--kms-key-id arn:aws:kms:{home_region}:{self.account_id}:key/YOUR_KMS_KEY_ID "
94
+ f"--region {home_region}"
95
+ )
96
+ )
97
+ )
98
+
99
+ return findings
@@ -0,0 +1,94 @@
1
+ """
2
+ SRA-CLOUDTRAIL-03: Organization CloudTrail Log File Validation.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.cloudtrail.base import CloudTrailCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_CLOUDTRAIL_03(CloudTrailCheck):
10
+ """Check if organization trails have log file validation enabled."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-CLOUDTRAIL-03"
16
+ self.check_name = "Organization trail has Log File validation enabled"
17
+ self.account_type = "management"
18
+ self.severity = "MEDIUM"
19
+ self.description = (
20
+ "This check verifies that your organization trail has log file validation enabled. "
21
+ "Validated log files are especially valuable in security and forensic investigations. "
22
+ "CloudTrail log file integrity validation uses industry standard algorithms: SHA-256 for "
23
+ "hashing and SHA-256 with RSA for digital signing. This makes it computationally unfeasible "
24
+ "to modify, delete or forge CloudTrail log files without detection."
25
+ )
26
+ self.check_logic = (
27
+ "Check if organization trails have LogFileValidationEnabled set to true."
28
+ )
29
+
30
+ def execute(self) -> List[Dict[str, Any]]:
31
+ """
32
+ Execute the check.
33
+
34
+ Returns:
35
+ List of findings
36
+ """
37
+ findings = []
38
+
39
+ # Get organization trails
40
+ org_trails = self.get_organization_trails()
41
+
42
+ if not org_trails:
43
+ findings.append(
44
+ self.create_finding(
45
+ status="FAIL",
46
+ region="global",
47
+ resource_id=f"organization/{self.account_id}",
48
+ checked_value="LogFileValidationEnabled: true",
49
+ actual_value="No organization trails found",
50
+ remediation=(
51
+ "Create an organization trail with log file validation in the management account using the AWS CLI command: "
52
+ f"aws cloudtrail create-trail --name org-trail --is-organization-trail --s3-bucket-name cloudtrail-logs-{self.account_id} "
53
+ f"--enable-log-file-validation --is-multi-region-trail --region {self.regions[0] if self.regions else 'us-east-1'}"
54
+ )
55
+ )
56
+ )
57
+ return findings
58
+
59
+ # Check each organization trail for log file validation
60
+ for trail in org_trails:
61
+ trail_name = trail.get('Name', 'Unknown')
62
+ trail_arn = trail.get('TrailARN', 'Unknown')
63
+ log_file_validation_enabled = trail.get('LogFileValidationEnabled', False)
64
+ home_region = trail.get('HomeRegion', 'Unknown')
65
+
66
+ if log_file_validation_enabled:
67
+ # Trail has log file validation enabled
68
+ findings.append(
69
+ self.create_finding(
70
+ status="PASS",
71
+ region="global",
72
+ resource_id=trail_arn,
73
+ checked_value="LogFileValidationEnabled: true",
74
+ actual_value=f"Organization trail '{trail_name}' has log file validation enabled",
75
+ remediation="No remediation needed"
76
+ )
77
+ )
78
+ else:
79
+ # Trail does not have log file validation enabled
80
+ findings.append(
81
+ self.create_finding(
82
+ status="FAIL",
83
+ region="global",
84
+ resource_id=trail_arn,
85
+ checked_value="LogFileValidationEnabled: true",
86
+ actual_value=f"Organization trail '{trail_name}' does not have log file validation enabled",
87
+ remediation=(
88
+ f"Update the organization trail '{trail_name}' to enable log file validation using the AWS CLI command: "
89
+ f"aws cloudtrail update-trail --name {trail_name} --enable-log-file-validation --region {home_region}"
90
+ )
91
+ )
92
+ )
93
+
94
+ return findings
@@ -0,0 +1,92 @@
1
+ """
2
+ SRA-CLOUDTRAIL-04: Organization CloudTrail Multi-Region Configuration.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.cloudtrail.base import CloudTrailCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_CLOUDTRAIL_04(CloudTrailCheck):
10
+ """Check if organization trails are configured as multi-region trails."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-CLOUDTRAIL-04"
16
+ self.check_name = "Organization Trail is a multi-region trail"
17
+ self.account_type = "management"
18
+ self.severity = "MEDIUM"
19
+ self.description = (
20
+ "This check verifies whether the Organization trail is configured as a multi-region trail. "
21
+ "This helps with visibility across your entire AWS environment, even for AWS Regions where "
22
+ "you are not operating to ensure you detect any malicious and/or unauthorized activities."
23
+ )
24
+ self.check_logic = (
25
+ "Check if organization trails have IsMultiRegionTrail set to true."
26
+ )
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
+ # Get organization trails
38
+ org_trails = self.get_organization_trails()
39
+
40
+ if not org_trails:
41
+ findings.append(
42
+ self.create_finding(
43
+ status="FAIL",
44
+ region="global",
45
+ resource_id=f"organization/{self.account_id}",
46
+ checked_value="IsMultiRegionTrail: true",
47
+ actual_value="No organization trails found",
48
+ remediation=(
49
+ "Create a multi-region organization trail in the management account using the AWS CLI command: "
50
+ f"aws cloudtrail create-trail --name org-trail --is-organization-trail --s3-bucket-name cloudtrail-logs-{self.account_id} "
51
+ f"--is-multi-region-trail --region {self.regions[0] if self.regions else 'us-east-1'}"
52
+ )
53
+ )
54
+ )
55
+ return findings
56
+
57
+ # Check each organization trail for multi-region configuration
58
+ for trail in org_trails:
59
+ trail_name = trail.get('Name', 'Unknown')
60
+ trail_arn = trail.get('TrailARN', 'Unknown')
61
+ is_multi_region_trail = trail.get('IsMultiRegionTrail', False)
62
+ home_region = trail.get('HomeRegion', 'Unknown')
63
+
64
+ if is_multi_region_trail:
65
+ # Trail is a multi-region trail
66
+ findings.append(
67
+ self.create_finding(
68
+ status="PASS",
69
+ region="global",
70
+ resource_id=trail_arn,
71
+ checked_value="IsMultiRegionTrail: true",
72
+ actual_value=f"Organization trail '{trail_name}' is configured as a multi-region trail",
73
+ remediation="No remediation needed"
74
+ )
75
+ )
76
+ else:
77
+ # Trail is not a multi-region trail
78
+ findings.append(
79
+ self.create_finding(
80
+ status="FAIL",
81
+ region="global",
82
+ resource_id=trail_arn,
83
+ checked_value="IsMultiRegionTrail: true",
84
+ actual_value=f"Organization trail '{trail_name}' is not configured as a multi-region trail",
85
+ remediation=(
86
+ f"Update the organization trail '{trail_name}' to be a multi-region trail using the AWS CLI command: "
87
+ f"aws cloudtrail update-trail --name {trail_name} --is-multi-region-trail --region {home_region}"
88
+ )
89
+ )
90
+ )
91
+
92
+ return findings
@@ -0,0 +1,106 @@
1
+ """
2
+ SRA-CLOUDTRAIL-05: CloudTrail CloudWatch Logs Configuration.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.cloudtrail.base import CloudTrailCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_CLOUDTRAIL_05(CloudTrailCheck):
10
+ """Check if trails have CloudWatch Logs configuration."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-CLOUDTRAIL-05"
16
+ self.check_name = "CloudTrail has CloudWatch Logs configuration"
17
+ self.account_type = "management"
18
+ self.severity = "MEDIUM"
19
+ self.description = (
20
+ "This check verifies that CloudTrail has CloudWatch Logs configuration. "
21
+ "CloudWatch Logs enables you to centralize the CloudTrail logs from all your AWS accounts and "
22
+ "regions in the AWS Organization, to a single, highly scalable service. You can then easily "
23
+ "view them, search them for specific error codes or patterns, filter them based on specific "
24
+ "fields, or archive them securely for future analysis."
25
+ )
26
+ self.check_logic = (
27
+ "Check if trails have CloudWatchLogsLogGroupArn and CloudWatchLogsRoleArn configured."
28
+ )
29
+
30
+ def execute(self) -> List[Dict[str, Any]]:
31
+ """
32
+ Execute the check.
33
+
34
+ Returns:
35
+ List of findings
36
+ """
37
+ findings = []
38
+
39
+ # Get all trails
40
+ all_trails = self.describe_trails()
41
+
42
+ if not all_trails:
43
+ findings.append(
44
+ self.create_finding(
45
+ status="FAIL",
46
+ region="global",
47
+ resource_id="cloudtrail:global",
48
+ checked_value="CloudWatchLogsLogGroupArn and CloudWatchLogsRoleArn: configured",
49
+ actual_value="No CloudTrail trails found",
50
+ remediation=(
51
+ "Create a CloudTrail trail with CloudWatch Logs configuration using the AWS CLI command: "
52
+ f"aws cloudtrail create-trail --name trail-with-cloudwatch --s3-bucket-name cloudtrail-logs-{self.account_id} "
53
+ f"--cloud-watch-logs-log-group-arn arn:aws:logs:{self.regions[0] if self.regions else 'us-east-1'}:{self.account_id}:log-group:CloudTrail/Logs:* "
54
+ f"--cloud-watch-logs-role-arn arn:aws:iam::{self.account_id}:role/CloudTrail_CloudWatchLogs_Role"
55
+ )
56
+ )
57
+ )
58
+ return findings
59
+
60
+ # Check each trail for CloudWatch Logs configuration
61
+ for trail in all_trails:
62
+ trail_name = trail.get('Name', 'Unknown')
63
+ trail_arn = trail.get('TrailARN', 'Unknown')
64
+ cloudwatch_logs_group_arn = trail.get('CloudWatchLogsLogGroupArn', '')
65
+ cloudwatch_logs_role_arn = trail.get('CloudWatchLogsRoleArn', '')
66
+
67
+ # Get the home region from the trail
68
+ home_region = trail.get('HomeRegion', self.regions[0] if self.regions else 'us-east-1')
69
+
70
+ if cloudwatch_logs_group_arn and cloudwatch_logs_role_arn:
71
+ # Trail has CloudWatch Logs configuration
72
+ resource_id = f"{cloudwatch_logs_group_arn},{cloudwatch_logs_role_arn}"
73
+
74
+ findings.append(
75
+ self.create_finding(
76
+ status="PASS",
77
+ region="global",
78
+ resource_id=resource_id,
79
+ checked_value="CloudWatchLogsLogGroupArn and CloudWatchLogsRoleArn: configured",
80
+ actual_value=(
81
+ f"CloudTrail '{trail_name}' has CloudWatch Logs configuration: "
82
+ f"CloudWatch Logs Group ARN: {cloudwatch_logs_group_arn}, "
83
+ f"CloudWatch Logs Role ARN: {cloudwatch_logs_role_arn}"
84
+ ),
85
+ remediation="No remediation needed"
86
+ )
87
+ )
88
+ else:
89
+ # Trail does not have CloudWatch Logs configuration
90
+ findings.append(
91
+ self.create_finding(
92
+ status="FAIL",
93
+ region="global",
94
+ resource_id=trail_arn,
95
+ checked_value="CloudWatchLogsLogGroupArn and CloudWatchLogsRoleArn: configured",
96
+ actual_value=f"CloudTrail '{trail_name}' does not have CloudWatch Logs configuration",
97
+ remediation=(
98
+ f"Configure CloudTrail '{trail_name}' to use CloudWatch Logs using the AWS CLI command: "
99
+ f"aws cloudtrail update-trail --name {trail_name} "
100
+ f"--cloud-watch-logs-log-group-arn arn:aws:logs:{home_region}:{self.account_id}:log-group:CloudTrail/Logs:* "
101
+ f"--cloud-watch-logs-role-arn arn:aws:iam::{self.account_id}:role/CloudTrail_CloudWatchLogs_Role"
102
+ )
103
+ )
104
+ )
105
+
106
+ return findings
@@ -0,0 +1,93 @@
1
+ """
2
+ SRA-CLOUDTRAIL-06: Organization CloudTrail Global Service Events.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.cloudtrail.base import CloudTrailCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_CLOUDTRAIL_06(CloudTrailCheck):
10
+ """Check if organization trails are configured to publish events from global services."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-CLOUDTRAIL-06"
16
+ self.check_name = "Organization trail is configured to publish events from global services"
17
+ self.account_type = "management"
18
+ self.severity = "MEDIUM"
19
+ self.description = (
20
+ "This check verifies that your organization trail is configured to publish event from AWS global services. "
21
+ "The organization trail should capture events from global services such as AWS IAM, AWS STS and Amazon CloudFront. "
22
+ "Trails created using CloudTrail console by default have global service event configured but if you are creating "
23
+ "trail with AWS CLI, AWS SDKs, or CloudTrail API you have to specify to included global services events."
24
+ )
25
+ self.check_logic = (
26
+ "Check if organization trails have IncludeGlobalServiceEvents set to true."
27
+ )
28
+
29
+ def execute(self) -> List[Dict[str, Any]]:
30
+ """
31
+ Execute the check.
32
+
33
+ Returns:
34
+ List of findings
35
+ """
36
+ findings = []
37
+
38
+ # Get organization trails
39
+ org_trails = self.get_organization_trails()
40
+
41
+ if not org_trails:
42
+ findings.append(
43
+ self.create_finding(
44
+ status="FAIL",
45
+ region="global",
46
+ resource_id=f"organization/{self.account_id}",
47
+ checked_value="IncludeGlobalServiceEvents: true",
48
+ actual_value="No organization trails found",
49
+ remediation=(
50
+ "Create an organization trail with global service events in the management account using the AWS CLI command: "
51
+ f"aws cloudtrail create-trail --name org-trail --is-organization-trail --s3-bucket-name cloudtrail-logs-{self.account_id} "
52
+ f"--include-global-service-events --is-multi-region-trail --region {self.regions[0] if self.regions else 'us-east-1'}"
53
+ )
54
+ )
55
+ )
56
+ return findings
57
+
58
+ # Check each organization trail for global service events
59
+ for trail in org_trails:
60
+ trail_name = trail.get('Name', 'Unknown')
61
+ trail_arn = trail.get('TrailARN', 'Unknown')
62
+ include_global_service_events = trail.get('IncludeGlobalServiceEvents', False)
63
+ home_region = trail.get('HomeRegion', 'Unknown')
64
+
65
+ if include_global_service_events:
66
+ # Trail includes global service events
67
+ findings.append(
68
+ self.create_finding(
69
+ status="PASS",
70
+ region="global",
71
+ resource_id=trail_arn,
72
+ checked_value="IncludeGlobalServiceEvents: true",
73
+ actual_value=f"Organization trail '{trail_name}' is configured to publish events from global services",
74
+ remediation="No remediation needed"
75
+ )
76
+ )
77
+ else:
78
+ # Trail does not include global service events
79
+ findings.append(
80
+ self.create_finding(
81
+ status="FAIL",
82
+ region="global",
83
+ resource_id=trail_arn,
84
+ checked_value="IncludeGlobalServiceEvents: true",
85
+ actual_value=f"Organization trail '{trail_name}' is not configured to publish events from global services",
86
+ remediation=(
87
+ f"Update the organization trail '{trail_name}' to include global service events using the AWS CLI command: "
88
+ f"aws cloudtrail update-trail --name {trail_name} --include-global-service-events --region {home_region}"
89
+ )
90
+ )
91
+ )
92
+
93
+ return findings
@@ -0,0 +1,96 @@
1
+ """
2
+ SRA-CLOUDTRAIL-07: Organization CloudTrail Active Logging.
3
+ """
4
+ from typing import List, Dict, Any
5
+ from sraverify.services.cloudtrail.base import CloudTrailCheck
6
+ from sraverify.core.logging import logger
7
+
8
+
9
+ class SRA_CLOUDTRAIL_07(CloudTrailCheck):
10
+ """Check if organization trails are actively publishing events."""
11
+
12
+ def __init__(self):
13
+ """Initialize the check."""
14
+ super().__init__()
15
+ self.check_id = "SRA-CLOUDTRAIL-07"
16
+ self.check_name = "Organization trail is actively publishing events"
17
+ self.account_type = "management"
18
+ self.severity = "HIGH"
19
+ self.description = (
20
+ "This check verifies that your organization trail is running and actively logging events. "
21
+ "If a trail is modified to stop logging, accidently or by malicious user, you will not have "
22
+ "visibility into any API activity across your AWS environment."
23
+ )
24
+ self.check_logic = (
25
+ "Check if organization trails have IsLogging set to true in their status."
26
+ )
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
+ # Get organization trails
38
+ org_trails = self.get_organization_trails()
39
+
40
+ if not org_trails:
41
+ findings.append(
42
+ self.create_finding(
43
+ status="FAIL",
44
+ region="global",
45
+ resource_id=f"organization/{self.account_id}",
46
+ checked_value="IsLogging: true",
47
+ actual_value="No organization trails found",
48
+ remediation=(
49
+ "Create an organization trail in the management account using the AWS CLI command: "
50
+ f"aws cloudtrail create-trail --name org-trail --is-organization-trail --s3-bucket-name cloudtrail-logs-{self.account_id} "
51
+ f"--is-multi-region-trail --region {self.regions[0] if self.regions else 'us-east-1'} && "
52
+ f"aws cloudtrail start-logging --name org-trail --region {self.regions[0] if self.regions else 'us-east-1'}"
53
+ )
54
+ )
55
+ )
56
+ return findings
57
+
58
+ # Check each organization trail for active logging
59
+ for trail in org_trails:
60
+ trail_name = trail.get('Name', 'Unknown')
61
+ trail_arn = trail.get('TrailARN', 'Unknown')
62
+ home_region = trail.get('HomeRegion', 'Unknown')
63
+
64
+ # Get trail status to check if logging is enabled
65
+ trail_status = self.get_trail_status(home_region, trail_arn)
66
+ is_logging = trail_status.get('IsLogging', False)
67
+
68
+ if is_logging:
69
+ # Trail is actively logging
70
+ findings.append(
71
+ self.create_finding(
72
+ status="PASS",
73
+ region="global",
74
+ resource_id=trail_arn,
75
+ checked_value="IsLogging: true",
76
+ actual_value=f"Organization trail '{trail_name}' is actively logging events",
77
+ remediation="No remediation needed"
78
+ )
79
+ )
80
+ else:
81
+ # Trail is not actively logging
82
+ findings.append(
83
+ self.create_finding(
84
+ status="FAIL",
85
+ region="global",
86
+ resource_id=trail_arn,
87
+ checked_value="IsLogging: true",
88
+ actual_value=f"Organization trail '{trail_name}' is not actively logging events",
89
+ remediation=(
90
+ f"Start logging for the organization trail '{trail_name}' using the AWS CLI command: "
91
+ f"aws cloudtrail start-logging --name {trail_name} --region {home_region}"
92
+ )
93
+ )
94
+ )
95
+
96
+ return findings