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
@@ -3,131 +3,58 @@ import logging
3
3
  from collections import namedtuple
4
4
  from typing import Dict
5
5
  from typing import List
6
+ from typing import Optional
6
7
  from typing import Set
7
8
 
8
- import googleapiclient.discovery
9
9
  import neo4j
10
+ from google.auth.credentials import Credentials as GoogleCredentials
11
+ from google.cloud.asset_v1 import AssetServiceClient
12
+ from googleapiclient.discovery import HttpError
10
13
  from googleapiclient.discovery import Resource
11
- from oauth2client.client import ApplicationDefaultCredentialsError
12
- from oauth2client.client import GoogleCredentials
13
14
 
14
15
  from cartography.config import Config
16
+ from cartography.graph.job import GraphJob
17
+ from cartography.intel.gcp import bigtable_app_profile
18
+ from cartography.intel.gcp import bigtable_backup
19
+ from cartography.intel.gcp import bigtable_cluster
20
+ from cartography.intel.gcp import bigtable_instance
21
+ from cartography.intel.gcp import bigtable_table
22
+ from cartography.intel.gcp import cai
15
23
  from cartography.intel.gcp import compute
16
- from cartography.intel.gcp import crm
17
24
  from cartography.intel.gcp import dns
18
25
  from cartography.intel.gcp import gke
26
+ from cartography.intel.gcp import iam
27
+ from cartography.intel.gcp import permission_relationships
28
+ from cartography.intel.gcp import policy_bindings
19
29
  from cartography.intel.gcp import storage
30
+ from cartography.intel.gcp.clients import build_asset_client
31
+ from cartography.intel.gcp.clients import build_client
32
+ from cartography.intel.gcp.clients import get_gcp_credentials
33
+ from cartography.intel.gcp.crm.folders import sync_gcp_folders
34
+ from cartography.intel.gcp.crm.orgs import sync_gcp_organizations
35
+ from cartography.intel.gcp.crm.projects import sync_gcp_projects
36
+ from cartography.models.gcp.crm.folders import GCPFolderSchema
37
+ from cartography.models.gcp.crm.organizations import GCPOrganizationSchema
38
+ from cartography.models.gcp.crm.projects import GCPProjectSchema
20
39
  from cartography.util import run_analysis_job
21
40
  from cartography.util import timeit
22
41
 
23
42
  logger = logging.getLogger(__name__)
24
- Resources = namedtuple('Resources', 'compute container crm_v1 crm_v2 dns storage serviceusage')
25
43
 
26
44
  # Mapping of service short names to their full names as in docs. See https://developers.google.com/apis-explorer,
27
45
  # and https://cloud.google.com/service-usage/docs/reference/rest/v1/services#ServiceConfig
28
- Services = namedtuple('Services', 'compute storage gke dns')
46
+ Services = namedtuple("Services", "compute storage gke dns iam bigtable cai")
29
47
  service_names = Services(
30
- compute='compute.googleapis.com',
31
- storage='storage.googleapis.com',
32
- gke='container.googleapis.com',
33
- dns='dns.googleapis.com',
48
+ compute="compute.googleapis.com",
49
+ storage="storage.googleapis.com",
50
+ gke="container.googleapis.com",
51
+ dns="dns.googleapis.com",
52
+ iam="iam.googleapis.com",
53
+ bigtable="bigtableadmin.googleapis.com",
54
+ cai="cloudasset.googleapis.com",
34
55
  )
35
56
 
36
57
 
