cartography 0.104.0rc2__py3-none-any.whl → 0.123.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 (642) hide show
  1. cartography/_version.py +16 -3
  2. cartography/cli.py +466 -5
  3. cartography/client/aws/__init__.py +19 -0
  4. cartography/client/aws/ecr.py +51 -0
  5. cartography/client/core/tx.py +357 -8
  6. cartography/config.py +153 -0
  7. cartography/data/azure_permission_relationships.yaml +20 -0
  8. cartography/data/gcp_permission_relationships.yaml +21 -0
  9. cartography/data/indexes.cypher +0 -186
  10. cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
  11. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  12. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  13. cartography/data/jobs/cleanup/github_repos_cleanup.json +2 -0
  14. cartography/driftdetect/cli.py +3 -2
  15. cartography/graph/cleanupbuilder.py +198 -41
  16. cartography/graph/job.py +54 -6
  17. cartography/graph/querybuilder.py +528 -27
  18. cartography/graph/statement.py +5 -1
  19. cartography/intel/airbyte/__init__.py +105 -0
  20. cartography/intel/airbyte/connections.py +120 -0
  21. cartography/intel/airbyte/destinations.py +81 -0
  22. cartography/intel/airbyte/organizations.py +59 -0
  23. cartography/intel/airbyte/sources.py +78 -0
  24. cartography/intel/airbyte/tags.py +64 -0
  25. cartography/intel/airbyte/users.py +106 -0
  26. cartography/intel/airbyte/util.py +122 -0
  27. cartography/intel/airbyte/workspaces.py +63 -0
  28. cartography/intel/aws/__init__.py +24 -9
  29. cartography/intel/aws/acm.py +124 -0
  30. cartography/intel/aws/apigateway.py +253 -22
  31. cartography/intel/aws/apigatewayv2.py +116 -0
  32. cartography/intel/aws/cloudtrail.py +17 -39
  33. cartography/intel/aws/cloudtrail_management_events.py +962 -0
  34. cartography/intel/aws/cloudwatch.py +150 -4
  35. cartography/intel/aws/codebuild.py +132 -0
  36. cartography/intel/aws/cognito.py +201 -0
  37. cartography/intel/aws/config.py +7 -3
  38. cartography/intel/aws/ec2/elastic_ip_addresses.py +3 -1
  39. cartography/intel/aws/ec2/instances.py +25 -1
  40. cartography/intel/aws/ec2/internet_gateways.py +4 -2
  41. cartography/intel/aws/ec2/load_balancer_v2s.py +11 -5
  42. cartography/intel/aws/ec2/network_interfaces.py +5 -1
  43. cartography/intel/aws/ec2/reserved_instances.py +3 -1
  44. cartography/intel/aws/ec2/security_groups.py +140 -122
  45. cartography/intel/aws/ec2/snapshots.py +47 -84
  46. cartography/intel/aws/ec2/subnets.py +37 -63
  47. cartography/intel/aws/ec2/tgw.py +11 -5
  48. cartography/intel/aws/ec2/volumes.py +1 -1
  49. cartography/intel/aws/ec2/vpc.py +140 -124
  50. cartography/intel/aws/ec2/vpc_peerings.py +262 -125
  51. cartography/intel/aws/ecr.py +269 -98
  52. cartography/intel/aws/ecr_image_layers.py +923 -0
  53. cartography/intel/aws/ecs.py +251 -380
  54. cartography/intel/aws/efs.py +179 -11
  55. cartography/intel/aws/elasticache.py +102 -79
  56. cartography/intel/aws/elasticsearch.py +13 -4
  57. cartography/intel/aws/eventbridge.py +164 -0
  58. cartography/intel/aws/glue.py +181 -0
  59. cartography/intel/aws/guardduty.py +443 -0
  60. cartography/intel/aws/iam.py +750 -493
  61. cartography/intel/aws/identitycenter.py +605 -83
  62. cartography/intel/aws/inspector.py +221 -105
  63. cartography/intel/aws/kms.py +173 -201
  64. cartography/intel/aws/lambda_function.py +272 -189
  65. cartography/intel/aws/organizations.py +10 -9
  66. cartography/intel/aws/permission_relationships.py +10 -20
  67. cartography/intel/aws/rds.py +337 -446
  68. cartography/intel/aws/redshift.py +9 -4
  69. cartography/intel/aws/resourcegroupstaggingapi.py +78 -19
  70. cartography/intel/aws/resources.py +18 -0
  71. cartography/intel/aws/route53.py +386 -332
  72. cartography/intel/aws/s3.py +322 -14
  73. cartography/intel/aws/secretsmanager.py +81 -49
  74. cartography/intel/aws/securityhub.py +3 -1
  75. cartography/intel/aws/sns.py +62 -2
  76. cartography/intel/aws/sqs.py +36 -90
  77. cartography/intel/aws/ssm.py +3 -5
  78. cartography/intel/azure/__init__.py +202 -48
  79. cartography/intel/azure/aks.py +175 -0
  80. cartography/intel/azure/app_service.py +105 -0
  81. cartography/intel/azure/compute.py +59 -112
  82. cartography/intel/azure/container_instances.py +95 -0
  83. cartography/intel/azure/cosmosdb.py +222 -361
  84. cartography/intel/azure/data_factory.py +85 -0
  85. cartography/intel/azure/data_factory_dataset.py +128 -0
  86. cartography/intel/azure/data_factory_linked_service.py +119 -0
  87. cartography/intel/azure/data_factory_pipeline.py +142 -0
  88. cartography/intel/azure/data_lake.py +124 -0
  89. cartography/intel/azure/event_grid.py +94 -0
  90. cartography/intel/azure/functions.py +124 -0
  91. cartography/intel/azure/load_balancers.py +263 -0
  92. cartography/intel/azure/logic_apps.py +101 -0
  93. cartography/intel/azure/monitor.py +105 -0
  94. cartography/intel/azure/network.py +467 -0
  95. cartography/intel/azure/permission_relationships.py +466 -0
  96. cartography/intel/azure/rbac.py +309 -0
  97. cartography/intel/azure/resource_groups.py +82 -0
  98. cartography/intel/azure/security_center.py +106 -0
  99. cartography/intel/azure/sql.py +145 -292
  100. cartography/intel/azure/storage.py +185 -262
  101. cartography/intel/azure/subscription.py +21 -43
  102. cartography/intel/azure/tenant.py +39 -30
  103. cartography/intel/azure/util/common.py +13 -0
  104. cartography/intel/azure/util/credentials.py +49 -174
  105. cartography/intel/azure/util/tag.py +41 -0
  106. cartography/intel/create_indexes.py +2 -1
  107. cartography/intel/crowdstrike/spotlight.py +5 -2
  108. cartography/intel/dns.py +5 -2
  109. cartography/intel/entra/__init__.py +100 -1
  110. cartography/intel/entra/app_role_assignments.py +284 -0
  111. cartography/intel/entra/applications.py +182 -0
  112. cartography/intel/entra/federation/__init__.py +0 -0
  113. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  114. cartography/intel/entra/groups.py +198 -0
  115. cartography/intel/entra/ou.py +48 -24
  116. cartography/intel/entra/service_principals.py +217 -0
  117. cartography/intel/entra/users.py +105 -57
  118. cartography/intel/gcp/__init__.py +334 -396
  119. cartography/intel/gcp/bigtable_app_profile.py +101 -0
  120. cartography/intel/gcp/bigtable_backup.py +91 -0
  121. cartography/intel/gcp/bigtable_cluster.py +93 -0
  122. cartography/intel/gcp/bigtable_instance.py +86 -0
  123. cartography/intel/gcp/bigtable_table.py +87 -0
  124. cartography/intel/gcp/cai.py +292 -0
  125. cartography/intel/gcp/clients.py +112 -0
  126. cartography/intel/gcp/compute.py +128 -119
  127. cartography/intel/gcp/crm/__init__.py +0 -0
  128. cartography/intel/gcp/crm/folders.py +114 -0
  129. cartography/intel/gcp/crm/orgs.py +70 -0
  130. cartography/intel/gcp/crm/projects.py +120 -0
  131. cartography/intel/gcp/dns.py +83 -169
  132. cartography/intel/gcp/gke.py +72 -113
  133. cartography/intel/gcp/iam.py +111 -91
  134. cartography/intel/gcp/permission_relationships.py +394 -0
  135. cartography/intel/gcp/policy_bindings.py +225 -0
  136. cartography/intel/gcp/storage.py +75 -159
  137. cartography/intel/github/__init__.py +62 -25
  138. cartography/intel/github/commits.py +423 -0
  139. cartography/intel/github/repos.py +463 -85
  140. cartography/intel/github/teams.py +3 -3
  141. cartography/intel/github/users.py +5 -0
  142. cartography/intel/github/util.py +12 -0
  143. cartography/intel/googleworkspace/__init__.py +193 -0
  144. cartography/intel/googleworkspace/devices.py +254 -0
  145. cartography/intel/googleworkspace/groups.py +568 -0
  146. cartography/intel/googleworkspace/oauth_apps.py +259 -0
  147. cartography/intel/googleworkspace/tenant.py +85 -0
  148. cartography/intel/googleworkspace/users.py +138 -0
  149. cartography/intel/gsuite/__init__.py +17 -9
  150. cartography/intel/gsuite/groups.py +291 -0
  151. cartography/intel/gsuite/users.py +142 -0
  152. cartography/intel/jamf/computers.py +7 -1
  153. cartography/intel/keycloak/__init__.py +153 -0
  154. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  155. cartography/intel/keycloak/authenticationflows.py +77 -0
  156. cartography/intel/keycloak/clients.py +187 -0
  157. cartography/intel/keycloak/groups.py +126 -0
  158. cartography/intel/keycloak/identityproviders.py +94 -0
  159. cartography/intel/keycloak/organizations.py +163 -0
  160. cartography/intel/keycloak/realms.py +61 -0
  161. cartography/intel/keycloak/roles.py +202 -0
  162. cartography/intel/keycloak/scopes.py +73 -0
  163. cartography/intel/keycloak/users.py +70 -0
  164. cartography/intel/keycloak/util.py +47 -0
  165. cartography/intel/kubernetes/__init__.py +60 -14
  166. cartography/intel/kubernetes/clusters.py +86 -0
  167. cartography/intel/kubernetes/eks.py +402 -0
  168. cartography/intel/kubernetes/namespaces.py +59 -57
  169. cartography/intel/kubernetes/pods.py +168 -75
  170. cartography/intel/kubernetes/rbac.py +597 -0
  171. cartography/intel/kubernetes/secrets.py +95 -45
  172. cartography/intel/kubernetes/services.py +131 -67
  173. cartography/intel/kubernetes/util.py +142 -14
  174. cartography/intel/oci/iam.py +23 -9
  175. cartography/intel/oci/organizations.py +3 -1
  176. cartography/intel/oci/utils.py +28 -5
  177. cartography/intel/okta/applications.py +15 -5
  178. cartography/intel/okta/awssaml.py +14 -10
  179. cartography/intel/okta/factors.py +3 -1
  180. cartography/intel/okta/groups.py +5 -2
  181. cartography/intel/okta/organization.py +3 -1
  182. cartography/intel/okta/origins.py +3 -1
  183. cartography/intel/okta/roles.py +5 -2
  184. cartography/intel/okta/users.py +10 -2
  185. cartography/intel/ontology/__init__.py +44 -0
  186. cartography/intel/ontology/devices.py +54 -0
  187. cartography/intel/ontology/users.py +54 -0
  188. cartography/intel/ontology/utils.py +176 -0
  189. cartography/intel/pagerduty/escalation_policies.py +13 -6
  190. cartography/intel/pagerduty/schedules.py +9 -4
  191. cartography/intel/pagerduty/services.py +7 -3
  192. cartography/intel/pagerduty/teams.py +5 -2
  193. cartography/intel/pagerduty/users.py +3 -1
  194. cartography/intel/pagerduty/vendors.py +3 -1
  195. cartography/intel/scaleway/__init__.py +127 -0
  196. cartography/intel/scaleway/iam/__init__.py +0 -0
  197. cartography/intel/scaleway/iam/apikeys.py +71 -0
  198. cartography/intel/scaleway/iam/applications.py +71 -0
  199. cartography/intel/scaleway/iam/groups.py +71 -0
  200. cartography/intel/scaleway/iam/users.py +71 -0
  201. cartography/intel/scaleway/instances/__init__.py +0 -0
  202. cartography/intel/scaleway/instances/flexibleips.py +86 -0
  203. cartography/intel/scaleway/instances/instances.py +92 -0
  204. cartography/intel/scaleway/projects.py +79 -0
  205. cartography/intel/scaleway/storage/__init__.py +0 -0
  206. cartography/intel/scaleway/storage/snapshots.py +86 -0
  207. cartography/intel/scaleway/storage/volumes.py +84 -0
  208. cartography/intel/scaleway/utils.py +37 -0
  209. cartography/intel/sentinelone/__init__.py +75 -0
  210. cartography/intel/sentinelone/account.py +140 -0
  211. cartography/intel/sentinelone/agent.py +139 -0
  212. cartography/intel/sentinelone/api.py +124 -0
  213. cartography/intel/sentinelone/application.py +248 -0
  214. cartography/intel/sentinelone/cve.py +119 -0
  215. cartography/intel/sentinelone/utils.py +28 -0
  216. cartography/intel/slack/__init__.py +78 -0
  217. cartography/intel/slack/channels.py +80 -0
  218. cartography/intel/slack/groups.py +90 -0
  219. cartography/intel/slack/teams.py +65 -0
  220. cartography/intel/slack/users.py +57 -0
  221. cartography/intel/slack/utils.py +29 -0
  222. cartography/intel/spacelift/__init__.py +161 -0
  223. cartography/intel/spacelift/account.py +73 -0
  224. cartography/intel/spacelift/ec2_ownership.py +280 -0
  225. cartography/intel/spacelift/runs.py +463 -0
  226. cartography/intel/spacelift/spaces.py +112 -0
  227. cartography/intel/spacelift/stacks.py +119 -0
  228. cartography/intel/spacelift/util.py +122 -0
  229. cartography/intel/spacelift/workerpools.py +131 -0
  230. cartography/intel/spacelift/workers.py +128 -0
  231. cartography/intel/trivy/__init__.py +272 -0
  232. cartography/intel/trivy/scanner.py +386 -0
  233. cartography/models/airbyte/__init__.py +0 -0
  234. cartography/models/airbyte/connection.py +138 -0
  235. cartography/models/airbyte/destination.py +75 -0
  236. cartography/models/airbyte/organization.py +19 -0
  237. cartography/models/airbyte/source.py +75 -0
  238. cartography/models/airbyte/stream.py +74 -0
  239. cartography/models/airbyte/tag.py +69 -0
  240. cartography/models/airbyte/user.py +115 -0
  241. cartography/models/airbyte/workspace.py +46 -0
  242. cartography/models/anthropic/apikey.py +4 -0
  243. cartography/models/anthropic/user.py +4 -0
  244. cartography/models/aws/acm/__init__.py +0 -0
  245. cartography/models/aws/acm/certificate.py +75 -0
  246. cartography/models/aws/apigateway/__init__.py +0 -0
  247. cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
  248. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  249. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  250. cartography/models/aws/apigatewayv2/__init__.py +0 -0
  251. cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
  252. cartography/models/aws/cloudtrail/management_events.py +153 -0
  253. cartography/models/aws/cloudtrail/trail.py +45 -0
  254. cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
  255. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  256. cartography/models/aws/codebuild/__init__.py +0 -0
  257. cartography/models/aws/codebuild/project.py +49 -0
  258. cartography/models/aws/cognito/__init__.py +0 -0
  259. cartography/models/aws/cognito/identity_pool.py +70 -0
  260. cartography/models/aws/cognito/user_pool.py +47 -0
  261. cartography/models/aws/dynamodb/tables.py +2 -0
  262. cartography/models/aws/ec2/instances.py +25 -1
  263. cartography/models/aws/ec2/networkinterfaces.py +4 -0
  264. cartography/models/aws/ec2/security_group_rules.py +109 -0
  265. cartography/models/aws/ec2/security_groups.py +90 -0
  266. cartography/models/aws/ec2/snapshots.py +58 -0
  267. cartography/models/aws/ec2/subnet_instance.py +2 -0
  268. cartography/models/aws/ec2/subnet_networkinterface.py +2 -0
  269. cartography/models/aws/ec2/subnets.py +65 -0
  270. cartography/models/aws/ec2/volumes.py +20 -0
  271. cartography/models/aws/ec2/vpc.py +46 -0
  272. cartography/models/aws/ec2/vpc_cidr.py +102 -0
  273. cartography/models/aws/ec2/vpc_peering.py +157 -0
  274. cartography/models/aws/ecr/__init__.py +0 -0
  275. cartography/models/aws/ecr/image.py +146 -0
  276. cartography/models/aws/ecr/image_layer.py +107 -0
  277. cartography/models/aws/ecr/repository.py +72 -0
  278. cartography/models/aws/ecr/repository_image.py +95 -0
  279. cartography/models/aws/ecs/__init__.py +0 -0
  280. cartography/models/aws/ecs/clusters.py +64 -0
  281. cartography/models/aws/ecs/container_definitions.py +93 -0
  282. cartography/models/aws/ecs/container_instances.py +84 -0
  283. cartography/models/aws/ecs/containers.py +101 -0
  284. cartography/models/aws/ecs/services.py +134 -0
  285. cartography/models/aws/ecs/task_definitions.py +135 -0
  286. cartography/models/aws/ecs/tasks.py +134 -0
  287. cartography/models/aws/efs/access_point.py +77 -0
  288. cartography/models/aws/efs/file_system.py +60 -0
  289. cartography/models/aws/efs/mount_target.py +29 -2
  290. cartography/models/aws/elasticache/__init__.py +0 -0
  291. cartography/models/aws/elasticache/cluster.py +65 -0
  292. cartography/models/aws/elasticache/topic.py +67 -0
  293. cartography/models/aws/eventbridge/__init__.py +0 -0
  294. cartography/models/aws/eventbridge/rule.py +77 -0
  295. cartography/models/aws/eventbridge/target.py +71 -0
  296. cartography/models/aws/glue/__init__.py +0 -0
  297. cartography/models/aws/glue/connection.py +51 -0
  298. cartography/models/aws/glue/job.py +69 -0
  299. cartography/models/aws/guardduty/__init__.py +1 -0
  300. cartography/models/aws/guardduty/detectors.py +50 -0
  301. cartography/models/aws/guardduty/findings.py +121 -0
  302. cartography/models/aws/iam/access_key.py +103 -0
  303. cartography/models/aws/iam/account_role.py +24 -0
  304. cartography/models/aws/iam/federated_principal.py +60 -0
  305. cartography/models/aws/iam/group.py +60 -0
  306. cartography/models/aws/iam/group_membership.py +27 -0
  307. cartography/models/aws/iam/inline_policy.py +78 -0
  308. cartography/models/aws/iam/managed_policy.py +51 -0
  309. cartography/models/aws/iam/policy_statement.py +57 -0
  310. cartography/models/aws/iam/role.py +83 -0
  311. cartography/models/aws/iam/root_principal.py +52 -0
  312. cartography/models/aws/iam/service_principal.py +30 -0
  313. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  314. cartography/models/aws/iam/user.py +59 -0
  315. cartography/models/aws/identitycenter/awsidentitycenter.py +1 -0
  316. cartography/models/aws/identitycenter/awspermissionset.py +70 -0
  317. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  318. cartography/models/aws/identitycenter/awsssouser.py +49 -9
  319. cartography/models/aws/inspector/findings.py +37 -0
  320. cartography/models/aws/inspector/packages.py +1 -31
  321. cartography/models/aws/kms/__init__.py +0 -0
  322. cartography/models/aws/kms/aliases.py +86 -0
  323. cartography/models/aws/kms/grants.py +65 -0
  324. cartography/models/aws/kms/keys.py +88 -0
  325. cartography/models/aws/lambda_function/__init__.py +0 -0
  326. cartography/models/aws/lambda_function/alias.py +74 -0
  327. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  328. cartography/models/aws/lambda_function/lambda_function.py +91 -0
  329. cartography/models/aws/lambda_function/layer.py +72 -0
  330. cartography/models/aws/rds/__init__.py +0 -0
  331. cartography/models/aws/rds/cluster.py +91 -0
  332. cartography/models/aws/rds/event_subscription.py +146 -0
  333. cartography/models/aws/rds/instance.py +156 -0
  334. cartography/models/aws/rds/snapshot.py +108 -0
  335. cartography/models/aws/rds/subnet_group.py +101 -0
  336. cartography/models/aws/route53/__init__.py +0 -0
  337. cartography/models/aws/route53/dnsrecord.py +235 -0
  338. cartography/models/aws/route53/nameserver.py +63 -0
  339. cartography/models/aws/route53/subzone.py +40 -0
  340. cartography/models/aws/route53/zone.py +47 -0
  341. cartography/models/aws/s3/notification.py +24 -0
  342. cartography/models/aws/secretsmanager/secret.py +106 -0
  343. cartography/models/aws/secretsmanager/secret_version.py +0 -2
  344. cartography/models/aws/sns/topic_subscription.py +74 -0
  345. cartography/models/aws/sqs/__init__.py +0 -0
  346. cartography/models/aws/sqs/queue.py +89 -0
  347. cartography/models/azure/__init__.py +0 -0
  348. cartography/models/azure/aks_cluster.py +54 -0
  349. cartography/models/azure/aks_nodepool.py +54 -0
  350. cartography/models/azure/app_service.py +59 -0
  351. cartography/models/azure/container_instance.py +57 -0
  352. cartography/models/azure/cosmosdb/__init__.py +0 -0
  353. cartography/models/azure/cosmosdb/account.py +77 -0
  354. cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
  355. cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
  356. cartography/models/azure/cosmosdb/cassandratable.py +81 -0
  357. cartography/models/azure/cosmosdb/corspolicy.py +74 -0
  358. cartography/models/azure/cosmosdb/dblocation.py +120 -0
  359. cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
  360. cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
  361. cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
  362. cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
  363. cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
  364. cartography/models/azure/cosmosdb/tableresource.py +76 -0
  365. cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
  366. cartography/models/azure/data_factory/__init__.py +0 -0
  367. cartography/models/azure/data_factory/data_factory.py +51 -0
  368. cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
  369. cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
  370. cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
  371. cartography/models/azure/data_lake_filesystem.py +51 -0
  372. cartography/models/azure/event_grid_topic.py +57 -0
  373. cartography/models/azure/function_app.py +59 -0
  374. cartography/models/azure/load_balancer/__init__.py +0 -0
  375. cartography/models/azure/load_balancer/load_balancer.py +49 -0
  376. cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
  377. cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
  378. cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
  379. cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
  380. cartography/models/azure/logic_apps.py +56 -0
  381. cartography/models/azure/monitor.py +54 -0
  382. cartography/models/azure/network_interface.py +112 -0
  383. cartography/models/azure/network_security_group.py +50 -0
  384. cartography/models/azure/permission_relationships.py +60 -0
  385. cartography/models/azure/principal.py +41 -0
  386. cartography/models/azure/public_ip_address.py +50 -0
  387. cartography/models/azure/rbac.py +268 -0
  388. cartography/models/azure/resource_groups.py +52 -0
  389. cartography/models/azure/security_center.py +50 -0
  390. cartography/models/azure/sql/__init__.py +0 -0
  391. cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
  392. cartography/models/azure/sql/elasticpool.py +77 -0
  393. cartography/models/azure/sql/failovergroup.py +73 -0
  394. cartography/models/azure/sql/recoverabledatabase.py +75 -0
  395. cartography/models/azure/sql/replicationlink.py +81 -0
  396. cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
  397. cartography/models/azure/sql/restorepoint.py +74 -0
  398. cartography/models/azure/sql/serveradadministrator.py +74 -0
  399. cartography/models/azure/sql/serverdnsalias.py +71 -0
  400. cartography/models/azure/sql/sqldatabase.py +85 -0
  401. cartography/models/azure/sql/sqlserver.py +50 -0
  402. cartography/models/azure/sql/transparentdataencryption.py +76 -0
  403. cartography/models/azure/storage/__init__.py +0 -0
  404. cartography/models/azure/storage/account.py +59 -0
  405. cartography/models/azure/storage/blobcontainer.py +85 -0
  406. cartography/models/azure/storage/blobservice.py +71 -0
  407. cartography/models/azure/storage/fileservice.py +71 -0
  408. cartography/models/azure/storage/fileshare.py +82 -0
  409. cartography/models/azure/storage/queue.py +71 -0
  410. cartography/models/azure/storage/queueservice.py +73 -0
  411. cartography/models/azure/storage/table.py +72 -0
  412. cartography/models/azure/storage/tableservice.py +73 -0
  413. cartography/models/azure/subnet.py +101 -0
  414. cartography/models/azure/subscription.py +47 -0
  415. cartography/models/azure/tags/__init__.py +0 -0
  416. cartography/models/azure/tags/storage_tag.py +40 -0
  417. cartography/models/azure/tags/tag.py +37 -0
  418. cartography/models/azure/tenant.py +17 -0
  419. cartography/models/azure/virtual_network.py +49 -0
  420. cartography/models/azure/vm/__init__.py +0 -0
  421. cartography/models/azure/vm/datadisk.py +80 -0
  422. cartography/models/azure/vm/disk.py +55 -0
  423. cartography/models/azure/vm/snapshot.py +56 -0
  424. cartography/models/azure/vm/virtualmachine.py +59 -0
  425. cartography/models/bigfix/bigfix_computer.py +1 -1
  426. cartography/models/cloudflare/member.py +4 -0
  427. cartography/models/core/common.py +1 -0
  428. cartography/models/core/nodes.py +15 -2
  429. cartography/models/core/relationships.py +44 -0
  430. cartography/models/crowdstrike/hosts.py +1 -1
  431. cartography/models/digitalocean/droplet.py +2 -0
  432. cartography/models/duo/endpoint.py +1 -1
  433. cartography/models/duo/phone.py +2 -2
  434. cartography/models/duo/user.py +4 -0
  435. cartography/models/entra/app_role_assignment.py +115 -0
  436. cartography/models/entra/application.py +49 -0
  437. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  438. cartography/models/entra/group.py +117 -0
  439. cartography/models/entra/service_principal.py +104 -0
  440. cartography/models/entra/user.py +42 -51
  441. cartography/models/gcp/__init__.py +0 -0
  442. cartography/models/gcp/bigtable/__init__.py +0 -0
  443. cartography/models/gcp/bigtable/app_profile.py +94 -0
  444. cartography/models/gcp/bigtable/backup.py +91 -0
  445. cartography/models/gcp/bigtable/cluster.py +73 -0
  446. cartography/models/gcp/bigtable/instance.py +52 -0
  447. cartography/models/gcp/bigtable/table.py +69 -0
  448. cartography/models/gcp/compute/__init__.py +0 -0
  449. cartography/models/gcp/compute/subnet.py +74 -0
  450. cartography/models/gcp/compute/vpc.py +50 -0
  451. cartography/models/gcp/crm/__init__.py +0 -0
  452. cartography/models/gcp/crm/folders.py +98 -0
  453. cartography/models/gcp/crm/organizations.py +21 -0
  454. cartography/models/gcp/crm/projects.py +100 -0
  455. cartography/models/gcp/dns.py +109 -0
  456. cartography/models/gcp/gke.py +69 -0
  457. cartography/models/gcp/iam.py +3 -0
  458. cartography/models/gcp/permission_relationships.py +61 -0
  459. cartography/models/gcp/policy_bindings.py +93 -0
  460. cartography/models/gcp/storage/__init__.py +0 -0
  461. cartography/models/gcp/storage/bucket.py +119 -0
  462. cartography/models/github/commits.py +63 -0
  463. cartography/models/github/dependencies.py +73 -0
  464. cartography/models/github/manifests.py +49 -0
  465. cartography/models/github/users.py +10 -0
  466. cartography/models/googleworkspace/__init__.py +0 -0
  467. cartography/models/googleworkspace/device.py +132 -0
  468. cartography/models/googleworkspace/group.py +382 -0
  469. cartography/models/googleworkspace/oauth_app.py +124 -0
  470. cartography/models/googleworkspace/tenant.py +30 -0
  471. cartography/models/googleworkspace/user.py +113 -0
  472. cartography/models/gsuite/__init__.py +0 -0
  473. cartography/models/gsuite/group.py +218 -0
  474. cartography/models/gsuite/tenant.py +29 -0
  475. cartography/models/gsuite/user.py +107 -0
  476. cartography/models/kandji/device.py +1 -2
  477. cartography/models/keycloak/__init__.py +0 -0
  478. cartography/models/keycloak/authenticationexecution.py +160 -0
  479. cartography/models/keycloak/authenticationflow.py +54 -0
  480. cartography/models/keycloak/client.py +179 -0
  481. cartography/models/keycloak/group.py +101 -0
  482. cartography/models/keycloak/identityprovider.py +89 -0
  483. cartography/models/keycloak/organization.py +116 -0
  484. cartography/models/keycloak/organizationdomain.py +73 -0
  485. cartography/models/keycloak/realm.py +173 -0
  486. cartography/models/keycloak/role.py +126 -0
  487. cartography/models/keycloak/scope.py +73 -0
  488. cartography/models/keycloak/user.py +55 -0
  489. cartography/models/kubernetes/__init__.py +0 -0
  490. cartography/models/kubernetes/clusterrolebindings.py +138 -0
  491. cartography/models/kubernetes/clusterroles.py +52 -0
  492. cartography/models/kubernetes/clusters.py +26 -0
  493. cartography/models/kubernetes/containers.py +133 -0
  494. cartography/models/kubernetes/groups.py +107 -0
  495. cartography/models/kubernetes/namespaces.py +51 -0
  496. cartography/models/kubernetes/oidc.py +51 -0
  497. cartography/models/kubernetes/pods.py +80 -0
  498. cartography/models/kubernetes/rolebindings.py +159 -0
  499. cartography/models/kubernetes/roles.py +76 -0
  500. cartography/models/kubernetes/secrets.py +79 -0
  501. cartography/models/kubernetes/serviceaccounts.py +77 -0
  502. cartography/models/kubernetes/services.py +108 -0
  503. cartography/models/kubernetes/users.py +105 -0
  504. cartography/models/lastpass/user.py +4 -0
  505. cartography/models/ontology/__init__.py +0 -0
  506. cartography/models/ontology/device.py +137 -0
  507. cartography/models/ontology/mapping/__init__.py +76 -0
  508. cartography/models/ontology/mapping/data/__init__.py +0 -0
  509. cartography/models/ontology/mapping/data/apikeys.py +93 -0
  510. cartography/models/ontology/mapping/data/computeinstance.py +95 -0
  511. cartography/models/ontology/mapping/data/containers.py +88 -0
  512. cartography/models/ontology/mapping/data/databases.py +182 -0
  513. cartography/models/ontology/mapping/data/devices.py +194 -0
  514. cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
  515. cartography/models/ontology/mapping/data/useraccounts.py +416 -0
  516. cartography/models/ontology/mapping/data/users.py +63 -0
  517. cartography/models/ontology/mapping/specs.py +85 -0
  518. cartography/models/ontology/user.py +51 -0
  519. cartography/models/openai/adminapikey.py +4 -0
  520. cartography/models/openai/apikey.py +4 -0
  521. cartography/models/openai/user.py +4 -0
  522. cartography/models/scaleway/__init__.py +0 -0
  523. cartography/models/scaleway/iam/__init__.py +0 -0
  524. cartography/models/scaleway/iam/apikey.py +100 -0
  525. cartography/models/scaleway/iam/application.py +52 -0
  526. cartography/models/scaleway/iam/group.py +95 -0
  527. cartography/models/scaleway/iam/user.py +64 -0
  528. cartography/models/scaleway/instance/__init__.py +0 -0
  529. cartography/models/scaleway/instance/flexibleip.py +52 -0
  530. cartography/models/scaleway/instance/instance.py +120 -0
  531. cartography/models/scaleway/organization.py +19 -0
  532. cartography/models/scaleway/project.py +48 -0
  533. cartography/models/scaleway/storage/__init__.py +0 -0
  534. cartography/models/scaleway/storage/snapshot.py +78 -0
  535. cartography/models/scaleway/storage/volume.py +51 -0
  536. cartography/models/sentinelone/__init__.py +1 -0
  537. cartography/models/sentinelone/account.py +40 -0
  538. cartography/models/sentinelone/agent.py +50 -0
  539. cartography/models/sentinelone/application.py +44 -0
  540. cartography/models/sentinelone/application_version.py +96 -0
  541. cartography/models/sentinelone/cve.py +73 -0
  542. cartography/models/slack/__init__.py +0 -0
  543. cartography/models/slack/channels.py +92 -0
  544. cartography/models/slack/group.py +129 -0
  545. cartography/models/slack/team.py +22 -0
  546. cartography/models/slack/user.py +62 -0
  547. cartography/models/snipeit/asset.py +2 -0
  548. cartography/models/snipeit/user.py +4 -0
  549. cartography/models/spacelift/__init__.py +0 -0
  550. cartography/models/spacelift/cloudtrailevent.py +120 -0
  551. cartography/models/spacelift/run.py +162 -0
  552. cartography/models/spacelift/space.py +131 -0
  553. cartography/models/spacelift/spaceliftaccount.py +31 -0
  554. cartography/models/spacelift/spaceliftgitcommit.py +157 -0
  555. cartography/models/spacelift/stack.py +96 -0
  556. cartography/models/spacelift/user.py +63 -0
  557. cartography/models/spacelift/worker.py +97 -0
  558. cartography/models/spacelift/workerpool.py +90 -0
  559. cartography/models/tailscale/device.py +2 -1
  560. cartography/models/tailscale/user.py +6 -1
  561. cartography/models/trivy/__init__.py +0 -0
  562. cartography/models/trivy/findings.py +66 -0
  563. cartography/models/trivy/fix.py +66 -0
  564. cartography/models/trivy/package.py +71 -0
  565. cartography/rules/README.md +1 -0
  566. cartography/rules/__init__.py +0 -0
  567. cartography/rules/cli.py +261 -0
  568. cartography/rules/data/__init__.py +0 -0
  569. cartography/rules/data/rules/__init__.py +46 -0
  570. cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
  571. cartography/rules/data/rules/compute_instance_exposed.py +51 -0
  572. cartography/rules/data/rules/database_instance_exposed.py +53 -0
  573. cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
  574. cartography/rules/data/rules/identity_administration_privileges.py +100 -0
  575. cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
  576. cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
  577. cartography/rules/data/rules/mfa_missing.py +46 -0
  578. cartography/rules/data/rules/object_storage_public.py +100 -0
  579. cartography/rules/data/rules/policy_administration_privileges.py +104 -0
  580. cartography/rules/data/rules/unmanaged_accounts.py +43 -0
  581. cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
  582. cartography/rules/formatters.py +108 -0
  583. cartography/rules/runners.py +216 -0
  584. cartography/rules/spec/__init__.py +0 -0
  585. cartography/rules/spec/model.py +267 -0
  586. cartography/rules/spec/result.py +38 -0
  587. cartography/sync.py +25 -5
  588. cartography/util.py +101 -31
  589. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/METADATA +61 -22
  590. cartography-0.123.0.dist-info/RECORD +856 -0
  591. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
  592. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  593. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  594. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  595. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  596. cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +0 -16
  597. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  598. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  599. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  600. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  601. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  602. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  603. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  604. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  605. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  606. cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
  607. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  608. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  609. cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
  610. cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
  611. cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
  612. cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
  613. cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
  614. cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
  615. cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
  616. cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
  617. cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
  618. cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
  619. cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
  620. cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
  621. cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
  622. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  623. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  624. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  625. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  626. cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
  627. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  628. cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
  629. cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
  630. cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
  631. cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
  632. cartography/intel/gcp/crm.py +0 -355
  633. cartography/intel/gsuite/api.py +0 -342
  634. cartography-0.104.0rc2.dist-info/RECORD +0 -455
  635. /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
  636. /cartography/models/aws/{apigateway.py → apigateway/apigateway.py} +0 -0
  637. /cartography/models/aws/{apigatewaycertificate.py → apigateway/apigatewaycertificate.py} +0 -0
  638. /cartography/models/aws/{apigatewayresource.py → apigateway/apigatewayresource.py} +0 -0
  639. /cartography/models/aws/{apigatewaystage.py → apigateway/apigatewaystage.py} +0 -0
  640. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/WHEEL +0 -0
  641. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/licenses/LICENSE +0 -0
  642. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
