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,847 @@
1
+ import logging
2
+ from typing import Any
3
+
4
+ import boto3
5
+ import botocore.exceptions
6
+ import neo4j
7
+
8
+ from cartography.client.core.tx import load
9
+ from cartography.client.core.tx import load_matchlinks
10
+ from cartography.client.core.tx import read_list_of_dicts_tx
11
+ from cartography.graph.job import GraphJob
12
+ from cartography.models.aws.identitycenter.awsidentitycenter import (
13
+ AWSIdentityCenterInstanceSchema,
14
+ )
15
+ from cartography.models.aws.identitycenter.awspermissionset import (
16
+ AWSPermissionSetSchema,
17
+ )
18
+ from cartography.models.aws.identitycenter.awspermissionset import (
19
+ AWSRoleToSSOGroupMatchLink,
20
+ )
21
+ from cartography.models.aws.identitycenter.awspermissionset import (
22
+ AWSRoleToSSOUserMatchLink,
23
+ )
24
+ from cartography.models.aws.identitycenter.awssogroup import AWSSSOGroupSchema
25
+ from cartography.models.aws.identitycenter.awsssouser import AWSSSOUserSchema
26
+ from cartography.util import aws_handle_regions
27
+ from cartography.util import timeit
28
+
29
+ logger = logging.getLogger(__name__)
30
+
31
+
32
+ def _is_permission_set_sync_unsupported_error(
33
+ error: botocore.exceptions.ClientError,
34
+ ) -> bool:
35
+ """Return True when the Identity Center instance does not support permission sets."""
36
+ error_info = error.response.get("Error", {})
37
+ if error_info.get("Code") != "ValidationException":
38
+ return False
39
+
40
+ message = error_info.get("Message", "").lower()
41
+ return "not supported for this identity center instance" in message
42
+
43
+
44
+ @timeit
45
+ @aws_handle_regions
46
+ def get_identity_center_instances(
47
+ boto3_session: boto3.session.Session,
48
+ region: str,
49
+ ) -> list[dict[str, Any]]:
50
+ """
51
+ Get all AWS IAM Identity Center instances in the current region
52
+ """
53
+ client = boto3_session.client("sso-admin", region_name=region)
54
+ instances = []
55
+
56
+ paginator = client.get_paginator("list_instances")
57
+ for page in paginator.paginate():
58
+ instances.extend(page.get("Instances", []))
59
+
60
+ return instances
61
+
62
+
63
+ @timeit
64
+ def load_identity_center_instances(
65
+ neo4j_session: neo4j.Session,
66
+ instance_data: list[dict[str, Any]],
67
+ region: str,
68
+ current_aws_account_id: str,
69
+ aws_update_tag: int,
70
+ ) -> None:
71
+ """
72
+ Load Identity Center instances into the graph
73
+ """
74
+ logger.info(
75
+ f"Loading {len(instance_data)} Identity Center instances for region {region}",
76
+ )
77
+ load(
78
+ neo4j_session,
79
+ AWSIdentityCenterInstanceSchema(),
80
+ instance_data,
81
+ lastupdated=aws_update_tag,
82
+ Region=region,
83
+ AWS_ID=current_aws_account_id,
84
+ )
85
+
86
+
87
+ @timeit
88
+ @aws_handle_regions
89
+ def get_permission_sets(
90
+ boto3_session: boto3.session.Session,
91
+ instance_arn: str,
92
+ region: str,
93
+ ) -> list[dict[str, Any]]:
94
+ """
95
+ Get all permission sets for a given Identity Center instance
96
+ """
97
+ client = boto3_session.client("sso-admin", region_name=region)
98
+ permission_sets = []
99
+
100
+ paginator = client.get_paginator("list_permission_sets")
101
+ for page in paginator.paginate(InstanceArn=instance_arn):
102
+ # Get detailed info for each permission set
103
+ for arn in page.get("PermissionSets", []):
104
+ details = client.describe_permission_set(
105
+ InstanceArn=instance_arn,
106
+ PermissionSetArn=arn,
107
+ )
108
+ permission_set = details.get("PermissionSet", {})
109
+ if permission_set:
110
+ permission_sets.append(permission_set)
111
+
112
+ return permission_sets
113
+
114
+
115
+ def transform_permission_sets(
116
+ permission_sets: list[dict[str, Any]],
117
+ region: str,
118
+ ) -> list[dict[str, Any]]:
119
+ """
120
+ Transform permission sets by adding the RoleHint based on region.
121
+
122
+ AWS SSO roles in us-east-1 don't include region in the ARN path,
123
+ but roles in other regions do: /aws-reserved/sso.amazonaws.com/{region}/AWSReservedSSO_*
124
+ """
125
+ for permission_set in permission_sets:
126
+ if region == "us-east-1":
127
+ permission_set["RoleHint"] = (
128
+ f":role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_{permission_set.get('Name')}"
129
+ )
130
+ else:
131
+ permission_set["RoleHint"] = (
132
+ f":role/aws-reserved/sso.amazonaws.com/{region}/AWSReservedSSO_{permission_set.get('Name')}"
133
+ )
134
+ return permission_sets
135
+
136
+
137
+ @timeit
138
+ def load_permission_sets(
139
+ neo4j_session: neo4j.Session,
140
+ permission_sets: list[dict[str, Any]],
141
+ instance_arn: str,
142
+ region: str,
143
+ aws_account_id: str,
144
+ aws_update_tag: int,
145
+ ) -> None:
146
+ """
147
+ Load Identity Center permission sets into the graph
148
+ """
149
+ logger.info(
150
+ f"Loading {len(permission_sets)} permission sets for instance {instance_arn} in region {region}",
151
+ )
152
+
153
+ load(
154
+ neo4j_session,
155
+ AWSPermissionSetSchema(),
156
+ permission_sets,
157
+ lastupdated=aws_update_tag,
158
+ InstanceArn=instance_arn,
159
+ Region=region,
160
+ AWS_ID=aws_account_id,
161
+ _sub_resource_label="AWSAccount",
162
+ _sub_resource_id=aws_account_id,
163
+ )
164
+
165
+
166
+ @timeit
167
+ @aws_handle_regions
168
+ def get_sso_users(
169
+ boto3_session: boto3.session.Session,
170
+ identity_store_id: str,
171
+ region: str,
172
+ ) -> list[dict[str, Any]]:
173
+ """
174
+ Get all SSO users for a given Identity Store
175
+ """
176
+ client = boto3_session.client("identitystore", region_name=region)
177
+ users = []
178
+
179
+ paginator = client.get_paginator("list_users")
180
+ for page in paginator.paginate(IdentityStoreId=identity_store_id):
181
+ user_page = page.get("Users", [])
182
+ for user in user_page:
183
+ users.append(user)
184
+
185
+ return users
186
+
187
+
188
+ @timeit
189
+ @aws_handle_regions
190
+ def get_sso_groups(
191
+ boto3_session: boto3.session.Session,
192
+ identity_store_id: str,
193
+ region: str,
194
+ ) -> list[dict[str, Any]]:
195
+ """
196
+ Get all SSO groups for a given Identity Store
197
+ """
198
+ client = boto3_session.client("identitystore", region_name=region)
199
+ groups: list[dict[str, Any]] = []
200
+
201
+ paginator = client.get_paginator("list_groups")
202
+ for page in paginator.paginate(IdentityStoreId=identity_store_id):
203
+ group_page = page.get("Groups", [])
204
+ for group in group_page:
205
+ groups.append(group)
206
+
207
+ return groups
208
+
209
+
210
+ def transform_sso_users(
211
+ users: list[dict[str, Any]],
212
+ user_group_memberships: dict[str, list[str]] | None = None,
213
+ user_permissionsets: list[dict[str, Any]] | None = None,
214
+ ) -> list[dict[str, Any]]:
215
+ """
216
+ Transform SSO users to match the expected schema, optionally including group memberships
217
+ and permission set assignments.
218
+
219
+ Args:
220
+ users: List of SSO users from AWS API
221
+ user_group_memberships: Optional mapping of UserId -> [GroupIds]
222
+ user_permissionsets: Optional list of permission set assignments with shape:
223
+ [{UserId: str, PermissionSetArn: str, AccountId: str}, ...]
224
+
225
+ Returns:
226
+ Transformed users with MemberOfGroups and AssignedPermissionSets fields added
227
+ """
228
+ # Build mapping from UserId to list of PermissionSetArns
229
+ user_permission_sets: dict[str, list[str]] = {}
230
+ if user_permissionsets:
231
+ for assignment in user_permissionsets:
232
+ user_id = assignment["UserId"]
233
+ perm_set = assignment["PermissionSetArn"]
234
+ user_permission_sets.setdefault(user_id, []).append(perm_set)
235
+
236
+ # Transform users
237
+ transformed_users = []
238
+ for user in users:
239
+ if user.get("ExternalIds"):
240
+ user["ExternalId"] = user["ExternalIds"][0].get("Id")
241
+ # Add group memberships if provided
242
+ if user_group_memberships:
243
+ user["MemberOfGroups"] = user_group_memberships.get(user["UserId"], [])
244
+ # Add direct permission set assignments if available
245
+ if user_permission_sets:
246
+ user["AssignedPermissionSets"] = user_permission_sets.get(
247
+ user["UserId"], []
248
+ )
249
+ transformed_users.append(user)
250
+ return transformed_users
251
+
252
+
253
+ def transform_sso_groups(
254
+ groups: list[dict[str, Any]],
255
+ group_role_assignments: list[dict[str, Any]] | None = None,
256
+ ) -> list[dict[str, Any]]:
257
+ """
258
+ Transform SSO groups to match the expected schema, optionally including permission set assignments.
259
+
260
+ Args:
261
+ groups: List of SSO groups from AWS API
262
+ group_role_assignments: Optional list of role assignments with shape:
263
+ [{GroupId: str, PermissionSetArn: str, AccountId: str}, ...]
264
+
265
+ Returns:
266
+ Transformed groups with AssignedPermissionSets field added
267
+ """
268
+ # Build mapping from GroupId to list of PermissionSetArns
269
+ group_permission_sets: dict[str, list[str]] = {}
270
+ if group_role_assignments:
271
+ for assignment in group_role_assignments:
272
+ group_id = assignment["GroupId"]
273
+ perm_set = assignment["PermissionSetArn"]
274
+ group_permission_sets.setdefault(group_id, []).append(perm_set)
275
+
276
+ # Transform groups
277
+ transformed_groups: list[dict[str, Any]] = []
278
+ for group in groups:
279
+ if group.get("ExternalIds"):
280
+ group["ExternalId"] = group["ExternalIds"][0].get("Id")
281
+ # Add permission set assignments if available
282
+ if group_permission_sets:
283
+ group["AssignedPermissionSets"] = group_permission_sets.get(
284
+ group["GroupId"], []
285
+ )
286
+ transformed_groups.append(group)
287
+ return transformed_groups
288
+
289
+
290
+ @timeit
291
+ def load_sso_users(
292
+ neo4j_session: neo4j.Session,
293
+ users: list[dict[str, Any]],
294
+ identity_store_id: str,
295
+ region: str,
296
+ aws_account_id: str,
297
+ aws_update_tag: int,
298
+ ) -> None:
299
+ """
300
+ Load SSO users into the graph
301
+ """
302
+ logger.info(
303
+ f"Loading {len(users)} SSO users for identity store {identity_store_id} in region {region}",
304
+ )
305
+
306
+ load(
307
+ neo4j_session,
308
+ AWSSSOUserSchema(),
309
+ users,
310
+ lastupdated=aws_update_tag,
311
+ IdentityStoreId=identity_store_id,
312
+ AWS_ID=aws_account_id,
313
+ Region=region,
314
+ )
315
+
316
+
317
+ @timeit
318
+ def load_sso_groups(
319
+ neo4j_session: neo4j.Session,
320
+ groups: list[dict[str, Any]],
321
+ identity_store_id: str,
322
+ region: str,
323
+ aws_account_id: str,
324
+ aws_update_tag: int,
325
+ ) -> None:
326
+ """
327
+ Load SSO groups into the graph
328
+ """
329
+ logger.info(
330
+ f"Loading {len(groups)} SSO groups for identity store {identity_store_id} in region {region}",
331
+ )
332
+
333
+ load(
334
+ neo4j_session,
335
+ AWSSSOGroupSchema(),
336
+ groups,
337
+ lastupdated=aws_update_tag,
338
+ IdentityStoreId=identity_store_id,
339
+ AWS_ID=aws_account_id,
340
+ Region=region,
341
+ )
342
+
343
+
344
+ @timeit
345
+ @aws_handle_regions
346
+ def get_user_permissionsets(
347
+ boto3_session: boto3.session.Session,
348
+ users: list[dict[str, Any]],
349
+ instance_arn: str,
350
+ region: str,
351
+ ) -> list[dict[str, Any]]:
352
+ """
353
+ Get permissionsets for SSO users, taking into account which accounts the user is assigned to.
354
+ Although a permissionset can be assigned to multiple accounts, it is possible for the user
355
+ to be assigned to just a subset of those!
356
+ """
357
+ logger.info(f"Getting permissionsets for {len(users)} users")
358
+ client = boto3_session.client("sso-admin", region_name=region)
359
+ user_permissionsets = []
360
+
361
+ for user in users:
362
+ user_id = user["UserId"]
363
+ paginator = client.get_paginator("list_account_assignments_for_principal")
364
+ for page in paginator.paginate(
365
+ InstanceArn=instance_arn,
366
+ PrincipalId=user_id,
367
+ PrincipalType="USER",
368
+ ):
369
+ for assignment in page.get("AccountAssignments", []):
370
+ user_permissionsets.append(
371
+ {
372
+ "UserId": user_id,
373
+ "PermissionSetArn": assignment.get("PermissionSetArn"),
374
+ "AccountId": assignment.get("AccountId"),
375
+ },
376
+ )
377
+
378
+ return user_permissionsets
379
+
380
+
381
+ @timeit
382
+ @aws_handle_regions
383
+ def get_group_permissionsets(
384
+ boto3_session: boto3.session.Session,
385
+ groups: list[dict[str, Any]],
386
+ instance_arn: str,
387
+ region: str,
388
+ ) -> list[dict[str, Any]]:
389
+ """
390
+ Get permissionsets for SSO groups, taking into account which accounts the group is assigned to.
391
+ """
392
+ logger.info(f"Getting permissionsets for {len(groups)} groups")
393
+ client = boto3_session.client("sso-admin", region_name=region)
394
+ group_permissionsets: list[dict[str, Any]] = []
395
+
396
+ for group in groups:
397
+ group_id = group["GroupId"]
398
+ paginator = client.get_paginator("list_account_assignments_for_principal")
399
+ for page in paginator.paginate(
400
+ InstanceArn=instance_arn,
401
+ PrincipalId=group_id,
402
+ PrincipalType="GROUP",
403
+ ):
404
+ for assignment in page.get("AccountAssignments", []):
405
+ group_permissionsets.append(
406
+ {
407
+ "GroupId": group_id,
408
+ "PermissionSetArn": assignment.get("PermissionSetArn"),
409
+ "AccountId": assignment.get("AccountId"),
410
+ }
411
+ )
412
+
413
+ return group_permissionsets
414
+
415
+
416
+ @timeit
417
+ @aws_handle_regions
418
+ def get_user_group_memberships(
419
+ boto3_session: boto3.session.Session,
420
+ identity_store_id: str,
421
+ groups: list[dict[str, Any]],
422
+ region: str,
423
+ ) -> dict[str, list[str]]:
424
+ """
425
+ Return a mapping of UserId -> [GroupIds] for all group memberships in the identity store.
426
+ """
427
+ client = boto3_session.client("identitystore", region_name=region)
428
+ user_groups: dict[str, list[str]] = {}
429
+
430
+ for group in groups:
431
+ group_id = group["GroupId"]
432
+ paginator = client.get_paginator("list_group_memberships")
433
+ for page in paginator.paginate(
434
+ IdentityStoreId=identity_store_id, GroupId=group_id
435
+ ):
436
+ for membership in page.get("GroupMemberships", []):
437
+ member = membership.get("MemberId", {})
438
+ user_id = member.get("UserId")
439
+ if user_id:
440
+ user_groups.setdefault(user_id, []).append(group_id)
441
+
442
+ return user_groups
443
+
444
+
445
+ @timeit
446
+ def _get_permset_roles(
447
+ neo4j_session: neo4j.Session,
448
+ permset_ids: list[str],
449
+ ) -> dict[tuple[str, str], str]:
450
+ """
451
+ Given a list of permission set ARNs, return a mapping of (permission set ARN, account ID) to role ARN
452
+ based on the ASSIGNED_TO_ROLE relationship in the graph.
453
+ """
454
+ query = """
455
+ MATCH (role:AWSRole)<-[:ASSIGNED_TO_ROLE]-(permset:AWSPermissionSet)
456
+ MATCH (account:AWSAccount)-[:RESOURCE]->(role)
457
+ WHERE permset.arn IN $PermSetIds
458
+ RETURN permset.arn AS PermissionSetArn, role.arn AS RoleArn, account.id AS AccountId
459
+ """
460
+ permset_to_role = neo4j_session.execute_read(
461
+ read_list_of_dicts_tx,
462
+ query,
463
+ PermSetIds=permset_ids,
464
+ )
465
+ return {
466
+ (entry["PermissionSetArn"], entry["AccountId"]): entry["RoleArn"]
467
+ for entry in permset_to_role
468
+ }
469
+
470
+
471
+ @timeit
472
+ def get_principal_roles(
473
+ neo4j_session: neo4j.Session,
474
+ principal_assignments: list[dict[str, Any]],
475
+ ) -> list[dict[str, Any]]:
476
+ """
477
+ At this point we've established that the principal has access to a given account
478
+ via a given permission set, and now we need to find the exact role in the account
479
+ it has access to.
480
+ :param neo4j_session: neo4j.Session
481
+ :param principal_assignments: either a list of {
482
+ "UserId": str
483
+ "AccountId": str,
484
+ "PermissionSetArn": str,
485
+ }, or a list of {
486
+ "GroupId": str,
487
+ "AccountId": str,
488
+ "PermissionSetArn": str,
489
+ }
490
+ :return: either a list of {
491
+ "UserId": str,
492
+ "AccountId": str,
493
+ "PermissionSetArn": str,
494
+ "RoleArn": str
495
+ } or,
496
+ a list of {
497
+ "GroupId": str,
498
+ "AccountId": str,
499
+ "PermissionSetArn": str,
500
+ "RoleArn": str
501
+ }
502
+ """
503
+ # Get unique permission set ARNs from role assignments
504
+ permset_ids = list({pa["PermissionSetArn"] for pa in principal_assignments})
505
+ permset_to_role = _get_permset_roles(neo4j_session, permset_ids)
506
+
507
+ unmatched = 0
508
+ # Use the lookup table to enrich assignments with exact role ARNs
509
+ principal_roles = []
510
+ for assignment in principal_assignments:
511
+ lookup_key = (assignment["PermissionSetArn"], assignment["AccountId"])
512
+ role_arn = permset_to_role.get(lookup_key)
513
+ if not role_arn:
514
+ unmatched += 1
515
+ principal_roles.append(
516
+ {
517
+ **assignment,
518
+ "RoleArn": role_arn,
519
+ }
520
+ )
521
+ if unmatched > 0:
522
+ logger.info(
523
+ f"Identity Center: {unmatched} of {len(principal_assignments)} principal assignments "
524
+ "did not match a role. This usually means IAM roles for some permission sets/accounts "
525
+ "have not been ingested yet. Re-run the IAM sync, and then the Identity Center sync to fix."
526
+ )
527
+ return principal_roles
528
+
529
+
530
+ @timeit
531
+ def load_user_roles(
532
+ neo4j_session: neo4j.Session,
533
+ user_roles: list[dict[str, Any]],
534
+ aws_account_id: str,
535
+ aws_update_tag: int,
536
+ ) -> None:
537
+ logger.info(f"Loading {len(user_roles)} user roles")
538
+ load_matchlinks(
539
+ neo4j_session,
540
+ AWSRoleToSSOUserMatchLink(),
541
+ user_roles,
542
+ lastupdated=aws_update_tag,
543
+ _sub_resource_label="AWSAccount",
544
+ _sub_resource_id=aws_account_id,
545
+ )
546
+
547
+
548
+ @timeit
549
+ def load_group_roles(
550
+ neo4j_session: neo4j.Session,
551
+ group_roles: list[dict[str, Any]],
552
+ aws_account_id: str,
553
+ aws_update_tag: int,
554
+ ) -> None:
555
+ logger.info(f"Loading {len(group_roles)} group roles")
556
+ load_matchlinks(
557
+ neo4j_session,
558
+ AWSRoleToSSOGroupMatchLink(),
559
+ group_roles,
560
+ lastupdated=aws_update_tag,
561
+ _sub_resource_label="AWSAccount",
562
+ _sub_resource_id=aws_account_id,
563
+ )
564
+
565
+
566
+ @timeit
567
+ def cleanup(
568
+ neo4j_session: neo4j.Session,
569
+ common_job_parameters: dict[str, Any],
570
+ ) -> None:
571
+ GraphJob.from_node_schema(
572
+ AWSIdentityCenterInstanceSchema(),
573
+ common_job_parameters,
574
+ ).run(neo4j_session)
575
+ GraphJob.from_node_schema(AWSPermissionSetSchema(), common_job_parameters).run(
576
+ neo4j_session,
577
+ )
578
+ GraphJob.from_node_schema(AWSSSOUserSchema(), common_job_parameters).run(
579
+ neo4j_session,
580
+ )
581
+ GraphJob.from_node_schema(AWSSSOGroupSchema(), common_job_parameters).run(
582
+ neo4j_session,
583
+ )
584
+
585
+ # Clean up role assignment MatchLinks
586
+ GraphJob.from_matchlink(
587
+ AWSRoleToSSOUserMatchLink(),
588
+ "AWSAccount",
589
+ common_job_parameters["AWS_ID"],
590
+ common_job_parameters["UPDATE_TAG"],
591
+ ).run(neo4j_session)
592
+ GraphJob.from_matchlink(
593
+ AWSRoleToSSOGroupMatchLink(),
594
+ "AWSAccount",
595
+ common_job_parameters["AWS_ID"],
596
+ common_job_parameters["UPDATE_TAG"],
597
+ ).run(neo4j_session)
598
+
599
+
600
+ def _sync_permission_sets(
601
+ neo4j_session: neo4j.Session,
602
+ boto3_session: boto3.session.Session,
603
+ instance_arn: str,
604
+ region: str,
605
+ current_aws_account_id: str,
606
+ update_tag: int,
607
+ ) -> bool:
608
+ """
609
+ Sync permission sets for an Identity Center instance.
610
+
611
+ Returns:
612
+ True if permission set sync is supported, False for account-scoped instances
613
+ that don't support permission sets.
614
+ """
615
+ try:
616
+ permission_sets = get_permission_sets(boto3_session, instance_arn, region)
617
+ # Transform permission sets to add RoleHint for fuzzy matching to IAM roles
618
+ permission_sets = transform_permission_sets(permission_sets, region)
619
+ load_permission_sets(
620
+ neo4j_session,
621
+ permission_sets,
622
+ instance_arn,
623
+ region,
624
+ current_aws_account_id,
625
+ update_tag,
626
+ )
627
+ return True
628
+ except botocore.exceptions.ClientError as error:
629
+ if _is_permission_set_sync_unsupported_error(error):
630
+ logger.warning(
631
+ "Skipping permission set sync for Identity Center instance %s in region %s "
632
+ "because the instance does not support permission sets. "
633
+ "Will attempt to sync users and groups only.",
634
+ instance_arn,
635
+ region,
636
+ )
637
+ return False
638
+ raise
639
+
640
+
641
+ def _sync_groups_and_users(
642
+ neo4j_session: neo4j.Session,
643
+ boto3_session: boto3.session.Session,
644
+ instance_arn: str,
645
+ identity_store_id: str,
646
+ region: str,
647
+ permission_set_sync_supported: bool,
648
+ current_aws_account_id: str,
649
+ update_tag: int,
650
+ ) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
651
+ """
652
+ Sync groups and users for an Identity Center instance.
653
+
654
+ Groups are synced first so that user->group membership edges can be created.
655
+ Permission set assignments are fetched (if supported) and used to enrich
656
+ the user/group nodes with HAS_PERMISSION_SET relationships, then returned
657
+ for later role assignment creation.
658
+
659
+ Args:
660
+ permission_set_sync_supported: If True, fetches and enriches permission set assignments
661
+
662
+ Returns:
663
+ (user_permission_set_assignments, group_permission_set_assignments)
664
+ These are the raw assignment data needed for creating ALLOWED_BY relationships.
665
+ Will be empty lists if permission_set_sync_supported is False.
666
+ """
667
+ # Fetch groups first to avoid interleaving between groups and users
668
+ groups = get_sso_groups(boto3_session, identity_store_id, region)
669
+
670
+ # Get permission set assignments for groups (if permission sets are supported)
671
+ group_permissionsets_raw: list[dict[str, Any]] = []
672
+ if permission_set_sync_supported:
673
+ group_permissionsets_raw = get_group_permissionsets(
674
+ boto3_session,
675
+ groups,
676
+ instance_arn,
677
+ region,
678
+ )
679
+
680
+ # Transform and load groups with their permission set assignments FIRST
681
+ # so that user->group membership edges can attach in the same run.
682
+ transformed_groups = transform_sso_groups(groups, group_permissionsets_raw)
683
+ load_sso_groups(
684
+ neo4j_session,
685
+ transformed_groups,
686
+ identity_store_id,
687
+ region,
688
+ current_aws_account_id,
689
+ update_tag,
690
+ )
691
+
692
+ # Handle users AFTER groups exist
693
+ users = get_sso_users(boto3_session, identity_store_id, region)
694
+ user_group_memberships = get_user_group_memberships(
695
+ boto3_session,
696
+ identity_store_id,
697
+ groups,
698
+ region,
699
+ )
700
+
701
+ # Get direct permission set assignments for users (if permission sets are supported)
702
+ user_permissionsets_raw: list[dict[str, Any]] = []
703
+ if permission_set_sync_supported:
704
+ user_permissionsets_raw = get_user_permissionsets(
705
+ boto3_session,
706
+ users,
707
+ instance_arn,
708
+ region,
709
+ )
710
+
711
+ # Transform and load users with their group memberships AFTER groups exist
712
+ transformed_users = transform_sso_users(
713
+ users,
714
+ user_group_memberships,
715
+ user_permissionsets_raw,
716
+ )
717
+ load_sso_users(
718
+ neo4j_session,
719
+ transformed_users,
720
+ identity_store_id,
721
+ region,
722
+ current_aws_account_id,
723
+ update_tag,
724
+ )
725
+
726
+ # Return the raw assignment data for role assignment creation
727
+ return user_permissionsets_raw, group_permissionsets_raw
728
+
729
+
730
+ def _sync_role_assignments(
731
+ neo4j_session: neo4j.Session,
732
+ user_permissionsets_raw: list[dict[str, Any]],
733
+ group_permissionsets_raw: list[dict[str, Any]],
734
+ current_aws_account_id: str,
735
+ update_tag: int,
736
+ ) -> None:
737
+ """
738
+ Create ALLOWED_BY relationships between IAM roles and SSO principals.
739
+
740
+ This enriches the raw permission set assignment data with exact role ARNs
741
+ from the graph (using the composite key lookup), then creates the MatchLink
742
+ relationships.
743
+
744
+ Note: This must be called AFTER groups and users are loaded so that the
745
+ MatchLinks can find the existing AWSSSOUser/AWSSSOGroup nodes when creating
746
+ the ALLOWED_BY edges.
747
+ """
748
+ user_roles = get_principal_roles(neo4j_session, user_permissionsets_raw)
749
+ load_user_roles(neo4j_session, user_roles, current_aws_account_id, update_tag)
750
+
751
+ group_roles = get_principal_roles(neo4j_session, group_permissionsets_raw)
752
+ load_group_roles(neo4j_session, group_roles, current_aws_account_id, update_tag)
753
+
754
+
755
+ def _sync_instance(
756
+ neo4j_session: neo4j.Session,
757
+ boto3_session: boto3.session.Session,
758
+ instance: dict[str, Any],
759
+ region: str,
760
+ current_aws_account_id: str,
761
+ update_tag: int,
762
+ ) -> None:
763
+ """
764
+ Sync a single Identity Center instance.
765
+
766
+ This syncs permission sets (if supported), groups, users, and role assignments
767
+ in the correct order to ensure all relationships can be created.
768
+ """
769
+ instance_arn = instance["InstanceArn"]
770
+ identity_store_id = instance["IdentityStoreId"]
771
+
772
+ # Sync permission sets (may not be supported for account-scoped instances)
773
+ permission_set_sync_supported = _sync_permission_sets(
774
+ neo4j_session,
775
+ boto3_session,
776
+ instance_arn,
777
+ region,
778
+ current_aws_account_id,
779
+ update_tag,
780
+ )
781
+
782
+ # Sync groups and users (always happens, but enriched with permission sets if available)
783
+ user_assignments, group_assignments = _sync_groups_and_users(
784
+ neo4j_session,
785
+ boto3_session,
786
+ instance_arn,
787
+ identity_store_id,
788
+ region,
789
+ permission_set_sync_supported,
790
+ current_aws_account_id,
791
+ update_tag,
792
+ )
793
+
794
+ # Create role assignment relationships (only if permission sets are supported)
795
+ if permission_set_sync_supported:
796
+ _sync_role_assignments(
797
+ neo4j_session,
798
+ user_assignments,
799
+ group_assignments,
800
+ current_aws_account_id,
801
+ update_tag,
802
+ )
803
+
804
+
805
+ @timeit
806
+ def sync_identity_center_instances(
807
+ neo4j_session: neo4j.Session,
808
+ boto3_session: boto3.session.Session,
809
+ regions: list[str],
810
+ current_aws_account_id: str,
811
+ update_tag: int,
812
+ common_job_parameters: dict[str, Any],
813
+ ) -> None:
814
+ """
815
+ Sync Identity Center instances across all specified regions.
816
+
817
+ For each instance, syncs:
818
+ 1. Permission sets (if supported by the instance type)
819
+ 2. Groups and users (with permission set assignments if available)
820
+ 3. Role assignment relationships (ALLOWED_BY edges from roles to principals)
821
+
822
+ Account-scoped Identity Center instances don't support permission sets and will
823
+ skip step 1 and 3, but still sync users and groups.
824
+ """
825
+ logger.info(f"Syncing Identity Center instances for regions {regions}")
826
+ for region in regions:
827
+ logger.info(f"Syncing Identity Center instances for region {region}")
828
+ instances = get_identity_center_instances(boto3_session, region)
829
+ load_identity_center_instances(
830
+ neo4j_session,
831
+ instances,
832
+ region,
833
+ current_aws_account_id,
834
+ update_tag,
835
+ )
836
+
837
+ for instance in instances:
838
+ _sync_instance(
839
+ neo4j_session,
840
+ boto3_session,
841
+ instance,
842
+ region,
843
+ current_aws_account_id,
844
+ update_tag,
845
+ )
846
+
847
+ cleanup(neo4j_session, common_job_parameters)