37
- def _get_crm_resource_v1(credentials: GoogleCredentials) -> Resource:
38
- """
39
- Instantiates a Google Compute Resource Manager v1 resource object to call the Resource Manager API.
40
- See https://cloud.google.com/resource-manager/reference/rest/.
41
- :param credentials: The GoogleCredentials object
42
- :return: A CRM v1 resource object
43
- """
44
- # cache_discovery=False to suppress extra warnings.
45
- # See https://github.com/googleapis/google-api-python-client/issues/299#issuecomment-268915510 and related issues
46
- return googleapiclient.discovery.build('cloudresourcemanager', 'v1', credentials=credentials, cache_discovery=False)
47
-
48
-
49
- def _get_crm_resource_v2(credentials: GoogleCredentials) -> Resource:
50
- """
51
- Instantiates a Google Compute Resource Manager v2 resource object to call the Resource Manager API.
52
- We need a v2 resource object to query for GCP folders.
53
- :param credentials: The GoogleCredentials object
54
- :return: A CRM v2 resource object
55
- """
56
- return googleapiclient.discovery.build('cloudresourcemanager', 'v2', credentials=credentials, cache_discovery=False)
57
-
58
-
59
- def _get_compute_resource(credentials: GoogleCredentials) -> Resource:
60
- """
61
- Instantiates a Google Compute resource object to call the Compute API. This is used to pull zone, instance, and
62
- networking data. See https://cloud.google.com/compute/docs/reference/rest/v1/.
63
- :param credentials: The GoogleCredentials object
64
- :return: A Compute resource object
65
- """
66
- return googleapiclient.discovery.build('compute', 'v1', credentials=credentials, cache_discovery=False)
67
-
68
-
69
- def _get_storage_resource(credentials: GoogleCredentials) -> Resource:
70
- """
71
- Instantiates a Google Cloud Storage resource object to call the Storage API.
72
- This is used to pull bucket metadata and IAM Policies
73
- as well as list buckets in a specified project.
74
- See https://cloud.google.com/storage/docs/json_api/.
75
- :param credentials: The GoogleCredentials object
76
- :return: A Storage resource object
77
- """
78
- return googleapiclient.discovery.build('storage', 'v1', credentials=credentials, cache_discovery=False)
79
-
80
-
81
- def _get_container_resource(credentials: GoogleCredentials) -> Resource:
82
- """
83
- Instantiates a Google Cloud Container resource object to call the
84
- Container API. See: https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/.
85
-
86
- :param credentials: The GoogleCredentials object
87
- :return: A Container resource object
88
- """
89
- return googleapiclient.discovery.build('container', 'v1', credentials=credentials, cache_discovery=False)
90
-
91
-
92
- def _get_dns_resource(credentials: GoogleCredentials) -> Resource:
93
- """
94
- Instantiates a Google Cloud DNS resource object to call the
95
- Container API. See: https://cloud.google.com/dns/docs/reference/v1/.
96
-
97
- :param credentials: The GoogleCredentials object
98
- :return: A DNS resource object
99
- """
100
- return googleapiclient.discovery.build('dns', 'v1', credentials=credentials, cache_discovery=False)
101
-
102
-
103
- def _get_serviceusage_resource(credentials: GoogleCredentials) -> Resource:
104
- """
105
- Instantiates a serviceusage resource object.
106
- See: https://cloud.google.com/service-usage/docs/reference/rest/v1/operations/list.
107
-
108
- :param credentials: The GoogleCredentials object
109
- :return: A serviceusage resource object
110
- """
111
- return googleapiclient.discovery.build('serviceusage', 'v1', credentials=credentials, cache_discovery=False)
112
-
113
-
114
- def _initialize_resources(credentials: GoogleCredentials) -> Resource:
115
- """
116
- Create namedtuple of all resource objects necessary for GCP data gathering.
117
- :param credentials: The GoogleCredentials object
118
- :return: namedtuple of all resource objects
119
- """
120
- return Resources(
121
- crm_v1=_get_crm_resource_v1(credentials),
122
- crm_v2=_get_crm_resource_v2(credentials),
123
- compute=_get_compute_resource(credentials),
124
- storage=_get_storage_resource(credentials),
125
- container=_get_container_resource(credentials),
126
- serviceusage=_get_serviceusage_resource(credentials),
127
- dns=_get_dns_resource(credentials),
128
- )
129
-
130
-
131
58
  def _services_enabled_on_project(serviceusage: Resource, project_id: str) -> Set:
132
59
  """
133
60
  Return a list of all Google API services that are enabled on the given project ID.
@@ -138,16 +65,22 @@ def _services_enabled_on_project(serviceusage: Resource, project_id: str) -> Set
138
65
  :return: A set of services that are enabled on the project
139
66
  """
140
67
  try:
