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
@@ -0,0 +1,181 @@
1
+ import logging
2
+ from typing import Any
3
+ from typing import Dict
4
+ from typing import List
5
+
6
+ import boto3
7
+ import neo4j
8
+
9
+ from cartography.client.core.tx import load
10
+ from cartography.graph.job import GraphJob
11
+ from cartography.intel.aws.ec2.util import get_botocore_config
12
+ from cartography.models.aws.glue.connection import GlueConnectionSchema
13
+ from cartography.models.aws.glue.job import GlueJobSchema
14
+ from cartography.util import aws_handle_regions
15
+ from cartography.util import timeit
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ @timeit
21
+ @aws_handle_regions
22
+ def get_glue_connections(
23
+ boto3_session: boto3.Session, region: str
24
+ ) -> List[Dict[str, Any]]:
25
+ client = boto3_session.client(
26
+ "glue", region_name=region, config=get_botocore_config()
27
+ )
28
+ paginator = client.get_paginator("get_connections")
29
+ connections = []
30
+ for page in paginator.paginate():
31
+ connections.extend(page.get("ConnectionList", []))
32
+
33
+ return connections
34
+
35
+
36
+ @timeit
37
+ @aws_handle_regions
38
+ def get_glue_jobs(boto3_session: boto3.Session, region: str) -> List[Dict[str, Any]]:
39
+ client = boto3_session.client(
40
+ "glue", region_name=region, config=get_botocore_config()
41
+ )
42
+ paginator = client.get_paginator("get_jobs")
43
+ jobs = []
44
+ for page in paginator.paginate():
45
+ jobs.extend(page.get("Jobs", []))
46
+ return jobs
47
+
48
+
49
+ def transform_glue_job(jobs: List[Dict[str, Any]], region: str) -> List[Dict[str, Any]]:
50
+ """
51
+ Transform Glue job data for ingestion
52
+ """
53
+ transformed_jobs = []
54
+ for job in jobs:
55
+ transformed_job = {
56
+ "Name": job["Name"],
57
+ "ProfileName": job.get("ProfileName"),
58
+ "JobMode": job.get("JobMode"),
59
+ "Connections": job.get("Connections", {}).get("Connections"),
60
+ "Region": region,
61
+ "Description": job.get("Description"),
62
+ }
63
+ transformed_jobs.append(transformed_job)
64
+ return transformed_jobs
65
+
66
+
67
+ def transform_glue_connections(
68
+ connections: List[Dict[str, Any]], region: str
69
+ ) -> List[Dict[str, Any]]:
70
+ """
71
+ Transform Glue connection data for ingestion
72
+ """
73
+ transformed_connections = []
74
+ for connection in connections:
75
+ transformed_connection = {
76
+ "Name": connection["Name"],
77
+ "Description": connection.get("Description"),
78
+ "ConnectionType": connection.get("ConnectionType"),
79
+ "Status": connection.get("Status"),
80
+ "StatusReason": connection.get("StatusReason"),
81
+ "AuthenticationType": connection.get("AuthenticationConfiguration", {}).get(
82
+ "AuthenticationType"
83
+ ),
84
+ "SecretArn": connection.get("AuthenticationConfiguration", {}).get(
85
+ "SecretArn"
86
+ ),
87
+ "Region": region,
88
+ }
89
+ transformed_connections.append(transformed_connection)
90
+ return transformed_connections
91
+
92
+
93
+ @timeit
94
+ def load_glue_connections(
95
+ neo4j_session: neo4j.Session,
96
+ data: List[Dict[str, Any]],
97
+ region: str,
98
+ current_aws_account_id: str,
99
+ aws_update_tag: int,
100
+ ) -> None:
101
+ logger.info(
102
+ f"Loading Glue {len(data)} connections for region '{region}' into graph.",
103
+ )
104
+ load(
105
+ neo4j_session,
106
+ GlueConnectionSchema(),
107
+ data,
108
+ lastupdated=aws_update_tag,
109
+ Region=region,
110
+ AWS_ID=current_aws_account_id,
111
+ )
112
+
113
+
114
+ @timeit
115
+ def load_glue_jobs(
116
+ neo4j_session: neo4j.Session,
117
+ data: List[Dict[str, Any]],
118
+ region: str,
119
+ current_aws_account_id: str,
120
+ aws_update_tag: int,
121
+ ) -> None:
122
+ logger.info(
123
+ f"Loading Glue {len(data)} jobs for region '{region}' into graph.",
124
+ )
125
+ load(
126
+ neo4j_session,
127
+ GlueJobSchema(),
128
+ data,
129
+ lastupdated=aws_update_tag,
130
+ Region=region,
131
+ AWS_ID=current_aws_account_id,
132
+ )
133
+
134
+
135
+ @timeit
136
+ def cleanup(
137
+ neo4j_session: neo4j.Session,
138
+ common_job_parameters: Dict[str, Any],
139
+ ) -> None:
140
+ logger.debug("Running Glue cleanup job.")
141
+ GraphJob.from_node_schema(GlueConnectionSchema(), common_job_parameters).run(
142
+ neo4j_session
143
+ )
144
+ GraphJob.from_node_schema(GlueJobSchema(), common_job_parameters).run(neo4j_session)
145
+
146
+
147
+ @timeit
148
+ def sync(
149
+ neo4j_session: neo4j.Session,
150
+ boto3_session: boto3.session.Session,
151
+ regions: List[str],
152
+ current_aws_account_id: str,
153
+ update_tag: int,
154
+ common_job_parameters: Dict[str, Any],
155
+ ) -> None:
156
+ for region in regions:
157
+ logger.info(
158
+ f"Syncing Glue for region '{region}' in account '{current_aws_account_id}'.",
159
+ )
160
+
161
+ connections = get_glue_connections(boto3_session, region)
162
+ transformed_connections = transform_glue_connections(connections, region)
163
+ load_glue_connections(
164
+ neo4j_session,
165
+ transformed_connections,
166
+ region,
167
+ current_aws_account_id,
168
+ update_tag,
169
+ )
170
+
171
+ jobs = get_glue_jobs(boto3_session, region)
172
+ transformed_jobs = transform_glue_job(jobs, region)
173
+ load_glue_jobs(
174
+ neo4j_session,
175
+ transformed_jobs,
176
+ region,
177
+ current_aws_account_id,
178
+ update_tag,
179
+ )
180
+
181
+ cleanup(neo4j_session, common_job_parameters)
@@ -0,0 +1,443 @@
1
+ import logging
2
+ from typing import Any
3
+
4
+ import boto3
5
+ import boto3.session
6
+ import neo4j
7
+
8
+ from cartography.client.core.tx import load
9
+ from cartography.graph.job import GraphJob
10
+ from cartography.models.aws.guardduty.detectors import GuardDutyDetectorSchema
11
+ from cartography.models.aws.guardduty.findings import GuardDutyFindingSchema
12
+ from cartography.stats import get_stats_client
13
+ from cartography.util import aws_handle_regions
14
+ from cartography.util import aws_paginate
15
+ from cartography.util import merge_module_sync_metadata
16
+ from cartography.util import timeit
17
+
18
+ logger = logging.getLogger(__name__)
19
+ stat_handler = get_stats_client(__name__)
20
+
21
+
22
+ def _get_severity_range_for_threshold(
23
+ severity_threshold: str | None,
24
+ ) -> list[str] | None:
25
+ """
26
+ Convert severity threshold string to GuardDuty numeric severity range.
27
+
28
+ GuardDuty severity mappings:
29
+ - LOW: 1.0-3.9
30
+ - MEDIUM: 4.0-6.9
31
+ - HIGH: 7.0-8.9
32
+ - CRITICAL: 9.0-10.0
33
+
34
+ :param severity_threshold: Severity threshold (LOW, MEDIUM, HIGH, CRITICAL)
35
+ :return: List of numeric severity ranges to include, or None for no filtering
36
+ """
37
+ if not severity_threshold:
38
+ return None
39
+
40
+ threshold_upper = severity_threshold.upper().strip()
41
+
42
+ # Map threshold to numeric ranges - include threshold level and above
43
+ if threshold_upper == "LOW":
44
+ return ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] # All severities
45
+ elif threshold_upper == "MEDIUM":
46
+ return ["4", "5", "6", "7", "8", "9", "10"] # MEDIUM and above
47
+ elif threshold_upper == "HIGH":
48
+ return ["7", "8", "9", "10"] # HIGH and CRITICAL only
49
+ elif threshold_upper == "CRITICAL":
50
+ return ["9", "10"] # CRITICAL only
51
+ else:
52
+ return None
53
+
54
+
55
+ @aws_handle_regions
56
+ def get_detectors(
57
+ boto3_session: boto3.session.Session,
58
+ region: str,
59
+ ) -> list[str]:
60
+ """
61
+ Get GuardDuty detector IDs for all detectors in a region.
62
+ """
63
+ client = boto3_session.client("guardduty", region_name=region)
64
+
65
+ # Get all detector IDs in this region
66
+ detectors_response = client.list_detectors()
67
+ detector_ids = detectors_response.get("DetectorIds", [])
68
+ return detector_ids
69
+
70
+
71
+ @aws_handle_regions
72
+ def get_detector_details(
73
+ boto3_session: boto3.session.Session,
74
+ region: str,
75
+ detector_ids: list[str],
76
+ ) -> list[dict[str, Any]]:
77
+ """
78
+ Get metadata about GuardDuty detectors in a region.
79
+ """
80
+ if not detector_ids:
81
+ return []
82
+
83
+ client = boto3_session.client("guardduty", region_name=region)
84
+ detectors: list[dict[str, Any]] = []
85
+
86
+ for detector_id in detector_ids:
87
+ detector = client.get_detector(DetectorId=detector_id)
88
+
89
+ detectors.append(
90
+ {
91
+ "id": detector_id,
92
+ "findingpublishingfrequency": detector.get(
93
+ "FindingPublishingFrequency",
94
+ ),
95
+ "service_role": detector.get("ServiceRole"),
96
+ "status": detector.get("Status"),
97
+ "createdat": detector.get("CreatedAt"),
98
+ "updatedat": detector.get("UpdatedAt"),
99
+ },
100
+ )
101
+
102
+ return detectors
103
+
104
+
105
+ @aws_handle_regions
106
+ @timeit
107
+ def get_findings(
108
+ boto3_session: boto3.session.Session,
109
+ region: str,
110
+ detector_id: str,
111
+ severity_threshold: str | None = None,
112
+ ) -> list[dict[str, Any]]:
113
+ """
114
+ Get GuardDuty findings for a specific detector.
115
+ Only fetches unarchived findings to avoid including closed/resolved findings.
116
+ Optionally filters by severity threshold.
117
+ """
118
+ client = boto3_session.client("guardduty", region_name=region)
119
+
120
+ # Build FindingCriteria - always exclude archived findings
121
+ criteria = {"service.archived": {"Equals": ["false"]}}
122
+
123
+ # Add severity filtering if threshold is provided
124
+ severity_range = _get_severity_range_for_threshold(severity_threshold)
125
+ if severity_range:
126
+ min_severity = min(
127
+ float(s) for s in severity_range
128
+ ) # get min severity from range
129
+ # I chose to ignore the type error here because the AWS API has fields that require different types
130
+ criteria["severity"] = {"GreaterThanOrEqual": int(min_severity)} # type: ignore
131
+
132
+ # Get all finding IDs for this detector with filtering
133
+ finding_ids = list(
134
+ aws_paginate(
135
+ client,
136
+ "list_findings",
137
+ "FindingIds",
138
+ DetectorId=detector_id,
139
+ FindingCriteria={"Criterion": criteria},
140
+ )
141
+ )
142
+
143
+ if not finding_ids:
144
+ logger.info(f"No findings found for detector {detector_id} in region {region}")
145
+ return []
146
+
147
+ findings_data = []
148
+
149
+ # Process findings in batches (GuardDuty API limit is 50)
150
+ batch_size = 50
151
+ for i in range(0, len(finding_ids), batch_size):
152
+ batch_ids = finding_ids[i : i + batch_size]
153
+
154
+ findings_response = client.get_findings(
155
+ DetectorId=detector_id, FindingIds=batch_ids
156
+ )
157
+
158
+ findings_batch = findings_response.get("Findings", [])
159
+ findings_data.extend(findings_batch)
160
+
161
+ logger.info(
162
+ f"Retrieved {len(findings_data)} findings for detector {detector_id} in region {region}"
163
+ )
164
+ return findings_data
165
+
166
+
167
+ def transform_findings(findings: list[dict[str, Any]]) -> list[dict[str, Any]]:
168
+ """Transform GuardDuty findings from API response to schema format."""
169
+ transformed: list[dict[str, Any]] = []
170
+ for f in findings:
171
+ item: dict[str, Any] = {
172
+ "id": f["Id"],
173
+ "arn": f.get("Arn"),
174
+ "type": f.get("Type"),
175
+ "severity": f.get("Severity"),
176
+ "title": f.get("Title"),
177
+ "description": f.get("Description"),
178
+ "confidence": f.get("Confidence"),
179
+ "eventfirstseen": f.get("EventFirstSeen"),
180
+ "eventlastseen": f.get("EventLastSeen"),
181
+ "accountid": f.get("AccountId"),
182
+ "region": f.get("Region"),
183
+ "detectorid": f.get("DetectorId"),
184
+ "archived": f.get("Archived"),
185
+ }
186
+
187
+ # Handle nested resource information
188
+ resource = f.get("Resource", {})
189
+ item["resource_type"] = resource.get("ResourceType")
190
+
191
+ # Extract resource ID based on resource type
192
+ if item["resource_type"] == "Instance":
193
+ details = resource.get("InstanceDetails", {})
194
+ item["resource_id"] = details.get("InstanceId")
195
+ elif item["resource_type"] == "S3Bucket":
196
+ buckets = resource.get("S3BucketDetails") or []
197
+ if buckets:
198
+ item["resource_id"] = buckets[0].get("Name")
199
+ else:
200
+ item["resource_id"] = None
201
+
202
+ transformed.append(item)
203
+
204
+ return transformed
205
+
206
+
207
+ def transform_detectors(
208
+ detectors: list[dict[str, Any]],
209
+ aws_account_id: str,
210
+ ) -> list[dict[str, Any]]:
211
+ """Transform GuardDuty detector metadata into schema format."""
212
+ transformed: list[dict[str, Any]] = []
213
+ for detector in detectors:
214
+ transformed.append(
215
+ {
216
+ "id": detector["id"],
217
+ "status": detector.get("status"),
218
+ "findingpublishingfrequency": detector.get(
219
+ "findingpublishingfrequency",
220
+ ),
221
+ "service_role": detector.get("service_role"),
222
+ "createdat": detector.get("createdat"),
223
+ "updatedat": detector.get("updatedat"),
224
+ "accountid": aws_account_id,
225
+ },
226
+ )
227
+
228
+ return transformed
229
+
230
+
231
+ @timeit
232
+ def load_guardduty_findings(
233
+ neo4j_session: neo4j.Session,
234
+ data: list[dict[str, Any]],
235
+ region: str,
236
+ aws_account_id: str,
237
+ update_tag: int,
238
+ ) -> None:
239
+ """
240
+ Load GuardDuty findings information into the graph.
241
+ """
242
+ logger.info(
243
+ f"Loading {len(data)} GuardDuty findings for region {region} into graph."
244
+ )
245
+
246
+ load(
247
+ neo4j_session,
248
+ GuardDutyFindingSchema(),
249
+ data,
250
+ lastupdated=update_tag,
251
+ Region=region,
252
+ AWS_ID=aws_account_id,
253
+ )
254
+
255
+
256
+ @timeit
257
+ def load_guardduty_detectors(
258
+ neo4j_session: neo4j.Session,
259
+ data: list[dict[str, Any]],
260
+ region: str,
261
+ aws_account_id: str,
262
+ update_tag: int,
263
+ ) -> None:
264
+ """Load GuardDuty detector information into the graph."""
265
+ logger.info(
266
+ f"Loading {len(data)} GuardDuty detectors for region {region} into graph.",
267
+ )
268
+
269
+ load(
270
+ neo4j_session,
271
+ GuardDutyDetectorSchema(),
272
+ data,
273
+ lastupdated=update_tag,
274
+ Region=region,
275
+ AWS_ID=aws_account_id,
276
+ )
277
+
278
+
279
+ @timeit
280
+ def sync_detectors(
281
+ neo4j_session: neo4j.Session,
282
+ boto3_session: boto3.session.Session,
283
+ region: str,
284
+ aws_account_id: str,
285
+ update_tag: int,
286
+ ) -> list[str]:
287
+ """
288
+ Sync GuardDuty detectors for a specific region.
289
+
290
+ :param neo4j_session: Neo4j session
291
+ :param boto3_session: Boto3 session
292
+ :param region: AWS region
293
+ :param aws_account_id: AWS account ID
294
+ :param update_tag: Update tag for tracking sync time
295
+ :return: List of detector IDs found in the region
296
+ """
297
+ logger.info(f"Syncing GuardDuty detectors for {region} in account {aws_account_id}")
298
+
299
+ # Get all detectors in the region
300
+ detector_ids = get_detectors(boto3_session, region)
301
+
302
+ if not detector_ids:
303
+ logger.info(f"No GuardDuty detectors found in region {region}")
304
+ return []
305
+
306
+ # Get detector details and load into graph
307
+ detectors = get_detector_details(boto3_session, region, detector_ids)
308
+ transformed_detectors = transform_detectors(detectors, aws_account_id)
309
+
310
+ load_guardduty_detectors(
311
+ neo4j_session,
312
+ transformed_detectors,
313
+ region,
314
+ aws_account_id,
315
+ update_tag,
316
+ )
317
+
318
+ return detector_ids
319
+
320
+
321
+ @timeit
322
+ def sync_findings(
323
+ neo4j_session: neo4j.Session,
324
+ boto3_session: boto3.session.Session,
325
+ region: str,
326
+ detector_ids: list[str],
327
+ aws_account_id: str,
328
+ update_tag: int,
329
+ severity_threshold: str | None = None,
330
+ ) -> None:
331
+ """
332
+ Sync GuardDuty findings for a list of detectors in a specific region.
333
+
334
+ :param neo4j_session: Neo4j session
335
+ :param boto3_session: Boto3 session
336
+ :param region: AWS region
337
+ :param detector_ids: List of detector IDs to fetch findings from
338
+ :param aws_account_id: AWS account ID
339
+ :param update_tag: Update tag for tracking sync time
340
+ :param severity_threshold: Optional severity threshold filter (LOW, MEDIUM, HIGH, CRITICAL)
341
+ """
342
+ logger.info(
343
+ f"Syncing GuardDuty findings for {len(detector_ids)} detector(s) in {region}"
344
+ )
345
+
346
+ # Get findings for all detectors in this region
347
+ all_findings = []
348
+ for detector_id in detector_ids:
349
+ findings = get_findings(boto3_session, region, detector_id, severity_threshold)
350
+ all_findings.extend(findings)
351
+
352
+ # Transform and load findings into graph
353
+ transformed_findings = transform_findings(all_findings)
354
+
355
+ load_guardduty_findings(
356
+ neo4j_session,
357
+ transformed_findings,
358
+ region,
359
+ aws_account_id,
360
+ update_tag,
361
+ )
362
+
363
+
364
+ @timeit
365
+ def cleanup_guardduty(
366
+ neo4j_session: neo4j.Session, common_job_parameters: dict[str, Any]
367
+ ) -> None:
368
+ """
369
+ Run GuardDuty cleanup job.
370
+ """
371
+ logger.debug("Running GuardDuty cleanup job.")
372
+ cleanup_jobs = [
373
+ GraphJob.from_node_schema(GuardDutyDetectorSchema(), common_job_parameters),
374
+ GraphJob.from_node_schema(GuardDutyFindingSchema(), common_job_parameters),
375
+ ]
376
+ for cleanup_job in cleanup_jobs:
377
+ cleanup_job.run(neo4j_session)
378
+
379
+
380
+ @timeit
381
+ def sync(
382
+ neo4j_session: neo4j.Session,
383
+ boto3_session: boto3.session.Session,
384
+ regions: list[str],
385
+ current_aws_account_id: str,
386
+ update_tag: int,
387
+ common_job_parameters: dict[str, Any],
388
+ ) -> None:
389
+ """
390
+ Sync GuardDuty detectors and findings for all regions.
391
+ Severity threshold filter is obtained from common_job_parameters.
392
+ """
393
+ # Get severity threshold from common job parameters
394
+ severity_threshold = common_job_parameters.get("aws_guardduty_severity_threshold")
395
+
396
+ for region in regions:
397
+ logger.info(
398
+ f"Syncing GuardDuty for {region} in account {current_aws_account_id}"
399
+ )
400
+
401
+ # Sync detectors for this region
402
+ detector_ids = sync_detectors(
403
+ neo4j_session,
404
+ boto3_session,
405
+ region,
406
+ current_aws_account_id,
407
+ update_tag,
408
+ )
409
+
410
+ if not detector_ids:
411
+ logger.info(f"No GuardDuty detectors found in region {region}, skipping.")
412
+ continue
413
+
414
+ # Sync findings for all detectors in this region
415
+ sync_findings(
416
+ neo4j_session,
417
+ boto3_session,
418
+ region,
419
+ detector_ids,
420
+ current_aws_account_id,
421
+ update_tag,
422
+ severity_threshold,
423
+ )
424
+
425
+ # Cleanup and metadata update (outside region loop)
426
+ cleanup_guardduty(neo4j_session, common_job_parameters)
427
+
428
+ merge_module_sync_metadata(
429
+ neo4j_session,
430
+ group_type="AWSAccount",
431
+ group_id=current_aws_account_id,
432
+ synced_type="GuardDutyDetector",
433
+ update_tag=update_tag,
434
+ stat_handler=stat_handler,
435
+ )
436
+ merge_module_sync_metadata(
437
+ neo4j_session,
438
+ group_type="AWSAccount",
439
+ group_id=current_aws_account_id,
440
+ synced_type="GuardDutyFinding",
441
+ update_tag=update_tag,
442
+ stat_handler=stat_handler,
443
+ )