@@ -16,7 +16,9 @@ from botocore.exceptions import ClientError
16
16
  from botocore.exceptions import EndpointConnectionError
17
17
  from policyuniverse.policy import Policy
18
18
 
19
+ from cartography.client.core.tx import run_write_query
19
20
  from cartography.stats import get_stats_client
21
+ from cartography.util import aws_handle_regions
20
22
  from cartography.util import merge_module_sync_metadata
21
23
  from cartography.util import run_analysis_job
22
24
  from cartography.util import run_cleanup_job
@@ -54,7 +56,7 @@ def get_s3_bucket_list(boto3_session: boto3.session.Session) -> List[Dict]:
54
56
  def get_s3_bucket_details(
55
57
  boto3_session: boto3.session.Session,
56
58
  bucket_data: Dict,
57
- ) -> Generator[Tuple[str, Dict, Dict, Dict, Dict, Dict], None, None]:
59
+ ) -> Generator[Tuple[str, Dict, Dict, Dict, Dict, Dict, Dict], None, None]:
58
60
  """
59
61
  Iterates over all S3 buckets. Yields bucket name (string), S3 bucket policies (JSON), ACLs (JSON),
60
62
  default encryption policy (JSON), Versioning (JSON), and Public Access Block (JSON)
@@ -69,6 +71,8 @@ def get_s3_bucket_details(
69
71
  Dict[str, Any],
70
72
  Dict[str, Any],
71
73
  Dict[str, Any],
74
+ Dict[str, Any],
75
+ Dict[str, Any],
72
76
  ]
73
77
 
74
78
  async def _get_bucket_detail(bucket: Dict[str, Any]) -> BucketDetail:
@@ -85,14 +89,27 @@ def get_s3_bucket_details(
85
89
  encryption,
86
90
  versioning,
87
91
  public_access_block,
92
+ bucket_ownership_controls,
93
+ bucket_logging,
88
94
  ) = await asyncio.gather(
89
95
  to_asynchronous(get_acl, bucket, client),
90
96
  to_asynchronous(get_policy, bucket, client),
91
97
  to_asynchronous(get_encryption, bucket, client),
92
98
  to_asynchronous(get_versioning, bucket, client),
93
99
  to_asynchronous(get_public_access_block, bucket, client),
100
+ to_asynchronous(get_bucket_ownership_controls, bucket, client),
101
+ to_asynchronous(get_bucket_logging, bucket, client),
102
+ )
103
+ return (
104
+ bucket["Name"],
105
+ acl,
106
+ policy,
107
+ encryption,
108
+ versioning,
109
+ public_access_block,
110
+ bucket_ownership_controls,
111
+ bucket_logging,
94
112
  )
95
- return bucket["Name"], acl, policy, encryption, versioning, public_access_block
96
113
 
97
114
  bucket_details = to_synchronous(
98
115
  *[_get_bucket_detail(bucket) for bucket in bucket_data["Buckets"]],
@@ -204,6 +221,54 @@ def get_public_access_block(
204
221
  return public_access_block
205
222
 
206
223
 
224
+ @timeit
225
+ def get_bucket_ownership_controls(
226
+ bucket: Dict, client: botocore.client.BaseClient
227
+ ) -> Optional[Dict]:
228
+ """
229
+ Gets the S3 object ownership controls configuration.
230
+ """
231
+ bucket_ownership_controls = None
232
+ try:
233
+ bucket_ownership_controls = client.get_bucket_ownership_controls(
234
+ Bucket=bucket["Name"]
235
+ )
236
+ except ClientError as e:
237
+ if _is_common_exception(e, bucket):
238
+ pass
239
+ else:
240
+ raise
241
+ except EndpointConnectionError:
242
+ logger.warning(
243
+ f"Failed to retrieve S3 bucket ownership controls for {bucket['Name']}"
244
+ " - Could not connect to the endpoint URL",
245
+ )
246
+ return bucket_ownership_controls
247
+
248
+
249
+ @timeit
250
+ @aws_handle_regions
251
+ def get_bucket_logging(
252
+ bucket: Dict, client: botocore.client.BaseClient
253
+ ) -> Optional[Dict]:
254
+ """
255
+ Gets the S3 bucket logging status configuration.
256
+ """
257
+ bucket_logging = None
258
+ try:
259
+ bucket_logging = client.get_bucket_logging(Bucket=bucket["Name"])
260
+ except ClientError as e:
261
+ if _is_common_exception(e, bucket):
262
+ pass
263
+ else:
264
+ raise
265
+ except EndpointConnectionError:
266
+ logger.warning(
267
+ f"Failed to retrieve S3 bucket logging status for {bucket['Name']} - Could not connect to the endpoint URL",
268
+ )
269
+ return bucket_logging
270
+
271
+
207
272
  @timeit
208
273
  def _is_common_exception(e: Exception, bucket: Dict) -> bool:
209
274
  error_msg = "Failed to retrieve S3 bucket detail"
@@ -240,6 +305,11 @@ def _is_common_exception(e: Exception, bucket: Dict) -> bool:
240
305
  f"{error_msg} for {bucket['Name']} - IllegalLocationConstraintException",
241
306
  )
242
307
  return True
308
+ elif "OwnershipControlsNotFoundError" in e.args[0]:
309
+ logger.warning(
310
+ f"{error_msg} for {bucket['Name']} - OwnershipControlsNotFoundError"
311
+ )
312
+ return True
243
313
  return False
244
314
 
245
315
 
@@ -265,7 +335,8 @@ def _load_s3_acls(
265
335
  SET r.lastupdated = $UpdateTag
266
336
  """