141
- req = serviceusage.services().list(parent=f'projects/{project_id}', filter='state:ENABLED')
68
+ req = serviceusage.services().list(
69
+ parent=f"projects/{project_id}",
70
+ filter="state:ENABLED",
71
+ )
142
72
  services = set()
143
73
  while req is not None:
144
74
  res = req.execute()
145
- if 'services' in res:
146
- services.update({svc['config']['name'] for svc in res['services']})
147
- req = serviceusage.services().list_next(previous_request=req, previous_response=res)
75
+ if "services" in res:
76
+ services.update({svc["config"]["name"] for svc in res["services"]})
77
+ req = serviceusage.services().list_next(
78
+ previous_request=req,
79
+ previous_response=res,
80
+ )
148
81
  return services
149
- except googleapiclient.discovery.HttpError as http_error:
150
- http_error = json.loads(http_error.content.decode('utf-8'))
82
+ except HttpError as http_error:
83
+ http_error = json.loads(http_error.content.decode("utf-8"))
151
84
  # This is set to log-level `info` because Google creates many projects under the hood that cartography cannot
152
85
  # audit (e.g. adding a script to a Google spreadsheet causes a project to get created) and we don't need to emit
153
86
  # a warning for these projects.
@@ -159,112 +92,385 @@ def _services_enabled_on_project(serviceusage: Resource, project_id: str) -> Set
159
92
  return set()
160
93
 
161
94
 
