cartography 0.93.0rc1__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 (822) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +34 -0
  3. cartography/cli.py +903 -225
  4. cartography/client/aws/__init__.py +19 -0
  5. cartography/client/aws/ecr.py +51 -0
  6. cartography/client/core/tx.py +400 -27
  7. cartography/config.py +215 -10
  8. cartography/data/azure_permission_relationships.yaml +20 -0
  9. cartography/data/gcp_permission_relationships.yaml +21 -0
  10. cartography/data/indexes.cypher +1 -200
  11. cartography/data/jobs/analysis/aws_ec2_asset_exposure.json +17 -2
  12. cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
  13. cartography/data/jobs/analysis/gcp_compute_asset_inet_exposure.json +1 -1
  14. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  15. cartography/data/jobs/cleanup/crowdstrike_import_cleanup.json +0 -5
  16. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  17. cartography/data/jobs/cleanup/github_repos_cleanup.json +27 -0
  18. cartography/data/jobs/scoped_analysis/aws_ec2_iaminstanceprofile.json +15 -0
  19. cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json +13 -13
  20. cartography/driftdetect/__main__.py +1 -2
  21. cartography/driftdetect/add_shortcut.py +10 -2
  22. cartography/driftdetect/cli.py +72 -75
  23. cartography/driftdetect/detect_deviations.py +7 -3
  24. cartography/driftdetect/get_states.py +20 -8
  25. cartography/driftdetect/model.py +5 -5
  26. cartography/driftdetect/serializers.py +8 -6
  27. cartography/driftdetect/storage.py +2 -2
  28. cartography/graph/cleanupbuilder.py +255 -35
  29. cartography/graph/job.py +104 -20
  30. cartography/graph/querybuilder.py +689 -91
  31. cartography/graph/statement.py +49 -36
  32. cartography/intel/airbyte/__init__.py +105 -0
  33. cartography/intel/airbyte/connections.py +120 -0
  34. cartography/intel/airbyte/destinations.py +81 -0
  35. cartography/intel/airbyte/organizations.py +59 -0
  36. cartography/intel/airbyte/sources.py +78 -0
  37. cartography/intel/airbyte/tags.py +64 -0
  38. cartography/intel/airbyte/users.py +106 -0
  39. cartography/intel/airbyte/util.py +122 -0
  40. cartography/intel/airbyte/workspaces.py +63 -0
  41. cartography/intel/analysis.py +4 -1
  42. cartography/intel/anthropic/__init__.py +62 -0
  43. cartography/intel/anthropic/apikeys.py +72 -0
  44. cartography/intel/anthropic/users.py +75 -0
  45. cartography/intel/anthropic/util.py +51 -0
  46. cartography/intel/anthropic/workspaces.py +95 -0
  47. cartography/intel/aws/__init__.py +137 -59
  48. cartography/intel/aws/acm.py +124 -0
  49. cartography/intel/aws/apigateway.py +482 -217
  50. cartography/intel/aws/apigatewayv2.py +116 -0
  51. cartography/intel/aws/cloudtrail.py +105 -0
  52. cartography/intel/aws/cloudtrail_management_events.py +962 -0
  53. cartography/intel/aws/cloudwatch.py +239 -0
  54. cartography/intel/aws/codebuild.py +132 -0
  55. cartography/intel/aws/cognito.py +201 -0
  56. cartography/intel/aws/config.py +63 -23
  57. cartography/intel/aws/dynamodb.py +108 -40
  58. cartography/intel/aws/ec2/__init__.py +2 -2
  59. cartography/intel/aws/ec2/auto_scaling_groups.py +254 -189
  60. cartography/intel/aws/ec2/elastic_ip_addresses.py +44 -14
  61. cartography/intel/aws/ec2/images.py +74 -39
  62. cartography/intel/aws/ec2/instances.py +262 -137
  63. cartography/intel/aws/ec2/internet_gateways.py +44 -13
  64. cartography/intel/aws/ec2/key_pairs.py +72 -39
  65. cartography/intel/aws/ec2/launch_templates.py +143 -66
  66. cartography/intel/aws/ec2/load_balancer_v2s.py +119 -45
  67. cartography/intel/aws/ec2/load_balancers.py +165 -147
  68. cartography/intel/aws/ec2/network_acls.py +233 -0
  69. cartography/intel/aws/ec2/network_interfaces.py +150 -87
  70. cartography/intel/aws/ec2/reserved_instances.py +48 -17
  71. cartography/intel/aws/ec2/route_tables.py +327 -0
  72. cartography/intel/aws/ec2/security_groups.py +189 -121
  73. cartography/intel/aws/ec2/snapshots.py +93 -91
  74. cartography/intel/aws/ec2/subnets.py +70 -58
  75. cartography/intel/aws/ec2/tgw.py +111 -39
  76. cartography/intel/aws/ec2/util.py +1 -1
  77. cartography/intel/aws/ec2/volumes.py +69 -41
  78. cartography/intel/aws/ec2/vpc.py +157 -116
  79. cartography/intel/aws/ec2/vpc_peerings.py +317 -121
  80. cartography/intel/aws/ecr.py +336 -93
  81. cartography/intel/aws/ecr_image_layers.py +923 -0
  82. cartography/intel/aws/ecs.py +310 -403
  83. cartography/intel/aws/efs.py +261 -0
  84. cartography/intel/aws/eks.py +55 -29
  85. cartography/intel/aws/elasticache.py +130 -83
  86. cartography/intel/aws/elasticsearch.py +70 -24
  87. cartography/intel/aws/emr.py +61 -23
  88. cartography/intel/aws/eventbridge.py +164 -0
  89. cartography/intel/aws/glue.py +181 -0
  90. cartography/intel/aws/guardduty.py +443 -0
  91. cartography/intel/aws/iam.py +978 -464
  92. cartography/intel/aws/iam_instance_profiles.py +73 -0
  93. cartography/intel/aws/identitycenter.py +847 -0
  94. cartography/intel/aws/inspector.py +330 -133
  95. cartography/intel/aws/kms.py +235 -209
  96. cartography/intel/aws/lambda_function.py +328 -176
  97. cartography/intel/aws/organizations.py +40 -19
  98. cartography/intel/aws/permission_relationships.py +144 -68
  99. cartography/intel/aws/rds.py +467 -412
  100. cartography/intel/aws/redshift.py +116 -50
  101. cartography/intel/aws/resourcegroupstaggingapi.py +198 -82
  102. cartography/intel/aws/resources.py +80 -42
  103. cartography/intel/aws/route53.py +419 -318
  104. cartography/intel/aws/s3.py +489 -96
  105. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  106. cartography/intel/aws/secretsmanager.py +217 -40
  107. cartography/intel/aws/securityhub.py +23 -10
  108. cartography/intel/aws/sns.py +226 -0
  109. cartography/intel/aws/sqs.py +74 -96
  110. cartography/intel/aws/ssm.py +142 -33
  111. cartography/intel/aws/util/arns.py +7 -7
  112. cartography/intel/aws/util/common.py +31 -4
  113. cartography/intel/azure/__init__.py +259 -46
  114. cartography/intel/azure/aks.py +175 -0
  115. cartography/intel/azure/app_service.py +105 -0
  116. cartography/intel/azure/compute.py +141 -120
  117. cartography/intel/azure/container_instances.py +95 -0
  118. cartography/intel/azure/cosmosdb.py +706 -519
  119. cartography/intel/azure/data_factory.py +85 -0
  120. cartography/intel/azure/data_factory_dataset.py +128 -0
  121. cartography/intel/azure/data_factory_linked_service.py +119 -0
  122. cartography/intel/azure/data_factory_pipeline.py +142 -0
  123. cartography/intel/azure/data_lake.py +124 -0
  124. cartography/intel/azure/event_grid.py +94 -0
  125. cartography/intel/azure/functions.py +124 -0
  126. cartography/intel/azure/load_balancers.py +263 -0
  127. cartography/intel/azure/logic_apps.py +101 -0
  128. cartography/intel/azure/monitor.py +105 -0
  129. cartography/intel/azure/network.py +467 -0
  130. cartography/intel/azure/permission_relationships.py +466 -0
  131. cartography/intel/azure/rbac.py +309 -0
  132. cartography/intel/azure/resource_groups.py +82 -0
  133. cartography/intel/azure/security_center.py +106 -0
  134. cartography/intel/azure/sql.py +436 -392
  135. cartography/intel/azure/storage.py +467 -335
  136. cartography/intel/azure/subscription.py +49 -55
  137. cartography/intel/azure/tenant.py +46 -28
  138. cartography/intel/azure/util/common.py +13 -0
  139. cartography/intel/azure/util/credentials.py +58 -143
  140. cartography/intel/azure/util/tag.py +41 -0
  141. cartography/intel/bigfix/__init__.py +2 -2
  142. cartography/intel/bigfix/computers.py +93 -65
  143. cartography/intel/cloudflare/__init__.py +74 -0
  144. cartography/intel/cloudflare/accounts.py +57 -0
  145. cartography/intel/cloudflare/dnsrecords.py +64 -0
  146. cartography/intel/cloudflare/members.py +75 -0
  147. cartography/intel/cloudflare/roles.py +65 -0
  148. cartography/intel/cloudflare/zones.py +64 -0
  149. cartography/intel/create_indexes.py +5 -3
  150. cartography/intel/crowdstrike/__init__.py +26 -12
  151. cartography/intel/crowdstrike/endpoints.py +17 -45
  152. cartography/intel/crowdstrike/spotlight.py +13 -5
  153. cartography/intel/cve/__init__.py +91 -26
  154. cartography/intel/cve/feed.py +77 -56
  155. cartography/intel/digitalocean/__init__.py +22 -13
  156. cartography/intel/digitalocean/compute.py +75 -108
  157. cartography/intel/digitalocean/management.py +44 -80
  158. cartography/intel/digitalocean/platform.py +48 -43
  159. cartography/intel/dns.py +41 -12
  160. cartography/intel/duo/__init__.py +21 -16
  161. cartography/intel/duo/api_host.py +14 -9
  162. cartography/intel/duo/endpoints.py +50 -45
  163. cartography/intel/duo/groups.py +18 -14
  164. cartography/intel/duo/phones.py +37 -34
  165. cartography/intel/duo/tokens.py +26 -23
  166. cartography/intel/duo/users.py +54 -50
  167. cartography/intel/duo/web_authn_credentials.py +30 -25
  168. cartography/intel/entra/__init__.py +160 -0
  169. cartography/intel/entra/app_role_assignments.py +284 -0
  170. cartography/intel/entra/applications.py +182 -0
  171. cartography/intel/entra/federation/__init__.py +0 -0
  172. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  173. cartography/intel/entra/groups.py +198 -0
  174. cartography/intel/entra/ou.py +136 -0
  175. cartography/intel/entra/service_principals.py +217 -0
  176. cartography/intel/entra/users.py +259 -0
  177. cartography/intel/gcp/__init__.py +381 -175
  178. cartography/intel/gcp/bigtable_app_profile.py +101 -0
  179. cartography/intel/gcp/bigtable_backup.py +91 -0
  180. cartography/intel/gcp/bigtable_cluster.py +93 -0
  181. cartography/intel/gcp/bigtable_instance.py +86 -0
  182. cartography/intel/gcp/bigtable_table.py +87 -0
  183. cartography/intel/gcp/cai.py +292 -0
  184. cartography/intel/gcp/clients.py +112 -0
  185. cartography/intel/gcp/compute.py +521 -325
  186. cartography/intel/gcp/crm/__init__.py +0 -0
  187. cartography/intel/gcp/crm/folders.py +114 -0
  188. cartography/intel/gcp/crm/orgs.py +70 -0
  189. cartography/intel/gcp/crm/projects.py +120 -0
  190. cartography/intel/gcp/dns.py +134 -179
  191. cartography/intel/gcp/gke.py +100 -107
  192. cartography/intel/gcp/iam.py +262 -0
  193. cartography/intel/gcp/permission_relationships.py +394 -0
  194. cartography/intel/gcp/policy_bindings.py +225 -0
  195. cartography/intel/gcp/storage.py +103 -158
  196. cartography/intel/github/__init__.py +66 -27
  197. cartography/intel/github/commits.py +423 -0
  198. cartography/intel/github/repos.py +871 -160
  199. cartography/intel/github/teams.py +386 -53
  200. cartography/intel/github/users.py +214 -49
  201. cartography/intel/github/util.py +50 -35
  202. cartography/intel/googleworkspace/__init__.py +193 -0
  203. cartography/intel/googleworkspace/devices.py +254 -0
  204. cartography/intel/googleworkspace/groups.py +568 -0
  205. cartography/intel/googleworkspace/oauth_apps.py +259 -0
  206. cartography/intel/googleworkspace/tenant.py +85 -0
  207. cartography/intel/googleworkspace/users.py +138 -0
  208. cartography/intel/gsuite/__init__.py +101 -42
  209. cartography/intel/gsuite/groups.py +291 -0
  210. cartography/intel/gsuite/users.py +142 -0
  211. cartography/intel/jamf/__init__.py +19 -1
  212. cartography/intel/jamf/computers.py +37 -8
  213. cartography/intel/jamf/util.py +7 -2
  214. cartography/intel/kandji/__init__.py +6 -3
  215. cartography/intel/kandji/devices.py +40 -10
  216. cartography/intel/keycloak/__init__.py +153 -0
  217. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  218. cartography/intel/keycloak/authenticationflows.py +77 -0
  219. cartography/intel/keycloak/clients.py +187 -0
  220. cartography/intel/keycloak/groups.py +126 -0
  221. cartography/intel/keycloak/identityproviders.py +94 -0
  222. cartography/intel/keycloak/organizations.py +163 -0
  223. cartography/intel/keycloak/realms.py +61 -0
  224. cartography/intel/keycloak/roles.py +202 -0
  225. cartography/intel/keycloak/scopes.py +73 -0
  226. cartography/intel/keycloak/users.py +70 -0
  227. cartography/intel/keycloak/util.py +47 -0
  228. cartography/intel/kubernetes/__init__.py +60 -14
  229. cartography/intel/kubernetes/clusters.py +86 -0
  230. cartography/intel/kubernetes/eks.py +402 -0
  231. cartography/intel/kubernetes/namespaces.py +60 -55
  232. cartography/intel/kubernetes/pods.py +171 -75
  233. cartography/intel/kubernetes/rbac.py +597 -0
  234. cartography/intel/kubernetes/secrets.py +95 -45
  235. cartography/intel/kubernetes/services.py +131 -63
  236. cartography/intel/kubernetes/util.py +142 -14
  237. cartography/intel/lastpass/__init__.py +2 -2
  238. cartography/intel/lastpass/users.py +23 -12
  239. cartography/intel/oci/__init__.py +44 -11
  240. cartography/intel/oci/iam.py +157 -47
  241. cartography/intel/oci/organizations.py +16 -7
  242. cartography/intel/oci/utils.py +71 -25
  243. cartography/intel/okta/__init__.py +66 -15
  244. cartography/intel/okta/applications.py +57 -25
  245. cartography/intel/okta/awssaml.py +105 -41
  246. cartography/intel/okta/factors.py +19 -5
  247. cartography/intel/okta/groups.py +61 -31
  248. cartography/intel/okta/organization.py +8 -2
  249. cartography/intel/okta/origins.py +9 -3
  250. cartography/intel/okta/roles.py +20 -7
  251. cartography/intel/okta/users.py +31 -10
  252. cartography/intel/okta/utils.py +6 -4
  253. cartography/intel/ontology/__init__.py +44 -0
  254. cartography/intel/ontology/devices.py +54 -0
  255. cartography/intel/ontology/users.py +54 -0
  256. cartography/intel/ontology/utils.py +176 -0
  257. cartography/intel/openai/__init__.py +86 -0
  258. cartography/intel/openai/adminapikeys.py +89 -0
  259. cartography/intel/openai/apikeys.py +96 -0
  260. cartography/intel/openai/projects.py +97 -0
  261. cartography/intel/openai/serviceaccounts.py +82 -0
  262. cartography/intel/openai/users.py +75 -0
  263. cartography/intel/openai/util.py +45 -0
  264. cartography/intel/pagerduty/__init__.py +8 -7
  265. cartography/intel/pagerduty/escalation_policies.py +31 -12
  266. cartography/intel/pagerduty/schedules.py +21 -8
  267. cartography/intel/pagerduty/services.py +18 -7
  268. cartography/intel/pagerduty/teams.py +13 -5
  269. cartography/intel/pagerduty/users.py +6 -2
  270. cartography/intel/pagerduty/vendors.py +6 -2
  271. cartography/intel/scaleway/__init__.py +127 -0
  272. cartography/intel/scaleway/iam/__init__.py +0 -0
  273. cartography/intel/scaleway/iam/apikeys.py +71 -0
  274. cartography/intel/scaleway/iam/applications.py +71 -0
  275. cartography/intel/scaleway/iam/groups.py +71 -0
  276. cartography/intel/scaleway/iam/users.py +71 -0
  277. cartography/intel/scaleway/instances/__init__.py +0 -0
  278. cartography/intel/scaleway/instances/flexibleips.py +86 -0
  279. cartography/intel/scaleway/instances/instances.py +92 -0
  280. cartography/intel/scaleway/projects.py +79 -0
  281. cartography/intel/scaleway/storage/__init__.py +0 -0
  282. cartography/intel/scaleway/storage/snapshots.py +86 -0
  283. cartography/intel/scaleway/storage/volumes.py +84 -0
  284. cartography/intel/scaleway/utils.py +37 -0
  285. cartography/intel/semgrep/__init__.py +30 -5
  286. cartography/intel/semgrep/dependencies.py +255 -0
  287. cartography/intel/semgrep/deployment.py +69 -0
  288. cartography/intel/semgrep/findings.py +157 -117
  289. cartography/intel/sentinelone/__init__.py +75 -0
  290. cartography/intel/sentinelone/account.py +140 -0
  291. cartography/intel/sentinelone/agent.py +139 -0
  292. cartography/intel/sentinelone/api.py +124 -0
  293. cartography/intel/sentinelone/application.py +248 -0
  294. cartography/intel/sentinelone/cve.py +119 -0
  295. cartography/intel/sentinelone/utils.py +28 -0
  296. cartography/intel/slack/__init__.py +78 -0
  297. cartography/intel/slack/channels.py +80 -0
  298. cartography/intel/slack/groups.py +90 -0
  299. cartography/intel/slack/teams.py +65 -0
  300. cartography/intel/slack/users.py +57 -0
  301. cartography/intel/slack/utils.py +29 -0
  302. cartography/intel/snipeit/__init__.py +44 -0
  303. cartography/intel/snipeit/asset.py +80 -0
  304. cartography/intel/snipeit/user.py +78 -0
  305. cartography/intel/snipeit/util.py +40 -0
  306. cartography/intel/spacelift/__init__.py +161 -0
  307. cartography/intel/spacelift/account.py +73 -0
  308. cartography/intel/spacelift/ec2_ownership.py +280 -0
  309. cartography/intel/spacelift/runs.py +463 -0
  310. cartography/intel/spacelift/spaces.py +112 -0
  311. cartography/intel/spacelift/stacks.py +119 -0
  312. cartography/intel/spacelift/util.py +122 -0
  313. cartography/intel/spacelift/workerpools.py +131 -0
  314. cartography/intel/spacelift/workers.py +128 -0
  315. cartography/intel/tailscale/__init__.py +77 -0
  316. cartography/intel/tailscale/acls.py +146 -0
  317. cartography/intel/tailscale/devices.py +127 -0
  318. cartography/intel/tailscale/postureintegrations.py +81 -0
  319. cartography/intel/tailscale/tailnets.py +76 -0
  320. cartography/intel/tailscale/users.py +80 -0
  321. cartography/intel/tailscale/utils.py +132 -0
  322. cartography/intel/trivy/__init__.py +272 -0
  323. cartography/intel/trivy/scanner.py +386 -0
  324. cartography/models/airbyte/__init__.py +0 -0
  325. cartography/models/airbyte/connection.py +138 -0
  326. cartography/models/airbyte/destination.py +75 -0
  327. cartography/models/airbyte/organization.py +19 -0
  328. cartography/models/airbyte/source.py +75 -0
  329. cartography/models/airbyte/stream.py +74 -0
  330. cartography/models/airbyte/tag.py +69 -0
  331. cartography/models/airbyte/user.py +115 -0
  332. cartography/models/airbyte/workspace.py +46 -0
  333. cartography/models/anthropic/__init__.py +0 -0
  334. cartography/models/anthropic/apikey.py +94 -0
  335. cartography/models/anthropic/organization.py +19 -0
  336. cartography/models/anthropic/user.py +52 -0
  337. cartography/models/anthropic/workspace.py +90 -0
  338. cartography/models/aws/acm/__init__.py +0 -0
  339. cartography/models/aws/acm/certificate.py +75 -0
  340. cartography/models/aws/apigateway/__init__.py +0 -0
  341. cartography/models/aws/apigateway/apigateway.py +51 -0
  342. cartography/models/aws/apigateway/apigatewaycertificate.py +72 -0
  343. cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
  344. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  345. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  346. cartography/models/aws/apigateway/apigatewayresource.py +70 -0
  347. cartography/models/aws/apigateway/apigatewaystage.py +75 -0
  348. cartography/models/aws/apigatewayv2/__init__.py +0 -0
  349. cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
  350. cartography/models/aws/cloudtrail/__init__.py +0 -0
  351. cartography/models/aws/cloudtrail/management_events.py +153 -0
  352. cartography/models/aws/cloudtrail/trail.py +106 -0
  353. cartography/models/aws/cloudwatch/__init__.py +0 -0
  354. cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
  355. cartography/models/aws/cloudwatch/loggroup.py +52 -0
  356. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  357. cartography/models/aws/codebuild/__init__.py +0 -0
  358. cartography/models/aws/codebuild/project.py +49 -0
  359. cartography/models/aws/cognito/__init__.py +0 -0
  360. cartography/models/aws/cognito/identity_pool.py +70 -0
  361. cartography/models/aws/cognito/user_pool.py +47 -0
  362. cartography/models/aws/dynamodb/gsi.py +30 -22
  363. cartography/models/aws/dynamodb/tables.py +27 -17
  364. cartography/models/aws/ec2/auto_scaling_groups.py +224 -0
  365. cartography/models/aws/ec2/images.py +36 -34
  366. cartography/models/aws/ec2/instances.py +85 -38
  367. cartography/models/aws/ec2/keypair.py +59 -0
  368. cartography/models/aws/ec2/keypair_instance.py +76 -0
  369. cartography/models/aws/ec2/launch_configurations.py +59 -0
  370. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  371. cartography/models/aws/ec2/launch_templates.py +21 -17
  372. cartography/models/aws/ec2/load_balancer_listeners.py +72 -0
  373. cartography/models/aws/ec2/load_balancers.py +112 -0
  374. cartography/models/aws/ec2/network_acl_rules.py +106 -0
  375. cartography/models/aws/ec2/network_acls.py +95 -0
  376. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  377. cartography/models/aws/ec2/networkinterfaces.py +57 -37
  378. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  379. cartography/models/aws/ec2/reservations.py +18 -14
  380. cartography/models/aws/ec2/route_table_associations.py +97 -0
  381. cartography/models/aws/ec2/route_tables.py +128 -0
  382. cartography/models/aws/ec2/routes.py +85 -0
  383. cartography/models/aws/ec2/security_group_rules.py +109 -0
  384. cartography/models/aws/ec2/security_groups.py +90 -0
  385. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  386. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  387. cartography/models/aws/ec2/snapshots.py +58 -0
  388. cartography/models/aws/ec2/subnet_instance.py +26 -19
  389. cartography/models/aws/ec2/subnet_networkinterface.py +42 -31
  390. cartography/models/aws/ec2/subnets.py +65 -0
  391. cartography/models/aws/ec2/volumes.py +67 -40
  392. cartography/models/aws/ec2/vpc.py +46 -0
  393. cartography/models/aws/ec2/vpc_cidr.py +102 -0
  394. cartography/models/aws/ec2/vpc_peering.py +157 -0
  395. cartography/models/aws/ecr/__init__.py +0 -0
  396. cartography/models/aws/ecr/image.py +146 -0
  397. cartography/models/aws/ecr/image_layer.py +107 -0
  398. cartography/models/aws/ecr/repository.py +72 -0
  399. cartography/models/aws/ecr/repository_image.py +95 -0
  400. cartography/models/aws/ecs/__init__.py +0 -0
  401. cartography/models/aws/ecs/clusters.py +64 -0
  402. cartography/models/aws/ecs/container_definitions.py +93 -0
  403. cartography/models/aws/ecs/container_instances.py +84 -0
  404. cartography/models/aws/ecs/containers.py +101 -0
  405. cartography/models/aws/ecs/services.py +134 -0
  406. cartography/models/aws/ecs/task_definitions.py +135 -0
  407. cartography/models/aws/ecs/tasks.py +134 -0
  408. cartography/models/aws/efs/__init__.py +0 -0
  409. cartography/models/aws/efs/access_point.py +77 -0
  410. cartography/models/aws/efs/file_system.py +60 -0
  411. cartography/models/aws/efs/mount_target.py +79 -0
  412. cartography/models/aws/eks/clusters.py +23 -21
  413. cartography/models/aws/elasticache/__init__.py +0 -0
  414. cartography/models/aws/elasticache/cluster.py +65 -0
  415. cartography/models/aws/elasticache/topic.py +67 -0
  416. cartography/models/aws/emr.py +32 -30
  417. cartography/models/aws/eventbridge/__init__.py +0 -0
  418. cartography/models/aws/eventbridge/rule.py +77 -0
  419. cartography/models/aws/eventbridge/target.py +71 -0
  420. cartography/models/aws/glue/__init__.py +0 -0
  421. cartography/models/aws/glue/connection.py +51 -0
  422. cartography/models/aws/glue/job.py +69 -0
  423. cartography/models/aws/guardduty/__init__.py +1 -0
  424. cartography/models/aws/guardduty/detectors.py +50 -0
  425. cartography/models/aws/guardduty/findings.py +121 -0
  426. cartography/models/aws/iam/__init__.py +0 -0
  427. cartography/models/aws/iam/access_key.py +103 -0
  428. cartography/models/aws/iam/account_role.py +24 -0
  429. cartography/models/aws/iam/federated_principal.py +60 -0
  430. cartography/models/aws/iam/group.py +60 -0
  431. cartography/models/aws/iam/group_membership.py +27 -0
  432. cartography/models/aws/iam/inline_policy.py +78 -0
  433. cartography/models/aws/iam/instanceprofile.py +76 -0
  434. cartography/models/aws/iam/managed_policy.py +51 -0
  435. cartography/models/aws/iam/policy_statement.py +57 -0
  436. cartography/models/aws/iam/role.py +83 -0
  437. cartography/models/aws/iam/root_principal.py +52 -0
  438. cartography/models/aws/iam/service_principal.py +30 -0
  439. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  440. cartography/models/aws/iam/user.py +59 -0
  441. cartography/models/aws/identitycenter/__init__.py +0 -0
  442. cartography/models/aws/identitycenter/awsidentitycenter.py +49 -0
  443. cartography/models/aws/identitycenter/awspermissionset.py +162 -0
  444. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  445. cartography/models/aws/identitycenter/awsssouser.py +110 -0
  446. cartography/models/aws/inspector/findings.py +124 -58
  447. cartography/models/aws/inspector/packages.py +18 -42
  448. cartography/models/aws/kms/__init__.py +0 -0
  449. cartography/models/aws/kms/aliases.py +86 -0
  450. cartography/models/aws/kms/grants.py +65 -0
  451. cartography/models/aws/kms/keys.py +88 -0
  452. cartography/models/aws/lambda_function/__init__.py +0 -0
  453. cartography/models/aws/lambda_function/alias.py +74 -0
  454. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  455. cartography/models/aws/lambda_function/lambda_function.py +91 -0
  456. cartography/models/aws/lambda_function/layer.py +72 -0
  457. cartography/models/aws/rds/__init__.py +0 -0
  458. cartography/models/aws/rds/cluster.py +91 -0
  459. cartography/models/aws/rds/event_subscription.py +146 -0
  460. cartography/models/aws/rds/instance.py +156 -0
  461. cartography/models/aws/rds/snapshot.py +108 -0
  462. cartography/models/aws/rds/subnet_group.py +101 -0
  463. cartography/models/aws/route53/__init__.py +0 -0
  464. cartography/models/aws/route53/dnsrecord.py +235 -0
  465. cartography/models/aws/route53/nameserver.py +63 -0
  466. cartography/models/aws/route53/subzone.py +40 -0
  467. cartography/models/aws/route53/zone.py +47 -0
  468. cartography/models/aws/s3/__init__.py +0 -0
  469. cartography/models/aws/s3/account_public_access_block.py +51 -0
  470. cartography/models/aws/s3/notification.py +24 -0
  471. cartography/models/aws/secretsmanager/__init__.py +0 -0
  472. cartography/models/aws/secretsmanager/secret.py +106 -0
  473. cartography/models/aws/secretsmanager/secret_version.py +114 -0
  474. cartography/models/aws/sns/__init__.py +0 -0
  475. cartography/models/aws/sns/topic.py +50 -0
  476. cartography/models/aws/sns/topic_subscription.py +74 -0
  477. cartography/models/aws/sqs/__init__.py +0 -0
  478. cartography/models/aws/sqs/queue.py +89 -0
  479. cartography/models/aws/ssm/instance_information.py +51 -39
  480. cartography/models/aws/ssm/instance_patch.py +32 -26
  481. cartography/models/aws/ssm/parameters.py +84 -0
  482. cartography/models/azure/__init__.py +0 -0
  483. cartography/models/azure/aks_cluster.py +54 -0
  484. cartography/models/azure/aks_nodepool.py +54 -0
  485. cartography/models/azure/app_service.py +59 -0
  486. cartography/models/azure/container_instance.py +57 -0
  487. cartography/models/azure/cosmosdb/__init__.py +0 -0
  488. cartography/models/azure/cosmosdb/account.py +77 -0
  489. cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
  490. cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
  491. cartography/models/azure/cosmosdb/cassandratable.py +81 -0
  492. cartography/models/azure/cosmosdb/corspolicy.py +74 -0
  493. cartography/models/azure/cosmosdb/dblocation.py +120 -0
  494. cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
  495. cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
  496. cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
  497. cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
  498. cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
  499. cartography/models/azure/cosmosdb/tableresource.py +76 -0
  500. cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
  501. cartography/models/azure/data_factory/__init__.py +0 -0
  502. cartography/models/azure/data_factory/data_factory.py +51 -0
  503. cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
  504. cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
  505. cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
  506. cartography/models/azure/data_lake_filesystem.py +51 -0
  507. cartography/models/azure/event_grid_topic.py +57 -0
  508. cartography/models/azure/function_app.py +59 -0
  509. cartography/models/azure/load_balancer/__init__.py +0 -0
  510. cartography/models/azure/load_balancer/load_balancer.py +49 -0
  511. cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
  512. cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
  513. cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
  514. cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
  515. cartography/models/azure/logic_apps.py +56 -0
  516. cartography/models/azure/monitor.py +54 -0
  517. cartography/models/azure/network_interface.py +112 -0
  518. cartography/models/azure/network_security_group.py +50 -0
  519. cartography/models/azure/permission_relationships.py +60 -0
  520. cartography/models/azure/principal.py +41 -0
  521. cartography/models/azure/public_ip_address.py +50 -0
  522. cartography/models/azure/rbac.py +268 -0
  523. cartography/models/azure/resource_groups.py +52 -0
  524. cartography/models/azure/security_center.py +50 -0
  525. cartography/models/azure/sql/__init__.py +0 -0
  526. cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
  527. cartography/models/azure/sql/elasticpool.py +77 -0
  528. cartography/models/azure/sql/failovergroup.py +73 -0
  529. cartography/models/azure/sql/recoverabledatabase.py +75 -0
  530. cartography/models/azure/sql/replicationlink.py +81 -0
  531. cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
  532. cartography/models/azure/sql/restorepoint.py +74 -0
  533. cartography/models/azure/sql/serveradadministrator.py +74 -0
  534. cartography/models/azure/sql/serverdnsalias.py +71 -0
  535. cartography/models/azure/sql/sqldatabase.py +85 -0
  536. cartography/models/azure/sql/sqlserver.py +50 -0
  537. cartography/models/azure/sql/transparentdataencryption.py +76 -0
  538. cartography/models/azure/storage/__init__.py +0 -0
  539. cartography/models/azure/storage/account.py +59 -0
  540. cartography/models/azure/storage/blobcontainer.py +85 -0
  541. cartography/models/azure/storage/blobservice.py +71 -0
  542. cartography/models/azure/storage/fileservice.py +71 -0
  543. cartography/models/azure/storage/fileshare.py +82 -0
  544. cartography/models/azure/storage/queue.py +71 -0
  545. cartography/models/azure/storage/queueservice.py +73 -0
  546. cartography/models/azure/storage/table.py +72 -0
  547. cartography/models/azure/storage/tableservice.py +73 -0
  548. cartography/models/azure/subnet.py +101 -0
  549. cartography/models/azure/subscription.py +47 -0
  550. cartography/models/azure/tags/__init__.py +0 -0
  551. cartography/models/azure/tags/storage_tag.py +40 -0
  552. cartography/models/azure/tags/tag.py +37 -0
  553. cartography/models/azure/tenant.py +17 -0
  554. cartography/models/azure/virtual_network.py +49 -0
  555. cartography/models/azure/vm/__init__.py +0 -0
  556. cartography/models/azure/vm/datadisk.py +80 -0
  557. cartography/models/azure/vm/disk.py +55 -0
  558. cartography/models/azure/vm/snapshot.py +56 -0
  559. cartography/models/azure/vm/virtualmachine.py +59 -0
  560. cartography/models/bigfix/bigfix_computer.py +42 -38
  561. cartography/models/bigfix/bigfix_root.py +3 -3
  562. cartography/models/cloudflare/__init__.py +0 -0
  563. cartography/models/cloudflare/account.py +25 -0
  564. cartography/models/cloudflare/dnsrecord.py +55 -0
  565. cartography/models/cloudflare/member.py +86 -0
  566. cartography/models/cloudflare/role.py +44 -0
  567. cartography/models/cloudflare/zone.py +59 -0
  568. cartography/models/core/common.py +53 -2
  569. cartography/models/core/nodes.py +20 -4
  570. cartography/models/core/relationships.py +58 -6
  571. cartography/models/crowdstrike/__init__.py +0 -0
  572. cartography/models/crowdstrike/hosts.py +51 -0
  573. cartography/models/cve/cve.py +34 -32
  574. cartography/models/cve/cve_feed.py +6 -6
  575. cartography/models/digitalocean/__init__.py +0 -0
  576. cartography/models/digitalocean/account.py +21 -0
  577. cartography/models/digitalocean/droplet.py +58 -0
  578. cartography/models/digitalocean/project.py +48 -0
  579. cartography/models/duo/api_host.py +3 -3
  580. cartography/models/duo/endpoint.py +43 -41
  581. cartography/models/duo/group.py +14 -14
  582. cartography/models/duo/phone.py +27 -27
  583. cartography/models/duo/token.py +16 -16
  584. cartography/models/duo/user.py +50 -44
  585. cartography/models/duo/web_authn_credential.py +27 -19
  586. cartography/models/entra/__init__.py +0 -0
  587. cartography/models/entra/app_role_assignment.py +115 -0
  588. cartography/models/entra/application.py +49 -0
  589. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  590. cartography/models/entra/group.py +117 -0
  591. cartography/models/entra/ou.py +48 -0
  592. cartography/models/entra/service_principal.py +104 -0
  593. cartography/models/entra/tenant.py +39 -0
  594. cartography/models/entra/user.py +90 -0
  595. cartography/models/gcp/__init__.py +0 -0
  596. cartography/models/gcp/bigtable/__init__.py +0 -0
  597. cartography/models/gcp/bigtable/app_profile.py +94 -0
  598. cartography/models/gcp/bigtable/backup.py +91 -0
  599. cartography/models/gcp/bigtable/cluster.py +73 -0
  600. cartography/models/gcp/bigtable/instance.py +52 -0
  601. cartography/models/gcp/bigtable/table.py +69 -0
  602. cartography/models/gcp/compute/__init__.py +0 -0
  603. cartography/models/gcp/compute/subnet.py +74 -0
  604. cartography/models/gcp/compute/vpc.py +50 -0
  605. cartography/models/gcp/crm/__init__.py +0 -0
  606. cartography/models/gcp/crm/folders.py +98 -0
  607. cartography/models/gcp/crm/organizations.py +21 -0
  608. cartography/models/gcp/crm/projects.py +100 -0
  609. cartography/models/gcp/dns.py +109 -0
  610. cartography/models/gcp/gke.py +69 -0
  611. cartography/models/gcp/iam.py +73 -0
  612. cartography/models/gcp/permission_relationships.py +61 -0
  613. cartography/models/gcp/policy_bindings.py +93 -0
  614. cartography/models/gcp/storage/__init__.py +0 -0
  615. cartography/models/gcp/storage/bucket.py +119 -0
  616. cartography/models/github/commits.py +63 -0
  617. cartography/models/github/dependencies.py +73 -0
  618. cartography/models/github/manifests.py +49 -0
  619. cartography/models/github/orgs.py +27 -0
  620. cartography/models/github/teams.py +74 -22
  621. cartography/models/github/users.py +149 -0
  622. cartography/models/googleworkspace/__init__.py +0 -0
  623. cartography/models/googleworkspace/device.py +132 -0
  624. cartography/models/googleworkspace/group.py +382 -0
  625. cartography/models/googleworkspace/oauth_app.py +124 -0
  626. cartography/models/googleworkspace/tenant.py +30 -0
  627. cartography/models/googleworkspace/user.py +113 -0
  628. cartography/models/gsuite/__init__.py +0 -0
  629. cartography/models/gsuite/group.py +218 -0
  630. cartography/models/gsuite/tenant.py +29 -0
  631. cartography/models/gsuite/user.py +107 -0
  632. cartography/models/kandji/device.py +22 -17
  633. cartography/models/kandji/tenant.py +6 -4
  634. cartography/models/keycloak/__init__.py +0 -0
  635. cartography/models/keycloak/authenticationexecution.py +160 -0
  636. cartography/models/keycloak/authenticationflow.py +54 -0
  637. cartography/models/keycloak/client.py +179 -0
  638. cartography/models/keycloak/group.py +101 -0
  639. cartography/models/keycloak/identityprovider.py +89 -0
  640. cartography/models/keycloak/organization.py +116 -0
  641. cartography/models/keycloak/organizationdomain.py +73 -0
  642. cartography/models/keycloak/realm.py +173 -0
  643. cartography/models/keycloak/role.py +126 -0
  644. cartography/models/keycloak/scope.py +73 -0
  645. cartography/models/keycloak/user.py +55 -0
  646. cartography/models/kubernetes/__init__.py +0 -0
  647. cartography/models/kubernetes/clusterrolebindings.py +138 -0
  648. cartography/models/kubernetes/clusterroles.py +52 -0
  649. cartography/models/kubernetes/clusters.py +26 -0
  650. cartography/models/kubernetes/containers.py +133 -0
  651. cartography/models/kubernetes/groups.py +107 -0
  652. cartography/models/kubernetes/namespaces.py +51 -0
  653. cartography/models/kubernetes/oidc.py +51 -0
  654. cartography/models/kubernetes/pods.py +80 -0
  655. cartography/models/kubernetes/rolebindings.py +159 -0
  656. cartography/models/kubernetes/roles.py +76 -0
  657. cartography/models/kubernetes/secrets.py +79 -0
  658. cartography/models/kubernetes/serviceaccounts.py +77 -0
  659. cartography/models/kubernetes/services.py +108 -0
  660. cartography/models/kubernetes/users.py +105 -0
  661. cartography/models/lastpass/tenant.py +3 -3
  662. cartography/models/lastpass/user.py +36 -28
  663. cartography/models/ontology/__init__.py +0 -0
  664. cartography/models/ontology/device.py +137 -0
  665. cartography/models/ontology/mapping/__init__.py +76 -0
  666. cartography/models/ontology/mapping/data/__init__.py +0 -0
  667. cartography/models/ontology/mapping/data/apikeys.py +93 -0
  668. cartography/models/ontology/mapping/data/computeinstance.py +95 -0
  669. cartography/models/ontology/mapping/data/containers.py +88 -0
  670. cartography/models/ontology/mapping/data/databases.py +182 -0
  671. cartography/models/ontology/mapping/data/devices.py +194 -0
  672. cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
  673. cartography/models/ontology/mapping/data/useraccounts.py +416 -0
  674. cartography/models/ontology/mapping/data/users.py +63 -0
  675. cartography/models/ontology/mapping/specs.py +85 -0
  676. cartography/models/ontology/user.py +51 -0
  677. cartography/models/openai/__init__.py +0 -0
  678. cartography/models/openai/adminapikey.py +94 -0
  679. cartography/models/openai/apikey.py +88 -0
  680. cartography/models/openai/organization.py +17 -0
  681. cartography/models/openai/project.py +89 -0
  682. cartography/models/openai/serviceaccount.py +50 -0
  683. cartography/models/openai/user.py +53 -0
  684. cartography/models/scaleway/__init__.py +0 -0
  685. cartography/models/scaleway/iam/__init__.py +0 -0
  686. cartography/models/scaleway/iam/apikey.py +100 -0
  687. cartography/models/scaleway/iam/application.py +52 -0
  688. cartography/models/scaleway/iam/group.py +95 -0
  689. cartography/models/scaleway/iam/user.py +64 -0
  690. cartography/models/scaleway/instance/__init__.py +0 -0
  691. cartography/models/scaleway/instance/flexibleip.py +52 -0
  692. cartography/models/scaleway/instance/instance.py +120 -0
  693. cartography/models/scaleway/organization.py +19 -0
  694. cartography/models/scaleway/project.py +48 -0
  695. cartography/models/scaleway/storage/__init__.py +0 -0
  696. cartography/models/scaleway/storage/snapshot.py +78 -0
  697. cartography/models/scaleway/storage/volume.py +51 -0
  698. cartography/models/semgrep/dependencies.py +102 -0
  699. cartography/models/semgrep/deployment.py +5 -5
  700. cartography/models/semgrep/findings.py +58 -40
  701. cartography/models/semgrep/locations.py +27 -21
  702. cartography/models/sentinelone/__init__.py +1 -0
  703. cartography/models/sentinelone/account.py +40 -0
  704. cartography/models/sentinelone/agent.py +50 -0
  705. cartography/models/sentinelone/application.py +44 -0
  706. cartography/models/sentinelone/application_version.py +96 -0
  707. cartography/models/sentinelone/cve.py +73 -0
  708. cartography/models/slack/__init__.py +0 -0
  709. cartography/models/slack/channels.py +92 -0
  710. cartography/models/slack/group.py +129 -0
  711. cartography/models/slack/team.py +22 -0
  712. cartography/models/slack/user.py +62 -0
  713. cartography/models/snipeit/__init__.py +0 -0
  714. cartography/models/snipeit/asset.py +92 -0
  715. cartography/models/snipeit/tenant.py +19 -0
  716. cartography/models/snipeit/user.py +60 -0
  717. cartography/models/spacelift/__init__.py +0 -0
  718. cartography/models/spacelift/cloudtrailevent.py +120 -0
  719. cartography/models/spacelift/run.py +162 -0
  720. cartography/models/spacelift/space.py +131 -0
  721. cartography/models/spacelift/spaceliftaccount.py +31 -0
  722. cartography/models/spacelift/spaceliftgitcommit.py +157 -0
  723. cartography/models/spacelift/stack.py +96 -0
  724. cartography/models/spacelift/user.py +63 -0
  725. cartography/models/spacelift/worker.py +97 -0
  726. cartography/models/spacelift/workerpool.py +90 -0
  727. cartography/models/tailscale/__init__.py +0 -0
  728. cartography/models/tailscale/device.py +96 -0
  729. cartography/models/tailscale/group.py +86 -0
  730. cartography/models/tailscale/postureintegration.py +58 -0
  731. cartography/models/tailscale/tag.py +102 -0
  732. cartography/models/tailscale/tailnet.py +29 -0
  733. cartography/models/tailscale/user.py +57 -0
  734. cartography/models/trivy/__init__.py +0 -0
  735. cartography/models/trivy/findings.py +66 -0
  736. cartography/models/trivy/fix.py +66 -0
  737. cartography/models/trivy/package.py +71 -0
  738. cartography/rules/README.md +1 -0
  739. cartography/rules/__init__.py +0 -0
  740. cartography/rules/cli.py +261 -0
  741. cartography/rules/data/__init__.py +0 -0
  742. cartography/rules/data/rules/__init__.py +46 -0
  743. cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
  744. cartography/rules/data/rules/compute_instance_exposed.py +51 -0
  745. cartography/rules/data/rules/database_instance_exposed.py +53 -0
  746. cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
  747. cartography/rules/data/rules/identity_administration_privileges.py +100 -0
  748. cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
  749. cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
  750. cartography/rules/data/rules/mfa_missing.py +46 -0
  751. cartography/rules/data/rules/object_storage_public.py +100 -0
  752. cartography/rules/data/rules/policy_administration_privileges.py +104 -0
  753. cartography/rules/data/rules/unmanaged_accounts.py +43 -0
  754. cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
  755. cartography/rules/formatters.py +108 -0
  756. cartography/rules/runners.py +216 -0
  757. cartography/rules/spec/__init__.py +0 -0
  758. cartography/rules/spec/model.py +267 -0
  759. cartography/rules/spec/result.py +38 -0
  760. cartography/stats.py +4 -4
  761. cartography/sync.py +137 -31
  762. cartography/util.py +187 -77
  763. cartography-0.123.0.dist-info/METADATA +230 -0
  764. cartography-0.123.0.dist-info/RECORD +856 -0
  765. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/WHEEL +1 -1
  766. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
  767. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info/licenses}/LICENSE +1 -1
  768. cartography/data/jobs/analysis/aws_ec2_iaminstance.json +0 -10
  769. cartography/data/jobs/analysis/aws_ec2_iaminstanceprofile.json +0 -10
  770. cartography/data/jobs/cleanup/aws_apigateway_details.json +0 -10
  771. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  772. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  773. cartography/data/jobs/cleanup/aws_import_apigateway_cleanup.json +0 -45
  774. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  775. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  776. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  777. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  778. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  779. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  780. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  781. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  782. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  783. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  784. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  785. cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
  786. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  787. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  788. cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
  789. cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
  790. cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
  791. cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
  792. cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
  793. cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
  794. cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
  795. cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
  796. cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
  797. cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
  798. cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
  799. cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
  800. cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
  801. cartography/data/jobs/cleanup/crxcavator_import_cleanup.json +0 -18
  802. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  803. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  804. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  805. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  806. cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
  807. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  808. cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
  809. cartography/data/jobs/cleanup/github_users_cleanup.json +0 -23
  810. cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
  811. cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
  812. cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
  813. cartography/intel/crxcavator/__init__.py +0 -44
  814. cartography/intel/crxcavator/crxcavator.py +0 -329
  815. cartography/intel/gcp/crm.py +0 -302
  816. cartography/intel/gsuite/api.py +0 -284
  817. cartography/models/aws/ec2/keypairs.py +0 -64
  818. cartography-0.93.0rc1.dist-info/METADATA +0 -55
  819. cartography-0.93.0rc1.dist-info/NOTICE +0 -4
  820. cartography-0.93.0rc1.dist-info/RECORD +0 -341
  821. /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
  822. {cartography-0.93.0rc1.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,272 @@
1
+ import json
2
+ import logging
3
+ from typing import Any
4
+
5
+ import boto3
6
+ from neo4j import Session
7
+
8
+ from cartography.client.aws import list_accounts
9
+ from cartography.client.aws.ecr import get_ecr_images
10
+ from cartography.config import Config
11
+ from cartography.intel.trivy.scanner import cleanup
12
+ from cartography.intel.trivy.scanner import get_json_files_in_dir
13
+ from cartography.intel.trivy.scanner import get_json_files_in_s3
14
+ from cartography.intel.trivy.scanner import sync_single_image
15
+ from cartography.stats import get_stats_client
16
+ from cartography.util import timeit
17
+
18
+ logger = logging.getLogger(__name__)
19
+ stat_handler = get_stats_client("trivy.scanner")
20
+
21
+
22
+ def _get_scan_targets_and_aliases(
23
+ neo4j_session: Session,
24
+ account_ids: list[str] | None = None,
25
+ ) -> tuple[set[str], dict[str, str]]:
26
+ """
27
+ Return tag URIs and a mapping of digest-qualified URIs to tag URIs.
28
+ """
29
+ if not account_ids:
30
+ aws_accounts = list_accounts(neo4j_session)
31
+ else:
32
+ aws_accounts = account_ids
33
+
34
+ image_uris: set[str] = set()
35
+ digest_aliases: dict[str, str] = {}
36
+
37
+ for account_id in aws_accounts:
38
+ for _, _, image_uri, _, digest in get_ecr_images(neo4j_session, account_id):
39
+ if not image_uri:
40
+ continue
41
+ image_uris.add(image_uri)
42
+ if digest:
43
+ # repo URI is everything before the trailing ":" (if present)
44
+ repo_uri = image_uri.rsplit(":", 1)[0]
45
+ digest_uri = f"{repo_uri}@{digest}"
46
+ digest_aliases[digest_uri] = image_uri
47
+
48
+ return image_uris, digest_aliases
49
+
50
+
51
+ @timeit
52
+ def get_scan_targets(
53
+ neo4j_session: Session,
54
+ account_ids: list[str] | None = None,
55
+ ) -> set[str]:
56
+ """
57
+ Return list of ECR images from all accounts in the graph.
58
+ """
59
+ image_uris, _ = _get_scan_targets_and_aliases(neo4j_session, account_ids)
60
+ return image_uris
61
+
62
+
63
+ def _prepare_trivy_data(
64
+ trivy_data: dict[str, Any],
65
+ image_uris: set[str],
66
+ digest_aliases: dict[str, str],
67
+ source: str,
68
+ ) -> tuple[dict[str, Any], str] | None:
69
+ """
70
+ Determine the tag URI that corresponds to this Trivy payload.
71
+
72
+ Returns (trivy_data, display_uri) if the payload can be linked to an image present
73
+ in the graph; otherwise returns None so the caller can skip ingestion.
74
+ """
75
+
76
+ artifact_name = (trivy_data.get("ArtifactName") or "").strip()
77
+ metadata = trivy_data.get("Metadata") or {}
78
+ candidates: list[str] = []
79
+
80
+ if artifact_name:
81
+ candidates.append(artifact_name)
82
+
83
+ repo_tags = metadata.get("RepoTags", [])
84
+ repo_digests = metadata.get("RepoDigests", [])
85
+ stripped_tags_digests = [item.strip() for item in repo_tags + repo_digests]
86
+ candidates.extend(stripped_tags_digests)
87
+
88
+ display_uri: str | None = None
89
+
90
+ for candidate in candidates:
91
+ if not candidate:
92
+ continue
93
+ if candidate in image_uris:
94
+ display_uri = candidate
95
+ break
96
+ alias = digest_aliases.get(candidate)
97
+ if alias:
98
+ display_uri = alias
99
+ break
100
+
101
+ if not display_uri:
102
+ logger.debug(
103
+ "Skipping Trivy results for %s because no matching image URI was found in the graph",
104
+ source,
105
+ )
106
+ return None
107
+
108
+ return trivy_data, display_uri
109
+
110
+
111
+ @timeit
112
+ def sync_trivy_aws_ecr_from_s3(
113
+ neo4j_session: Session,
114
+ trivy_s3_bucket: str,
115
+ trivy_s3_prefix: str,
116
+ update_tag: int,
117
+ common_job_parameters: dict[str, Any],
118
+ boto3_session: boto3.Session,
119
+ ) -> None:
120
+ """
121
+ Sync Trivy scan results from S3 for AWS ECR images.
122
+
123
+ Args:
124
+ neo4j_session: Neo4j session for database operations
125
+ trivy_s3_bucket: S3 bucket containing scan results
126
+ trivy_s3_prefix: S3 prefix path containing scan results
127
+ update_tag: Update tag for tracking
128
+ common_job_parameters: Common job parameters for cleanup
129
+ boto3_session: boto3 session for S3 operations
130
+ """
131
+ logger.info(
132
+ f"Using Trivy scan results from s3://{trivy_s3_bucket}/{trivy_s3_prefix}"
133
+ )
134
+
135
+ image_uris, digest_aliases = _get_scan_targets_and_aliases(neo4j_session)
136
+ json_files: set[str] = get_json_files_in_s3(
137
+ trivy_s3_bucket, trivy_s3_prefix, boto3_session
138
+ )
139
+
140
+ if len(json_files) == 0:
141
+ logger.error(
142
+ f"Trivy sync was configured, but there are no ECR images with S3 json scan results in bucket "
143
+ f"'{trivy_s3_bucket}' with prefix '{trivy_s3_prefix}'. "
144
+ "Skipping Trivy sync to avoid potential data loss. "
145
+ "Please check the S3 bucket and prefix configuration. We expect the json files in s3 to be named "
146
+ f"`<image_uri>.json` and to be in the same bucket and prefix as the scan results. If the prefix is "
147
+ "a folder, it MUST end with a trailing slash '/'. "
148
+ )
149
+ raise ValueError("No ECR images with S3 json scan results found.")
150
+
151
+ logger.info(f"Processing {len(json_files)} Trivy result files from S3")
152
+ s3_client = boto3_session.client("s3")
153
+ for s3_object_key in json_files:
154
+ logger.debug(
155
+ f"Reading scan results from S3: s3://{trivy_s3_bucket}/{s3_object_key}"
156
+ )
157
+ response = s3_client.get_object(Bucket=trivy_s3_bucket, Key=s3_object_key)
158
+ scan_data_json = response["Body"].read().decode("utf-8")
159
+ trivy_data = json.loads(scan_data_json)
160
+
161
+ prepared = _prepare_trivy_data(
162
+ trivy_data,
163
+ image_uris=image_uris,
164
+ digest_aliases=digest_aliases,
165
+ source=f"s3://{trivy_s3_bucket}/{s3_object_key}",
166
+ )
167
+ if prepared is None:
168
+ continue
169
+
170
+ prepared_data, display_uri = prepared
171
+ sync_single_image(
172
+ neo4j_session,
173
+ prepared_data,
174
+ display_uri,
175
+ update_tag,
176
+ )
177
+
178
+ cleanup(neo4j_session, common_job_parameters)
179
+
180
+
181
+ @timeit
182
+ def sync_trivy_aws_ecr_from_dir(
183
+ neo4j_session: Session,
184
+ results_dir: str,
185
+ update_tag: int,
186
+ common_job_parameters: dict[str, Any],
187
+ ) -> None:
188
+ """Sync Trivy scan results from local files for AWS ECR images."""
189
+ logger.info(f"Using Trivy scan results from {results_dir}")
190
+
191
+ image_uris, digest_aliases = _get_scan_targets_and_aliases(neo4j_session)
192
+ json_files: set[str] = get_json_files_in_dir(results_dir)
193
+
194
+ if not json_files:
195
+ logger.error(
196
+ f"Trivy sync was configured, but no json files were found in {results_dir}."
197
+ )
198
+ raise ValueError("No Trivy json results found on disk")
199
+
200
+ logger.info(f"Processing {len(json_files)} local Trivy result files")
201
+
202
+ for file_path in json_files:
203
+ try:
204
+ with open(file_path, encoding="utf-8") as f:
205
+ trivy_data = json.load(f)
206
+ except json.JSONDecodeError as e:
207
+ logger.error(f"Failed to read Trivy data from {file_path}: {e}")
208
+ continue
209
+
210
+ prepared = _prepare_trivy_data(
211
+ trivy_data,
212
+ image_uris=image_uris,
213
+ digest_aliases=digest_aliases,
214
+ source=file_path,
215
+ )
216
+ if prepared is None:
217
+ continue
218
+
219
+ prepared_data, display_uri = prepared
220
+ sync_single_image(
221
+ neo4j_session,
222
+ prepared_data,
223
+ display_uri,
224
+ update_tag,
225
+ )
226
+
227
+ cleanup(neo4j_session, common_job_parameters)
228
+
229
+
230
+ @timeit
231
+ def start_trivy_ingestion(neo4j_session: Session, config: Config) -> None:
232
+ """Start Trivy scan ingestion from S3 or local files.
233
+
234
+ Args:
235
+ neo4j_session: Neo4j session for database operations
236
+ config: Configuration object containing S3 or directory paths
237
+ """
238
+ if not config.trivy_s3_bucket and not config.trivy_results_dir:
239
+ logger.info("Trivy configuration not provided. Skipping Trivy ingestion.")
240
+ return
241
+
242
+ if config.trivy_results_dir:
243
+ common_job_parameters = {
244
+ "UPDATE_TAG": config.update_tag,
245
+ }
246
+ sync_trivy_aws_ecr_from_dir(
247
+ neo4j_session,
248
+ config.trivy_results_dir,
249
+ config.update_tag,
250
+ common_job_parameters,
251
+ )
252
+ return
253
+
254
+ if config.trivy_s3_prefix is None:
255
+ config.trivy_s3_prefix = ""
256
+
257
+ common_job_parameters = {
258
+ "UPDATE_TAG": config.update_tag,
259
+ }
260
+
261
+ boto3_session = boto3.Session()
262
+
263
+ sync_trivy_aws_ecr_from_s3(
264
+ neo4j_session,
265
+ config.trivy_s3_bucket,
266
+ config.trivy_s3_prefix,
267
+ config.update_tag,
268
+ common_job_parameters,
269
+ boto3_session,
270
+ )
271
+
272
+ # Support other Trivy resource types here e.g. if Google Cloud has images.
@@ -0,0 +1,386 @@
1
+ import json
2
+ import logging
3
+ import os
4
+ from typing import Any
5
+
6
+ import boto3
7
+ from neo4j import Session
8
+
9
+ from cartography.client.core.tx import load
10
+ from cartography.graph.job import GraphJob
11
+ from cartography.models.trivy.findings import TrivyImageFindingSchema
12
+ from cartography.models.trivy.fix import TrivyFixSchema
13
+ from cartography.models.trivy.package import TrivyPackageSchema
14
+ from cartography.stats import get_stats_client
15
+ from cartography.util import timeit
16
+
17
+ logger = logging.getLogger(__name__)
18
+ stat_handler = get_stats_client(__name__)
19
+
20
+
21
+ def _validate_packages(package_list: list[dict]) -> list[dict]:
22
+ """
23
+ Validates that each package has the required fields.
24
+ Returns only packages that have both InstalledVersion and PkgName.
25
+ """
26
+ validated_packages: list[dict] = []
27
+ for pkg in package_list:
28
+ if (
29
+ "InstalledVersion" in pkg
30
+ and pkg["InstalledVersion"]
31
+ and "PkgName" in pkg
32
+ and pkg["PkgName"]
33
+ ):
34
+ validated_packages.append(pkg)
35
+ else:
36
+ logger.warning(
37
+ "Package object does not have required fields `InstalledVersion` or `PkgName` - skipping."
38
+ )
39
+ return validated_packages
40
+
41
+
42
+ def transform_scan_results(
43
+ results: list[dict], image_digest: str
44
+ ) -> tuple[list[dict], list[dict], list[dict]]:
45
+ """
46
+ Transform raw Trivy scan results into a format suitable for loading into Neo4j.
47
+ Returns a tuple of (findings_list, packages_list, fixes_list).
48
+ """
49
+ findings_list = []
50
+ packages_list = []
51
+ fixes_list = []
52
+
53
+ for scan_class in results:
54
+ # Sometimes a scan class will have no vulns and Trivy will leave the key undefined instead of showing [].
55
+ if "Vulnerabilities" in scan_class and scan_class["Vulnerabilities"]:
56
+ for result in scan_class["Vulnerabilities"]:
57
+ # Transform finding data
58
+ finding = {
59
+ "id": f'TIF|{result["VulnerabilityID"]}',
60
+ "VulnerabilityID": result["VulnerabilityID"],
61
+ "cve_id": result["VulnerabilityID"],
62
+ "Description": result.get("Description"),
63
+ "LastModifiedDate": result.get("LastModifiedDate"),
64
+ "PrimaryURL": result.get("PrimaryURL"),
65
+ "PublishedDate": result.get("PublishedDate"),
66
+ "Severity": result["Severity"],
67
+ "SeveritySource": result.get("SeveritySource"),
68
+ "Title": result.get("Title"),
69
+ "nvd_v2_score": None,
70
+ "nvd_v2_vector": None,
71
+ "nvd_v3_score": None,
72
+ "nvd_v3_vector": None,
73
+ "redhat_v3_score": None,
74
+ "redhat_v3_vector": None,
75
+ "ubuntu_v3_score": None,
76
+ "ubuntu_v3_vector": None,
77
+ "Class": scan_class["Class"],
78
+ "Type": scan_class["Type"],
79
+ "ImageDigest": image_digest, # For AFFECTS relationship
80
+ }
81
+
82
+ # Add CVSS scores if available
83
+ if "CVSS" in result:
84
+ if "nvd" in result["CVSS"]:
85
+ nvd = result["CVSS"]["nvd"]
86
+ finding["nvd_v2_score"] = nvd.get("V2Score")
87
+ finding["nvd_v2_vector"] = nvd.get("V2Vector")
88
+ finding["nvd_v3_score"] = nvd.get("V3Score")
89
+ finding["nvd_v3_vector"] = nvd.get("V3Vector")
90
+ if "redhat" in result["CVSS"]:
91
+ redhat = result["CVSS"]["redhat"]
92
+ finding["redhat_v3_score"] = redhat.get("V3Score")
93
+ finding["redhat_v3_vector"] = redhat.get("V3Vector")
94
+ if "ubuntu" in result["CVSS"]:
95
+ ubuntu = result["CVSS"]["ubuntu"]
96
+ finding["ubuntu_v3_score"] = ubuntu.get("V3Score")
97
+ finding["ubuntu_v3_vector"] = ubuntu.get("V3Vector")
98
+
99
+ findings_list.append(finding)
100
+
101
+ # Transform package data
102
+ package_id = f"{result['InstalledVersion']}|{result['PkgName']}"
103
+ packages_list.append(
104
+ {
105
+ "id": package_id,
106
+ "InstalledVersion": result["InstalledVersion"],
107
+ "PkgName": result["PkgName"],
108
+ "Class": scan_class["Class"],
109
+ "Type": scan_class["Type"],
110
+ "ImageDigest": image_digest, # For DEPLOYED relationship
111
+ "FindingId": finding["id"], # For AFFECTS relationship
112
+ }
113
+ )
114
+
115
+ # Transform fix data if available
116
+ if result.get("FixedVersion") is not None:
117
+ fixes_list.append(
118
+ {
119
+ "id": f"{result['FixedVersion']}|{result['PkgName']}",
120
+ "FixedVersion": result["FixedVersion"],
121
+ "PackageId": package_id,
122
+ "FindingId": finding["id"],
123
+ }
124
+ )
125
+
126
+ # Validate packages before returning
127
+ packages_list = _validate_packages(packages_list)
128
+ return findings_list, packages_list, fixes_list
129
+
130
+
131
+ def _parse_trivy_data(
132
+ trivy_data: dict, source: str
133
+ ) -> tuple[str | None, list[dict], str]:
134
+ """
135
+ Parse Trivy scan data and extract common fields.
136
+
137
+ Args:
138
+ trivy_data: Raw JSON Trivy data
139
+ source: Source identifier for error messages (file path or S3 URI)
140
+
141
+ Returns:
142
+ Tuple of (artifact_name, results, image_digest)
143
+ """
144
+ # Extract artifact name if present (only for file-based)
145
+ artifact_name = trivy_data.get("ArtifactName")
146
+
147
+ if "Results" not in trivy_data:
148
+ logger.error(
149
+ f"Scan data did not contain a `Results` key for {source}. This indicates a malformed scan result."
150
+ )
151
+ raise ValueError(f"Missing 'Results' key in scan data for {source}")
152
+
153
+ results = trivy_data["Results"]
154
+ if not results:
155
+ stat_handler.incr("image_scan_no_results_count")
156
+ logger.info(f"No vulnerabilities found for {source}")
157
+
158
+ if "Metadata" not in trivy_data or not trivy_data["Metadata"]:
159
+ raise ValueError(f"Missing 'Metadata' in scan data for {source}")
160
+
161
+ repo_digests = trivy_data["Metadata"].get("RepoDigests", [])
162
+ if not repo_digests:
163
+ raise ValueError(f"Missing 'RepoDigests' in scan metadata for {source}")
164
+
165
+ repo_digest = repo_digests[0]
166
+ if "@" not in repo_digest:
167
+ raise ValueError(f"Invalid repo digest format in {source}: {repo_digest}")
168
+
169
+ image_digest = repo_digest.split("@")[1]
170
+ if not image_digest:
171
+ raise ValueError(f"Empty image digest for {source}")
172
+
173
+ return artifact_name, results, image_digest
174
+
175
+
176
+ @timeit
177
+ def sync_single_image(
178
+ neo4j_session: Session,
179
+ trivy_data: dict,
180
+ source: str,
181
+ update_tag: int,
182
+ ) -> None:
183
+ """
184
+ Sync a single image's Trivy scan results to Neo4j.
185
+
186
+ Args:
187
+ neo4j_session: Neo4j session for database operations
188
+ trivy_data: Raw Trivy JSON data
189
+ source: Source identifier for logging (file path or image URI)
190
+ update_tag: Update tag for tracking
191
+ """
192
+ try:
193
+ _, results, image_digest = _parse_trivy_data(trivy_data, source)
194
+
195
+ # Transform all data in one pass
196
+ findings_list, packages_list, fixes_list = transform_scan_results(
197
+ results,
198
+ image_digest,
199
+ )
200
+
201
+ num_findings = len(findings_list)
202
+ stat_handler.incr("image_scan_cve_count", num_findings)
203
+
204
+ # Load the transformed data
205
+ load_scan_vulns(neo4j_session, findings_list, update_tag=update_tag)
206
+ load_scan_packages(neo4j_session, packages_list, update_tag=update_tag)
207
+ load_scan_fixes(neo4j_session, fixes_list, update_tag=update_tag)
208
+ stat_handler.incr("images_processed_count")
209
+
210
+ except Exception as e:
211
+ logger.error(f"Failed to process scan results for {source}: {e}")
212
+ raise
213
+
214
+
215
+ @timeit
216
+ def get_json_files_in_s3(
217
+ s3_bucket: str, s3_prefix: str, boto3_session: boto3.Session
218
+ ) -> set[str]:
219
+ """
220
+ List S3 objects in the S3 prefix.
221
+
222
+ Args:
223
+ s3_bucket: S3 bucket name containing scan results
224
+ s3_prefix: S3 prefix path containing scan results
225
+ boto3_session: boto3 session for dependency injection
226
+
227
+ Returns:
228
+ Set of S3 object keys for JSON files in the S3 prefix
229
+ """
230
+ s3_client = boto3_session.client("s3")
231
+
232
+ try:
233
+ # List objects in the S3 prefix
234
+ paginator = s3_client.get_paginator("list_objects_v2")
235
+ page_iterator = paginator.paginate(Bucket=s3_bucket, Prefix=s3_prefix)
236
+ results = set()
237
+
238
+ for page in page_iterator:
239
+ if "Contents" not in page:
240
+ continue
241
+
242
+ for obj in page["Contents"]:
243
+ object_key = obj["Key"]
244
+
245
+ # Skip non-JSON files
246
+ if not object_key.endswith(".json"):
247
+ continue
248
+
249
+ # Skip files that don't start with our prefix
250
+ if not object_key.startswith(s3_prefix):
251
+ continue
252
+
253
+ results.add(object_key)
254
+
255
+ except Exception as e:
256
+ logger.error(
257
+ f"Error listing S3 objects in bucket {s3_bucket} with prefix {s3_prefix}: {e}"
258
+ )
259
+ raise
260
+
261
+ logger.info(f"Found {len(results)} json files in s3://{s3_bucket}/{s3_prefix}")
262
+ return results
263
+
264
+
265
+ @timeit
266
+ def get_json_files_in_dir(results_dir: str) -> set[str]:
267
+ """Return set of JSON file paths under a directory."""
268
+ results = set()
269
+ for root, _dirs, files in os.walk(results_dir):
270
+ for filename in files:
271
+ if filename.endswith(".json"):
272
+ results.add(os.path.join(root, filename))
273
+ logger.info(f"Found {len(results)} json files in {results_dir}")
274
+ return results
275
+
276
+
277
+ @timeit
278
+ def cleanup(neo4j_session: Session, common_job_parameters: dict[str, Any]) -> None:
279
+ """
280
+ Run cleanup jobs for Trivy nodes.
281
+ """
282
+ logger.info("Running Trivy cleanup")
283
+ GraphJob.from_node_schema(TrivyImageFindingSchema(), common_job_parameters).run(
284
+ neo4j_session
285
+ )
286
+ GraphJob.from_node_schema(TrivyPackageSchema(), common_job_parameters).run(
287
+ neo4j_session
288
+ )
289
+ GraphJob.from_node_schema(TrivyFixSchema(), common_job_parameters).run(
290
+ neo4j_session
291
+ )
292
+
293
+
294
+ @timeit
295
+ def load_scan_vulns(
296
+ neo4j_session: Session,
297
+ findings_list: list[dict[str, Any]],
298
+ update_tag: int,
299
+ ) -> None:
300
+ """
301
+ Load TrivyImageFinding nodes into Neo4j.
302
+ """
303
+ load(
304
+ neo4j_session,
305
+ TrivyImageFindingSchema(),
306
+ findings_list,
307
+ lastupdated=update_tag,
308
+ )
309
+
310
+
311
+ @timeit
312
+ def load_scan_packages(
313
+ neo4j_session: Session,
314
+ packages_list: list[dict[str, Any]],
315
+ update_tag: int,
316
+ ) -> None:
317
+ """
318
+ Load TrivyPackage nodes into Neo4j.
319
+ """
320
+ load(
321
+ neo4j_session,
322
+ TrivyPackageSchema(),
323
+ packages_list,
324
+ lastupdated=update_tag,
325
+ )
326
+
327
+
328
+ @timeit
329
+ def load_scan_fixes(
330
+ neo4j_session: Session,
331
+ fixes_list: list[dict[str, Any]],
332
+ update_tag: int,
333
+ ) -> None:
334
+ """
335
+ Load TrivyFix nodes into Neo4j.
336
+ """
337
+ load(
338
+ neo4j_session,
339
+ TrivyFixSchema(),
340
+ fixes_list,
341
+ lastupdated=update_tag,
342
+ )
343
+
344
+
345
+ @timeit
346
+ def sync_single_image_from_s3(
347
+ neo4j_session: Session,
348
+ image_uri: str,
349
+ update_tag: int,
350
+ s3_bucket: str,
351
+ s3_object_key: str,
352
+ boto3_session: boto3.Session,
353
+ ) -> None:
354
+ """
355
+ Read Trivy scan results from S3 and sync to Neo4j.
356
+
357
+ Args:
358
+ neo4j_session: Neo4j session for database operations
359
+ image_uri: ECR image URI
360
+ update_tag: Update tag for tracking
361
+ s3_bucket: S3 bucket containing scan results
362
+ s3_object_key: S3 object key for this image's scan results
363
+ boto3_session: boto3 session for S3 operations
364
+ """
365
+ s3_client = boto3_session.client("s3")
366
+
367
+ logger.debug(f"Reading scan results from S3: s3://{s3_bucket}/{s3_object_key}")
368
+ response = s3_client.get_object(Bucket=s3_bucket, Key=s3_object_key)
369
+ scan_data_json = response["Body"].read().decode("utf-8")
370
+
371
+ trivy_data = json.loads(scan_data_json)
372
+ sync_single_image(neo4j_session, trivy_data, image_uri, update_tag)
373
+
374
+
375
+ @timeit
376
+ def sync_single_image_from_file(
377
+ neo4j_session: Session,
378
+ file_path: str,
379
+ update_tag: int,
380
+ ) -> None:
381
+ """Read a Trivy JSON file from disk and sync to Neo4j."""
382
+ logger.debug(f"Reading scan results from file: {file_path}")
383
+ with open(file_path, encoding="utf-8") as f:
384
+ trivy_data = json.load(f)
385
+
386
+ sync_single_image(neo4j_session, trivy_data, file_path, update_tag)
File without changes