267
337
 
268
- neo4j_session.run(
338
+ run_write_query(
339
+ neo4j_session,
269
340
  ingest_acls,
270
341
  acls=acls,
271
342
  UpdateTag=update_tag,
@@ -277,6 +348,7 @@ def _load_s3_acls(
277
348
  "aws_s3acl_analysis.json",
278
349
  neo4j_session,
279
350
  {"AWS_ID": aws_account_id},
351
+ package="cartography.data.jobs.scoped_analysis",
280
352
  )
281
353
 
282
354
 
@@ -298,7 +370,8 @@ def _load_s3_policies(
298
370
  s.lastupdated = $UpdateTag
299
371
  """
300
372
 
301
- neo4j_session.run(
373
+ run_write_query(
374
+ neo4j_session,
302
375
  ingest_policies,
303
376
  policies=policies,
304
377
  UpdateTag=update_tag,
@@ -331,11 +404,12 @@ def _load_s3_policy_statements(
331
404
  MERGE (bucket)-[r:POLICY_STATEMENT]->(statement)
332
405
  SET r.lastupdated = $UpdateTag
333
406
  """
334
- neo4j_session.run(
407
+ run_write_query(
408
+ neo4j_session,
335
409
  ingest_policy_statement,
336
410
  Statements=statements,
337
411
  UpdateTag=update_tag,
338
- ).consume()
412
+ )
339
413
 
340
414
 
341
415
  @timeit
@@ -357,7 +431,8 @@ def _load_s3_encryption(
357
431
  s.lastupdated = $UpdateTag
358
432
  """
359
433
 
360
- neo4j_session.run(
434
+ run_write_query(
435
+ neo4j_session,
361
436
  ingest_encryption,
362
437
  encryption_configs=encryption_configs,
363
438
  UpdateTag=update_tag,
@@ -381,7 +456,8 @@ def _load_s3_versioning(
381
456
  s.lastupdated = $UpdateTag
382
457
  """
383
458
 
384
- neo4j_session.run(
459
+ run_write_query(
460
+ neo4j_session,
385
461
  ingest_versioning,
386
462
  versioning_configs=versioning_configs,
387
463
  UpdateTag=update_tag,
@@ -407,19 +483,70 @@ def _load_s3_public_access_block(
407
483
  s.lastupdated = $UpdateTag
408
484
  """
409
485
 
410
- neo4j_session.run(
486
+ run_write_query(
487
+ neo4j_session,
411
488
  ingest_public_access_block,
412
489
  public_access_block_configs=public_access_block_configs,
413
490
  UpdateTag=update_tag,
414
491
  )
415
492
 
416
493
 
494
+ @timeit
495
+ def _load_bucket_ownership_controls(
496
+ neo4j_session: neo4j.Session,
497
+ bucket_ownership_controls_configs: List[Dict],
498
+ update_tag: int,
499
+ ) -> None:
500
+ """
501
+ Ingest S3 BucketOwnershipControls results into neo4j.
502
+ """
503
+ ingest_bucket_ownership_controls = """
504
+ UNWIND $bucket_ownership_controls_configs AS bucket_ownership_controls
505
+ MATCH (s:S3Bucket) where s.name = bucket_ownership_controls.bucket
506
+ SET s.object_ownership = bucket_ownership_controls.object_ownership,
507
+ s.lastupdated = $UpdateTag
508
+ """
509
+
510
+ run_write_query(
511
+ neo4j_session,
512
+ ingest_bucket_ownership_controls,
513
+ bucket_ownership_controls_configs=bucket_ownership_controls_configs,
514
+ UpdateTag=update_tag,
515
+ )
516
+
517
+
518
+ @timeit
519
+ def _load_bucket_logging(
520
+ neo4j_session: neo4j.Session,
521
+ bucket_logging_configs: List[Dict],
522
+ update_tag: int,
523
+ ) -> None:
524
+ """
525
+ Ingest S3 bucket logging status configuration into neo4j.
526
+ """
527
+ # Load basic logging status
528
+ ingest_bucket_logging = """
529
+ UNWIND $bucket_logging_configs AS bucket_logging
530
+ MATCH (bucket:S3Bucket{name: bucket_logging.bucket})
531
+ SET bucket.logging_enabled = bucket_logging.logging_enabled,
532
+ bucket.logging_target_bucket = bucket_logging.target_bucket,
533
+ bucket.lastupdated = $update_tag
534
+ """
535
+ run_write_query(
536
+ neo4j_session,
537
+ ingest_bucket_logging,
538
+ bucket_logging_configs=bucket_logging_configs,
539
+ update_tag=update_tag,
540
+ )
541
+
542
+
417
543
  def _set_default_values(neo4j_session: neo4j.Session, aws_account_id: str) -> None:
418
544
  set_defaults = """
419
545
  MATCH (:AWSAccount{id: $AWS_ID})-[:RESOURCE]->(s:S3Bucket) where s.anonymous_actions IS NULL
420
546
  SET s.anonymous_access = false, s.anonymous_actions = []
421
547
  """
422
- neo4j_session.run(
548
+ run_write_query(
549
+ neo4j_session,
423
550
  set_defaults,
424
551
  AWS_ID=aws_account_id,
425
552
  )
@@ -428,7 +555,8 @@ def _set_default_values(neo4j_session: neo4j.Session, aws_account_id: str) -> No
428
555
  MATCH (:AWSAccount{id: $AWS_ID})-[:RESOURCE]->(s:S3Bucket) where s.default_encryption IS NULL
429
556
  SET s.default_encryption = false
430
557
  """
431
- neo4j_session.run(
558
+ run_write_query(
559
+ neo4j_session,
432
560
  set_encryption_defaults,
433
561
  AWS_ID=aws_account_id,
434
562
  )
@@ -450,6 +578,8 @@ def load_s3_details(
450
578
  encryption_configs: List[Dict] = []
451
579
  versioning_configs: List[Dict] = []
452
580
  public_access_block_configs: List[Dict] = []
581
+ bucket_ownership_controls_configs: List[Dict] = []
582
+ bucket_logging_configs: List[Dict] = []
453
583
  for (
454
584
  bucket,
455
585
  acl,
@@ -457,6 +587,8 @@ def load_s3_details(
457
587
  encryption,
458
588
  versioning,
459
589
  public_access_block,
590
+ bucket_ownership_controls,
591
+ bucket_logging,
460
592
  ) in s3_details_iter:
461
593
  parsed_acls = parse_acl(acl, bucket, aws_account_id)
462
594
  if parsed_acls is not None:
@@ -479,6 +611,14 @@ def load_s3_details(
479
611
  )
480
612
  if parsed_public_access_block is not None:
481
613
  public_access_block_configs.append(parsed_public_access_block)
614
+ parsed_bucket_ownership_controls = parse_bucket_ownership_controls(
615
+ bucket, bucket_ownership_controls
616
+ )
617
+ if parsed_bucket_ownership_controls is not None:
618
+ bucket_ownership_controls_configs.append(parsed_bucket_ownership_controls)
619
+ parsed_bucket_logging = parse_bucket_logging(bucket, bucket_logging)
620
+ if parsed_bucket_logging is not None:
621
+ bucket_logging_configs.append(parsed_bucket_logging)
482
622
 
483
623
  # cleanup existing policy properties set on S3 Buckets
484
624
  run_cleanup_job(
@@ -494,6 +634,10 @@ def load_s3_details(
494
634
  _load_s3_encryption(neo4j_session, encryption_configs, update_tag)
495
635
  _load_s3_versioning(neo4j_session, versioning_configs, update_tag)
496
636
  _load_s3_public_access_block(neo4j_session, public_access_block_configs, update_tag)
637
+ _load_bucket_ownership_controls(
638
+ neo4j_session, bucket_ownership_controls_configs, update_tag
639
+ )
640
+ _load_bucket_logging(neo4j_session, bucket_logging_configs, update_tag)
497
641
  _set_default_values(neo4j_session, aws_account_id)
498
642
 
499
643
 
@@ -751,6 +895,123 @@ def parse_public_access_block(
751
895
  }
752
896
 
753
897
 
898
+ @timeit
899
+ def parse_bucket_ownership_controls(
900
+ bucket: str, bucket_ownership_controls: Optional[Dict]
901
+ ) -> Optional[Dict]:
902
+ """Parses the S3 bucket ownership controls object and returns a dict of the relevant data"""
903
+ # Versioning object JSON looks like:
904
+ # {
905
+ # 'OwnershipControls': {
906
+ # 'Rules': [
907
+ # {
908
+ # 'ObjectOwnership': 'BucketOwnerPreferred'|'ObjectWriter'|'BucketOwnerEnforced'
909
+ # },
910
+ # ]
911
+ # }
912
+ # }
913
+ if bucket_ownership_controls is None:
914
+ return None
915
+ return {
916
+ "bucket": bucket,
917
+ "object_ownership": bucket_ownership_controls.get("OwnershipControls", {})
918
+ .get("Rules", [{}])[0]
919
+ .get("ObjectOwnership"),
920
+ }
921
+
922
+
923
+ def parse_bucket_logging(bucket: str, bucket_logging: Optional[Dict]) -> Optional[Dict]:
924
+ """Parses the S3 bucket logging status configuration and returns a dict of the relevant data"""
925
+ # Logging status object JSON looks like:
926
+ # {
927
+ # 'LoggingEnabled': {
928
+ # 'TargetBucket': 'string',
929
+ # 'TargetGrants': [
930
+ # {
931
+ # 'Grantee': {
932
+ # 'DisplayName': 'string',
933
+ # 'EmailAddress': 'string',
934
+ # 'ID': 'string',
935
+ # 'Type': 'CanonicalUser'|'AmazonCustomerByEmail'|'Group',
936
+ # 'URI': 'string'
937
+ # },
938
+ # 'Permission': 'FULL_CONTROL'|'READ'|'WRITE'
939
+ # },
940
+ # ],
941
+ # 'TargetPrefix': 'string',
942
+ # 'TargetObjectKeyFormat': {
943
+ # 'SimplePrefix': {},
944
+ # 'PartitionedPrefix': {
945
+ # 'PartitionDateSource': 'EventTime'|'DeliveryTime'
946
+ # }
947
+ # }
948
+ # }
949
+ # }
950
+ # Or empty dict {} if logging is not enabled
951
+ if bucket_logging is None:
952
+ return None
953
+
954
+ logging_config = bucket_logging.get("LoggingEnabled", {})
955
+ if not logging_config:
956
+ return {
957
+ "bucket": bucket,
958
+ "logging_enabled": False,
959
+ "target_bucket": None,
960
+ }
961
+
962
+ return {
963
+ "bucket": bucket,
964
+ "logging_enabled": True,
965
+ "target_bucket": logging_config.get("TargetBucket"),
966
+ }
967
+
968
+
969
+ @timeit
970
+ def parse_notification_configuration(
971
+ bucket: str, notification_config: Optional[Dict]
972
+ ) -> List[Dict]:
973
+ """
974
+ Parse S3 bucket notification configuration to extract SNS topic notifications.
975
+ Returns a list of notification configurations.
976
+ """
977
+ if not notification_config or "TopicConfigurations" not in notification_config:
978
+ return []
979
+
980
+ notifications = []
981
+ for topic_config in notification_config.get("TopicConfigurations", []):
982
+ notification = {
983
+ "bucket": bucket,
984
+ "TopicArn": topic_config["TopicArn"],
985
+ }
986
+ notifications.append(notification)
987
+ return notifications
988
+
989
+
990
+ @timeit
991
+ def _load_s3_notifications(
992
+ neo4j_session: neo4j.Session,
993
+ notifications: List[Dict],
994
+ update_tag: int,
995
+ ) -> None:
996
+ """
997
+ Ingest S3 bucket to SNS topic notification relationships into neo4j.
998
+ """
999
+ ingest_notifications = """
1000
+ UNWIND $notifications AS notification
1001
+ MATCH (bucket:S3Bucket{name: notification.bucket})
1002
+ MATCH (topic:SNSTopic{arn: notification.TopicArn})
1003
+ MERGE (bucket)-[r:NOTIFIES]->(topic)
1004
+ ON CREATE SET r.firstseen = timestamp()
1005
+ SET r.lastupdated = $UpdateTag
1006
+ """
1007
+ run_write_query(
1008
+ neo4j_session,
1009
+ ingest_notifications,
1010
+ notifications=notifications,
1011
+ UpdateTag=update_tag,
1012
+ )
1013
+
1014
+
754
1015
  @timeit
755
1016
  def load_s3_buckets(
756
1017
  neo4j_session: neo4j.Session,
@@ -776,7 +1037,8 @@ def load_s3_buckets(
776
1037
 
777
1038
  for bucket in data["Buckets"]:
778
1039
  arn = "arn:aws:s3:::" + bucket["Name"]
779
- neo4j_session.run(
1040
+ run_write_query(
1041
+ neo4j_session,
780
1042
  ingest_bucket,
781
1043
  BucketName=bucket["Name"],
782
1044
  BucketRegion=bucket["Region"],
@@ -811,6 +1073,43 @@ def cleanup_s3_bucket_acl_and_policy(
811
1073
  )
812
1074
 
813
1075
 
1076
+ @timeit
1077
+ @aws_handle_regions
1078
+ def _sync_s3_notifications(
1079
+ neo4j_session: neo4j.Session,
1080
+ boto3_session: boto3.session.Session,
1081
+ bucket_data: Dict,
1082
+ update_tag: int,
1083
+ ) -> None:
1084
+ """
1085
+ Sync S3 bucket notification configurations to Neo4j.
1086
+ """
1087
+ logger.info("Syncing S3 bucket notifications")
1088
+ s3_client = boto3_session.client("s3")
1089
+ notifications = []
1090
+
1091
+ for bucket in bucket_data["Buckets"]:
1092
+ try:
1093
+ notification_config = s3_client.get_bucket_notification_configuration(
1094
+ Bucket=bucket["Name"]
1095
+ )
1096
+ parsed_notifications = parse_notification_configuration(
1097
+ bucket["Name"], notification_config
1098
+ )
1099
+ notifications.extend(parsed_notifications)
1100
+ logger.debug(
1101
+ f"Found {len(parsed_notifications)} notifications for bucket {bucket['Name']}"
1102
+ )
1103
+ except ClientError as e:
1104
+ logger.warning(
1105
+ f"Failed to retrieve notification configuration for bucket {bucket['Name']}: {e}"
1106
+ )
1107
+ continue
1108
+
1109
+ logger.info(f"Loading {len(notifications)} S3 bucket notifications into Neo4j")
1110
+ _load_s3_notifications(neo4j_session, notifications, update_tag)
1111
+
1112
+
814
1113
  @timeit
815
1114
  def sync(
816
1115
  neo4j_session: neo4j.Session,
@@ -820,9 +1119,16 @@ def sync(
820
1119
  update_tag: int,
821
1120
  common_job_parameters: Dict,
822
1121
  ) -> None:
823
- logger.info("Syncing S3 for account '%s'.", current_aws_account_id)
824
- bucket_data = get_s3_bucket_list(boto3_session)
1122
+ """
1123
+ Sync S3 buckets and their configurations to Neo4j.
1124
+ This includes:
1125
+ 1. Basic bucket information
1126
+ 2. ACLs and policies
1127
+ 3. Notification configurations
1128
+ """
1129
+ logger.info("Syncing S3 for account '%s'", current_aws_account_id)
825
1130
 
1131
+ bucket_data = get_s3_bucket_list(boto3_session)
826
1132
  load_s3_buckets(neo4j_session, bucket_data, current_aws_account_id, update_tag)
827
1133
  cleanup_s3_buckets(neo4j_session, common_job_parameters)
828
1134
 
@@ -835,6 +1141,8 @@ def sync(
835
1141
  )
836
1142
  cleanup_s3_bucket_acl_and_policy(neo4j_session, common_job_parameters)
837
1143
 
1144
+ _sync_s3_notifications(neo4j_session, boto3_session, bucket_data, update_tag)
1145
+
838
1146
  merge_module_sync_metadata(
839
1147
  neo4j_session,
840
1148
  group_type="AWSAccount",