162
- def _sync_single_project(
163
- neo4j_session: neo4j.Session, resources: Resource, project_id: str, gcp_update_tag: int,
95
+ def _sync_project_resources(
96
+ neo4j_session: neo4j.Session,
97
+ projects: List[Dict],
98
+ gcp_update_tag: int,
164
99
  common_job_parameters: Dict,
100
+ credentials: GoogleCredentials,
165
101
  ) -> None:
166
102
  """
167
- Handles graph sync for a single GCP project.
103
+ Syncs GCP service-specific resources (Compute, Storage, GKE, DNS, IAM) for each project.
168
104
  :param neo4j_session: The Neo4j session
169
- :param resources: namedtuple of the GCP resource objects
170
- :param project_id: The project ID number to sync. See the `projectId` field in
171
- https://cloud.google.com/resource-manager/reference/rest/v1/projects
105
+ :param projects: A list of projects containing at minimum a "projectId" field.
172
106
  :param gcp_update_tag: The timestamp value to set our new Neo4j nodes with
173
107
  :param common_job_parameters: Other parameters sent to Neo4j
108
+ :param credentials: GCP credentials to use for API calls.
174
109
  :return: Nothing
175
110
  """
176
- # Determine the resources available on the project.
177
- enabled_services = _services_enabled_on_project(resources.serviceusage, project_id)
178
- if service_names.compute in enabled_services:
179
- compute.sync(neo4j_session, resources.compute, project_id, gcp_update_tag, common_job_parameters)
180
- if service_names.storage in enabled_services:
181
- storage.sync_gcp_buckets(neo4j_session, resources.storage, project_id, gcp_update_tag, common_job_parameters)
182
- if service_names.gke in enabled_services:
183
- gke.sync_gke_clusters(neo4j_session, resources.container, project_id, gcp_update_tag, common_job_parameters)
184
- if service_names.dns in enabled_services:
185
- dns.sync(neo4j_session, resources.dns, project_id, gcp_update_tag, common_job_parameters)
186
-
187
-
188
- def _sync_multiple_projects(
189
- neo4j_session: neo4j.Session, resources: Resource, projects: List[Dict],
190
- gcp_update_tag: int, common_job_parameters: Dict,
191
- ) -> None:
192
- """
193
- Handles graph sync for multiple GCP projects.
194
- :param neo4j_session: The Neo4j session
195
- :param resources: namedtuple of the GCP resource objects
196
- :param: projects: A list of projects. At minimum, this list should contain a list of dicts with the key "projectId"
197
- defined; so it would look like this: [{"projectId": "my-project-id-12345"}].
198
- This is the returned data from `crm.get_gcp_projects()`.
199
- See https://cloud.google.com/resource-manager/reference/rest/v1/projects.
200
- :param gcp_update_tag: The timestamp value to set our new Neo4j nodes with
201
- :param common_job_parameters: Other parameters sent to Neo4j
202
- :return: Nothing
203
- """
204
- logger.info("Syncing %d GCP projects.", len(projects))
205
- crm.sync_gcp_projects(neo4j_session, projects, gcp_update_tag, common_job_parameters)
111
+ logger.info("Syncing resources for %d GCP projects.", len(projects))
112
+
113
+ # Cloud Asset Inventory (CAI) clients are lazily initialized and reused across all projects.
114
+ # CAI is used for:
115
+ # 1. Fallback IAM sync when IAM API is disabled on target projects (cai_rest_client)
116
+ # 2. Policy bindings sync (cai_grpc_client)
117
+ #
118
+ # Note: We do NOT explicitly set a quota project for CAI clients. Google's default behavior
119
+ # will use the service account's host project for quota/billing, which doesn't require
120
+ # the serviceusage.serviceUsageConsumer permission.
121
+ cai_rest_client: Optional[Resource] = None # REST client for asset listing
122
+ cai_grpc_client: Optional[AssetServiceClient] = None # gRPC client for policy APIs
123
+ cai_enabled_on_first_project: Optional[bool] = (
124
+ None # Cached check for CAI enablement
125
+ )
126
+ policy_bindings_permission_ok: Optional[bool] = (
127
+ None # Track if we have permission for policy bindings
128
+ )
129
+
130
+ # Predefined roles are global (not project-specific), so we fetch them once
131
+ # and reuse them for all target projects that use the CAI fallback.
132
+ predefined_roles: Optional[List[Dict]] = None
206
133
 
134
+ # Per-project sync across services
207
135
  for project in projects:
208
- project_id = project['projectId']
209
- logger.info("Syncing GCP project %s.", project_id)
210
- _sync_single_project(neo4j_session, resources, project_id, gcp_update_tag, common_job_parameters)
136
+ project_id = project["projectId"]
137
+ common_job_parameters["PROJECT_ID"] = project_id
138
+ enabled_services = _services_enabled_on_project(
139
+ build_client("serviceusage", "v1", credentials=credentials),
140
+ project_id,
141
+ )
142
+
143
+ if service_names.compute in enabled_services:
144
+ logger.info("Syncing GCP project %s for Compute.", project_id)
145
+ compute_cred = build_client("compute", "v1", credentials=credentials)
146
+ compute.sync(
147
+ neo4j_session,
148
+ compute_cred,
149
+ project_id,
150
+ gcp_update_tag,
151
+ common_job_parameters,
152
+ )
153
+
154
+ if service_names.storage in enabled_services:
155
+ logger.info("Syncing GCP project %s for Storage.", project_id)
156
+ storage_cred = build_client("storage", "v1", credentials=credentials)
157
+ storage.sync_gcp_buckets(
158
+ neo4j_session,
159
+ storage_cred,
160
+ project_id,
161
+ gcp_update_tag,
162
+ common_job_parameters,
163
+ )
164
+
165
+ if service_names.gke in enabled_services:
166
+ logger.info("Syncing GCP project %s for GKE.", project_id)
167
+ container_cred = build_client("container", "v1", credentials=credentials)
168
+ gke.sync_gke_clusters(
169
+ neo4j_session,
170
+ container_cred,
171
+ project_id,
172
+ gcp_update_tag,
173
+ common_job_parameters,
174
+ )
175
+
176
+ if service_names.dns in enabled_services:
177
+ logger.info("Syncing GCP project %s for DNS.", project_id)
178
+ dns_cred = build_client("dns", "v1", credentials=credentials)
179
+ dns.sync(
180
+ neo4j_session,
181
+ dns_cred,
182
+ project_id,
183
+ gcp_update_tag,
184
+ common_job_parameters,
185
+ )
186
+
187
+ if service_names.iam in enabled_services:
188
+ logger.info("Syncing GCP project %s for IAM.", project_id)
189
+ iam_cred = build_client("iam", "v1", credentials=credentials)
190
+ iam.sync(
191
+ neo4j_session,
192
+ iam_cred,
193
+ project_id,
194
+ gcp_update_tag,
195
+ common_job_parameters,
196
+ )
197
+ else:
198
+ # Fallback to Cloud Asset Inventory even if the target project does not have the IAM API enabled.
199
+ # CAI uses the service account's host project for quota by default (no explicit quota project needed).
200
+ # Lazily initialize the CAI REST client once and reuse it for all projects.
201
+ if cai_rest_client is None:
202
+ cai_rest_client = build_client(
203
+ "cloudasset",
204
+ "v1",
205
+ credentials=credentials,
206
+ )
207
+
208
+ # Fetch predefined roles once for CAI fallback (they're global, not project-specific)
209
+ if predefined_roles is None:
210
+ logger.info("Fetching predefined IAM roles for CAI fallback")
211
+ iam_client = build_client("iam", "v1", credentials=credentials)
212
+ predefined_roles = iam.get_gcp_predefined_roles(iam_client)
213
+ logger.info(
214
+ "Fetched %d predefined IAM roles",
215
+ len(predefined_roles),
216
+ )
217
+
218
+ logger.info(
219
+ "IAM API not enabled. Attempting IAM sync for project %s via Cloud Asset Inventory.",
220
+ project_id,
221
+ )
222
+ try:
223
+ cai.sync(
224
+ neo4j_session,
225
+ cai_rest_client,
226
+ project_id,
227
+ gcp_update_tag,
228
+ common_job_parameters,
229
+ predefined_roles=predefined_roles,
230
+ )
231
+ except HttpError as e:
232
+ if e.resp.status == 403:
233
+ logger.warning(
234
+ "CAI fallback skipped for project %s: %s. "
235
+ "Ensure Cloud Asset API is enabled and roles/cloudasset.viewer is granted.",
236
+ project_id,
237
+ e.reason,
238
+ )
239
+ else:
240
+ raise
241
+ if service_names.bigtable in enabled_services:
242
+ logger.info(f"Syncing GCP project {project_id} for Bigtable.")
243
+ bigtable_client = build_client(
244
+ "bigtableadmin", "v2", credentials=credentials
245
+ )
246
+ instances_raw = bigtable_instance.sync_bigtable_instances(
247
+ neo4j_session,
248
+ bigtable_client,
249
+ project_id,
250
+ gcp_update_tag,
251
+ common_job_parameters,
252
+ )
253
+
254
+ if instances_raw:
255
+ clusters_raw = bigtable_cluster.sync_bigtable_clusters(
256
+ neo4j_session,
257
+ bigtable_client,
258
+ instances_raw,
259
+ project_id,
260
+ gcp_update_tag,
261
+ common_job_parameters,
262
+ )
263
+
264
+ bigtable_table.sync_bigtable_tables(
265
+ neo4j_session,
266
+ bigtable_client,
267
+ instances_raw,
268
+ project_id,
269
+ gcp_update_tag,
270
+ common_job_parameters,
271
+ )
272
+
273
+ bigtable_app_profile.sync_bigtable_app_profiles(
274
+ neo4j_session,
275
+ bigtable_client,
276
+ instances_raw,
277
+ project_id,
278
+ gcp_update_tag,
279
+ common_job_parameters,
280
+ )
281
+
282
+ if clusters_raw:
283
+ bigtable_backup.sync_bigtable_backups(
284
+ neo4j_session,
285
+ bigtable_client,
286
+ clusters_raw,
287
+ project_id,
288
+ gcp_update_tag,
289
+ common_job_parameters,
290
+ )
291
+
292
+ # Policy bindings sync uses CAI gRPC client.
293
+ # We attempt policy bindings for all projects unless we've already encountered a permission error.
294
+ # CAI uses the service account's host project for quota by default.
295
+ if policy_bindings_permission_ok is not False:
296
+ # Check if CAI is enabled (cached after first check on first project)
297
+ if cai_enabled_on_first_project is None:
298
+ first_project_services = _services_enabled_on_project(
299
+ build_client("serviceusage", "v1", credentials=credentials),
300
+ project_id,
301
+ )
302
+ cai_enabled_on_first_project = (
303
+ service_names.cai in first_project_services
304
+ )
305
+ if cai_enabled_on_first_project:
306
+ logger.info(
307
+ "CAI enabled, will sync policy bindings for all projects.",
308
+ )
309
+ else:
310
+ logger.info(
311
+ "CAI not enabled on project %s, skipping policy bindings sync. "
312
+ "Enable the Cloud Asset Inventory API to sync IAM policy bindings.",
313
+ project_id,
314
+ )
315
+
316
+ if cai_enabled_on_first_project:
317
+ # Lazily initialize CAI gRPC client for policy bindings.
318
+ if cai_grpc_client is None:
319
+ cai_grpc_client = build_asset_client(
320
+ credentials=credentials,
321
+ )
322
+ logger.info(
323
+ "Syncing IAM policies for GCP project %s.",
324
+ project_id,
325
+ )
326
+ success = policy_bindings.sync(
327
+ neo4j_session,
328
+ project_id,
329
+ gcp_update_tag,
330
+ common_job_parameters,
331
+ cai_grpc_client,
332
+ )
333
+ # Track if we have permission. Once set to False (permission denied),
334
+ # the outer condition will skip policy_bindings for remaining projects.
335
+ if not success:
336
+ policy_bindings_permission_ok = False
337
+
338
+ permission_relationships.sync(
339
+ neo4j_session,
340
+ project_id,
341
+ gcp_update_tag,
342
+ common_job_parameters,
343
+ )
344
+
345
+ del common_job_parameters["PROJECT_ID"]
211
346
 
212
347
 
213
348
  @timeit
214
- def start_gcp_ingestion(neo4j_session: neo4j.Session, config: Config) -> None:
349
+ def start_gcp_ingestion(
350
+ neo4j_session: neo4j.Session,
351
+ config: Config,
352
+ credentials: Optional[GoogleCredentials] = None,
353
+ ) -> None:
215
354
  """
216
355
  Starts the GCP ingestion process by initializing Google Application Default Credentials, creating the necessary
217
356
  resource objects, listing all GCP organizations and projects available to the GCP identity, and supplying that
218
357
  context to all intel modules.
219
358
  :param neo4j_session: The Neo4j session
220
359
  :param config: A `cartography.config` object
360
+ :param credentials: Optional GCP credentials. If not provided, ADC will be used.
221
361
  :return: Nothing
222
362
  """
363
+ # Initialize credentials from ADC if not provided. This ensures we have a single
364
+ # credentials object used consistently across all API clients.
365
+ if credentials is None:
366
+ credentials = get_gcp_credentials()
367
+ if credentials is None:
368
+ raise RuntimeError(
369
+ "GCP credentials are not available; cannot start GCP ingestion."
370
+ )
371
+
223
372
  common_job_parameters = {
224
373
  "UPDATE_TAG": config.update_tag,
374
+ "gcp_permission_relationships_file": config.gcp_permission_relationships_file,
225
375
  }
226
- try:
227
- # Explicitly use Application Default Credentials.
228
- # See https://oauth2client.readthedocs.io/en/latest/source/
229
- # oauth2client.client.html#oauth2client.client.OAuth2Credentials
230
- credentials = GoogleCredentials.get_application_default()
231
- except ApplicationDefaultCredentialsError as e:
232
- logger.debug("Error occurred calling GoogleCredentials.get_application_default().", exc_info=True)
233
- logger.error(
234
- (
235
- "Unable to initialize Google Compute Platform creds. If you don't have GCP data or don't want to load "
236
- "GCP data then you can ignore this message. Otherwise, the error code is: %s "
237
- "Make sure your GCP credentials are configured correctly, your credentials file (if any) is valid, and "
238
- "that the identity you are authenticating to has the securityReviewer role attached."
239
- ),
240
- e,
376
+
377
+ # IMPORTANT: We defer cleanup for hierarchical resources (orgs, folders, projects) and run them
378
+ # in reverse order. This prevents orphaned nodes when a parent is deleted.
379
+ # Without this, deleting an org would break its relationships to projects/folders, leaving them
380
+ # disconnected and unable to be cleaned up by their own cleanup jobs.
381
+ #
382
+ # Order of operations:
383
+ # 1. Sync all orgs
384
+ # 2. For each org:
385
+ # a. Sync folders and projects
386
+ # b. Sync project resources (with immediate cleanup)
387
+ # c. Clean up projects and folders for this org
388
+ # 3. Clean up all orgs at the end
389
+ #
390
+ # This ensures children are cleaned up before their parents.
391
+
392
+ orgs = sync_gcp_organizations(
393
+ neo4j_session,
394
+ config.update_tag,
395
+ common_job_parameters,
396
+ credentials=credentials,
397
+ )
398
+
399
+ # Track org cleanup jobs to run at the very end
400
+ org_cleanup_jobs = []
401
+
402
+ # For each org, sync its folders and projects (as sub-resources), then ingest per-project services
403
+ for org in orgs:
404
+ org_resource_name = org.get("name", "") # e.g., organizations/123456789012
405
+ if not org_resource_name or "/" not in org_resource_name:
406
+ logger.error(f"Invalid org resource name: {org_resource_name}")
407
+ continue
408
+
409
+ # Store the full resource name for cleanup operations
410
+ common_job_parameters["ORG_RESOURCE_NAME"] = org_resource_name
411
+
412
+ # Sync folders under org
413
+ folders = sync_gcp_folders(
414
+ neo4j_session,
415
+ config.update_tag,
416
+ common_job_parameters,
417
+ org_resource_name,
418
+ credentials=credentials,
419
+ )
420
+
421
+ # Sync projects under org and each folder
422
+ projects = sync_gcp_projects(
423
+ neo4j_session,
424
+ org_resource_name,
425
+ folders,
426
+ config.update_tag,
427
+ common_job_parameters,
428
+ credentials=credentials,
241
429
  )
242
- return
243
430
 
244
- resources = _initialize_resources(credentials)
431
+ # Ingest per-project resources (these run their own cleanup immediately since they're leaf nodes)
432
+ _sync_project_resources(
433
+ neo4j_session,
434
+ projects,
435
+ config.update_tag,
436
+ common_job_parameters,
437
+ credentials=credentials,
438
+ )
439
+
440
+ # Clean up projects and folders for this org (children before parents)
441
+ logger.debug(f"Running cleanup for projects and folders in {org_resource_name}")
442
+ GraphJob.from_node_schema(GCPProjectSchema(), common_job_parameters).run(
443
+ neo4j_session
444
+ )
445
+ GraphJob.from_node_schema(GCPFolderSchema(), common_job_parameters).run(
446
+ neo4j_session
447
+ )
245
448
 
246
- # If we don't have perms to pull Orgs or Folders from GCP, we will skip safely
247
- crm.sync_gcp_organizations(neo4j_session, resources.crm_v1, config.update_tag, common_job_parameters)
248
- crm.sync_gcp_folders(neo4j_session, resources.crm_v2, config.update_tag, common_job_parameters)
449
+ # Save org cleanup job for later
450
+ org_cleanup_jobs.append((GCPOrganizationSchema, dict(common_job_parameters)))
249
451
 
250
- projects = crm.get_gcp_projects(resources.crm_v1)
452
+ # Remove org ID from common job parameters after processing
453
+ del common_job_parameters["ORG_RESOURCE_NAME"]
251
454
 
252
- _sync_multiple_projects(neo4j_session, resources, projects, config.update_tag, common_job_parameters)
455
+ # Run all org cleanup jobs at the very end, after all children have been cleaned up
456
+ logger.info("Running cleanup for GCP organizations")
457
+ for schema_class, params in org_cleanup_jobs:
458
+ GraphJob.from_node_schema(schema_class(), params).run(neo4j_session)
253
459
 
254
460
  run_analysis_job(
255
- 'gcp_compute_asset_inet_exposure.json',
461
+ "gcp_compute_asset_inet_exposure.json",
256
462
  neo4j_session,
257
463
  common_job_parameters,
258
464
  )
259
465
 
260
466
  run_analysis_job(
261
- 'gcp_gke_asset_exposure.json',
467
+ "gcp_gke_asset_exposure.json",
262
468
  neo4j_session,
263
469
  common_job_parameters,
264
470
  )
265
471
 
266
472
  run_analysis_job(
267
- 'gcp_gke_basic_auth.json',
473
+ "gcp_gke_basic_auth.json",
268
474
  neo4j_session,
269
475
  common_job_parameters,
270
476
  )