cartography 0.104.0rc2__py3-none-any.whl → 0.123.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (642) hide show
  1. cartography/_version.py +16 -3
  2. cartography/cli.py +466 -5
  3. cartography/client/aws/__init__.py +19 -0
  4. cartography/client/aws/ecr.py +51 -0
  5. cartography/client/core/tx.py +357 -8
  6. cartography/config.py +153 -0
  7. cartography/data/azure_permission_relationships.yaml +20 -0
  8. cartography/data/gcp_permission_relationships.yaml +21 -0
  9. cartography/data/indexes.cypher +0 -186
  10. cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +2 -2
  11. cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
  12. cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -12
  13. cartography/data/jobs/cleanup/github_repos_cleanup.json +2 -0
  14. cartography/driftdetect/cli.py +3 -2
  15. cartography/graph/cleanupbuilder.py +198 -41
  16. cartography/graph/job.py +54 -6
  17. cartography/graph/querybuilder.py +528 -27
  18. cartography/graph/statement.py +5 -1
  19. cartography/intel/airbyte/__init__.py +105 -0
  20. cartography/intel/airbyte/connections.py +120 -0
  21. cartography/intel/airbyte/destinations.py +81 -0
  22. cartography/intel/airbyte/organizations.py +59 -0
  23. cartography/intel/airbyte/sources.py +78 -0
  24. cartography/intel/airbyte/tags.py +64 -0
  25. cartography/intel/airbyte/users.py +106 -0
  26. cartography/intel/airbyte/util.py +122 -0
  27. cartography/intel/airbyte/workspaces.py +63 -0
  28. cartography/intel/aws/__init__.py +24 -9
  29. cartography/intel/aws/acm.py +124 -0
  30. cartography/intel/aws/apigateway.py +253 -22
  31. cartography/intel/aws/apigatewayv2.py +116 -0
  32. cartography/intel/aws/cloudtrail.py +17 -39
  33. cartography/intel/aws/cloudtrail_management_events.py +962 -0
  34. cartography/intel/aws/cloudwatch.py +150 -4
  35. cartography/intel/aws/codebuild.py +132 -0
  36. cartography/intel/aws/cognito.py +201 -0
  37. cartography/intel/aws/config.py +7 -3
  38. cartography/intel/aws/ec2/elastic_ip_addresses.py +3 -1
  39. cartography/intel/aws/ec2/instances.py +25 -1
  40. cartography/intel/aws/ec2/internet_gateways.py +4 -2
  41. cartography/intel/aws/ec2/load_balancer_v2s.py +11 -5
  42. cartography/intel/aws/ec2/network_interfaces.py +5 -1
  43. cartography/intel/aws/ec2/reserved_instances.py +3 -1
  44. cartography/intel/aws/ec2/security_groups.py +140 -122
  45. cartography/intel/aws/ec2/snapshots.py +47 -84
  46. cartography/intel/aws/ec2/subnets.py +37 -63
  47. cartography/intel/aws/ec2/tgw.py +11 -5
  48. cartography/intel/aws/ec2/volumes.py +1 -1
  49. cartography/intel/aws/ec2/vpc.py +140 -124
  50. cartography/intel/aws/ec2/vpc_peerings.py +262 -125
  51. cartography/intel/aws/ecr.py +269 -98
  52. cartography/intel/aws/ecr_image_layers.py +923 -0
  53. cartography/intel/aws/ecs.py +251 -380
  54. cartography/intel/aws/efs.py +179 -11
  55. cartography/intel/aws/elasticache.py +102 -79
  56. cartography/intel/aws/elasticsearch.py +13 -4
  57. cartography/intel/aws/eventbridge.py +164 -0
  58. cartography/intel/aws/glue.py +181 -0
  59. cartography/intel/aws/guardduty.py +443 -0
  60. cartography/intel/aws/iam.py +750 -493
  61. cartography/intel/aws/identitycenter.py +605 -83
  62. cartography/intel/aws/inspector.py +221 -105
  63. cartography/intel/aws/kms.py +173 -201
  64. cartography/intel/aws/lambda_function.py +272 -189
  65. cartography/intel/aws/organizations.py +10 -9
  66. cartography/intel/aws/permission_relationships.py +10 -20
  67. cartography/intel/aws/rds.py +337 -446
  68. cartography/intel/aws/redshift.py +9 -4
  69. cartography/intel/aws/resourcegroupstaggingapi.py +78 -19
  70. cartography/intel/aws/resources.py +18 -0
  71. cartography/intel/aws/route53.py +386 -332
  72. cartography/intel/aws/s3.py +322 -14
  73. cartography/intel/aws/secretsmanager.py +81 -49
  74. cartography/intel/aws/securityhub.py +3 -1
  75. cartography/intel/aws/sns.py +62 -2
  76. cartography/intel/aws/sqs.py +36 -90
  77. cartography/intel/aws/ssm.py +3 -5
  78. cartography/intel/azure/__init__.py +202 -48
  79. cartography/intel/azure/aks.py +175 -0
  80. cartography/intel/azure/app_service.py +105 -0
  81. cartography/intel/azure/compute.py +59 -112
  82. cartography/intel/azure/container_instances.py +95 -0
  83. cartography/intel/azure/cosmosdb.py +222 -361
  84. cartography/intel/azure/data_factory.py +85 -0
  85. cartography/intel/azure/data_factory_dataset.py +128 -0
  86. cartography/intel/azure/data_factory_linked_service.py +119 -0
  87. cartography/intel/azure/data_factory_pipeline.py +142 -0
  88. cartography/intel/azure/data_lake.py +124 -0
  89. cartography/intel/azure/event_grid.py +94 -0
  90. cartography/intel/azure/functions.py +124 -0
  91. cartography/intel/azure/load_balancers.py +263 -0
  92. cartography/intel/azure/logic_apps.py +101 -0
  93. cartography/intel/azure/monitor.py +105 -0
  94. cartography/intel/azure/network.py +467 -0
  95. cartography/intel/azure/permission_relationships.py +466 -0
  96. cartography/intel/azure/rbac.py +309 -0
  97. cartography/intel/azure/resource_groups.py +82 -0
  98. cartography/intel/azure/security_center.py +106 -0
  99. cartography/intel/azure/sql.py +145 -292
  100. cartography/intel/azure/storage.py +185 -262
  101. cartography/intel/azure/subscription.py +21 -43
  102. cartography/intel/azure/tenant.py +39 -30
  103. cartography/intel/azure/util/common.py +13 -0
  104. cartography/intel/azure/util/credentials.py +49 -174
  105. cartography/intel/azure/util/tag.py +41 -0
  106. cartography/intel/create_indexes.py +2 -1
  107. cartography/intel/crowdstrike/spotlight.py +5 -2
  108. cartography/intel/dns.py +5 -2
  109. cartography/intel/entra/__init__.py +100 -1
  110. cartography/intel/entra/app_role_assignments.py +284 -0
  111. cartography/intel/entra/applications.py +182 -0
  112. cartography/intel/entra/federation/__init__.py +0 -0
  113. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  114. cartography/intel/entra/groups.py +198 -0
  115. cartography/intel/entra/ou.py +48 -24
  116. cartography/intel/entra/service_principals.py +217 -0
  117. cartography/intel/entra/users.py +105 -57
  118. cartography/intel/gcp/__init__.py +334 -396
  119. cartography/intel/gcp/bigtable_app_profile.py +101 -0
  120. cartography/intel/gcp/bigtable_backup.py +91 -0
  121. cartography/intel/gcp/bigtable_cluster.py +93 -0
  122. cartography/intel/gcp/bigtable_instance.py +86 -0
  123. cartography/intel/gcp/bigtable_table.py +87 -0
  124. cartography/intel/gcp/cai.py +292 -0
  125. cartography/intel/gcp/clients.py +112 -0
  126. cartography/intel/gcp/compute.py +128 -119
  127. cartography/intel/gcp/crm/__init__.py +0 -0
  128. cartography/intel/gcp/crm/folders.py +114 -0
  129. cartography/intel/gcp/crm/orgs.py +70 -0
  130. cartography/intel/gcp/crm/projects.py +120 -0
  131. cartography/intel/gcp/dns.py +83 -169
  132. cartography/intel/gcp/gke.py +72 -113
  133. cartography/intel/gcp/iam.py +111 -91
  134. cartography/intel/gcp/permission_relationships.py +394 -0
  135. cartography/intel/gcp/policy_bindings.py +225 -0
  136. cartography/intel/gcp/storage.py +75 -159
  137. cartography/intel/github/__init__.py +62 -25
  138. cartography/intel/github/commits.py +423 -0
  139. cartography/intel/github/repos.py +463 -85
  140. cartography/intel/github/teams.py +3 -3
  141. cartography/intel/github/users.py +5 -0
  142. cartography/intel/github/util.py +12 -0
  143. cartography/intel/googleworkspace/__init__.py +193 -0
  144. cartography/intel/googleworkspace/devices.py +254 -0
  145. cartography/intel/googleworkspace/groups.py +568 -0
  146. cartography/intel/googleworkspace/oauth_apps.py +259 -0
  147. cartography/intel/googleworkspace/tenant.py +85 -0
  148. cartography/intel/googleworkspace/users.py +138 -0
  149. cartography/intel/gsuite/__init__.py +17 -9
  150. cartography/intel/gsuite/groups.py +291 -0
  151. cartography/intel/gsuite/users.py +142 -0
  152. cartography/intel/jamf/computers.py +7 -1
  153. cartography/intel/keycloak/__init__.py +153 -0
  154. cartography/intel/keycloak/authenticationexecutions.py +322 -0
  155. cartography/intel/keycloak/authenticationflows.py +77 -0
  156. cartography/intel/keycloak/clients.py +187 -0
  157. cartography/intel/keycloak/groups.py +126 -0
  158. cartography/intel/keycloak/identityproviders.py +94 -0
  159. cartography/intel/keycloak/organizations.py +163 -0
  160. cartography/intel/keycloak/realms.py +61 -0
  161. cartography/intel/keycloak/roles.py +202 -0
  162. cartography/intel/keycloak/scopes.py +73 -0
  163. cartography/intel/keycloak/users.py +70 -0
  164. cartography/intel/keycloak/util.py +47 -0
  165. cartography/intel/kubernetes/__init__.py +60 -14
  166. cartography/intel/kubernetes/clusters.py +86 -0
  167. cartography/intel/kubernetes/eks.py +402 -0
  168. cartography/intel/kubernetes/namespaces.py +59 -57
  169. cartography/intel/kubernetes/pods.py +168 -75
  170. cartography/intel/kubernetes/rbac.py +597 -0
  171. cartography/intel/kubernetes/secrets.py +95 -45
  172. cartography/intel/kubernetes/services.py +131 -67
  173. cartography/intel/kubernetes/util.py +142 -14
  174. cartography/intel/oci/iam.py +23 -9
  175. cartography/intel/oci/organizations.py +3 -1
  176. cartography/intel/oci/utils.py +28 -5
  177. cartography/intel/okta/applications.py +15 -5
  178. cartography/intel/okta/awssaml.py +14 -10
  179. cartography/intel/okta/factors.py +3 -1
  180. cartography/intel/okta/groups.py +5 -2
  181. cartography/intel/okta/organization.py +3 -1
  182. cartography/intel/okta/origins.py +3 -1
  183. cartography/intel/okta/roles.py +5 -2
  184. cartography/intel/okta/users.py +10 -2
  185. cartography/intel/ontology/__init__.py +44 -0
  186. cartography/intel/ontology/devices.py +54 -0
  187. cartography/intel/ontology/users.py +54 -0
  188. cartography/intel/ontology/utils.py +176 -0
  189. cartography/intel/pagerduty/escalation_policies.py +13 -6
  190. cartography/intel/pagerduty/schedules.py +9 -4
  191. cartography/intel/pagerduty/services.py +7 -3
  192. cartography/intel/pagerduty/teams.py +5 -2
  193. cartography/intel/pagerduty/users.py +3 -1
  194. cartography/intel/pagerduty/vendors.py +3 -1
  195. cartography/intel/scaleway/__init__.py +127 -0
  196. cartography/intel/scaleway/iam/__init__.py +0 -0
  197. cartography/intel/scaleway/iam/apikeys.py +71 -0
  198. cartography/intel/scaleway/iam/applications.py +71 -0
  199. cartography/intel/scaleway/iam/groups.py +71 -0
  200. cartography/intel/scaleway/iam/users.py +71 -0
  201. cartography/intel/scaleway/instances/__init__.py +0 -0
  202. cartography/intel/scaleway/instances/flexibleips.py +86 -0
  203. cartography/intel/scaleway/instances/instances.py +92 -0
  204. cartography/intel/scaleway/projects.py +79 -0
  205. cartography/intel/scaleway/storage/__init__.py +0 -0
  206. cartography/intel/scaleway/storage/snapshots.py +86 -0
  207. cartography/intel/scaleway/storage/volumes.py +84 -0
  208. cartography/intel/scaleway/utils.py +37 -0
  209. cartography/intel/sentinelone/__init__.py +75 -0
  210. cartography/intel/sentinelone/account.py +140 -0
  211. cartography/intel/sentinelone/agent.py +139 -0
  212. cartography/intel/sentinelone/api.py +124 -0
  213. cartography/intel/sentinelone/application.py +248 -0
  214. cartography/intel/sentinelone/cve.py +119 -0
  215. cartography/intel/sentinelone/utils.py +28 -0
  216. cartography/intel/slack/__init__.py +78 -0
  217. cartography/intel/slack/channels.py +80 -0
  218. cartography/intel/slack/groups.py +90 -0
  219. cartography/intel/slack/teams.py +65 -0
  220. cartography/intel/slack/users.py +57 -0
  221. cartography/intel/slack/utils.py +29 -0
  222. cartography/intel/spacelift/__init__.py +161 -0
  223. cartography/intel/spacelift/account.py +73 -0
  224. cartography/intel/spacelift/ec2_ownership.py +280 -0
  225. cartography/intel/spacelift/runs.py +463 -0
  226. cartography/intel/spacelift/spaces.py +112 -0
  227. cartography/intel/spacelift/stacks.py +119 -0
  228. cartography/intel/spacelift/util.py +122 -0
  229. cartography/intel/spacelift/workerpools.py +131 -0
  230. cartography/intel/spacelift/workers.py +128 -0
  231. cartography/intel/trivy/__init__.py +272 -0
  232. cartography/intel/trivy/scanner.py +386 -0
  233. cartography/models/airbyte/__init__.py +0 -0
  234. cartography/models/airbyte/connection.py +138 -0
  235. cartography/models/airbyte/destination.py +75 -0
  236. cartography/models/airbyte/organization.py +19 -0
  237. cartography/models/airbyte/source.py +75 -0
  238. cartography/models/airbyte/stream.py +74 -0
  239. cartography/models/airbyte/tag.py +69 -0
  240. cartography/models/airbyte/user.py +115 -0
  241. cartography/models/airbyte/workspace.py +46 -0
  242. cartography/models/anthropic/apikey.py +4 -0
  243. cartography/models/anthropic/user.py +4 -0
  244. cartography/models/aws/acm/__init__.py +0 -0
  245. cartography/models/aws/acm/certificate.py +75 -0
  246. cartography/models/aws/apigateway/__init__.py +0 -0
  247. cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
  248. cartography/models/aws/apigateway/apigatewayintegration.py +79 -0
  249. cartography/models/aws/apigateway/apigatewaymethod.py +74 -0
  250. cartography/models/aws/apigatewayv2/__init__.py +0 -0
  251. cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
  252. cartography/models/aws/cloudtrail/management_events.py +153 -0
  253. cartography/models/aws/cloudtrail/trail.py +45 -0
  254. cartography/models/aws/cloudwatch/log_metric_filter.py +79 -0
  255. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  256. cartography/models/aws/codebuild/__init__.py +0 -0
  257. cartography/models/aws/codebuild/project.py +49 -0
  258. cartography/models/aws/cognito/__init__.py +0 -0
  259. cartography/models/aws/cognito/identity_pool.py +70 -0
  260. cartography/models/aws/cognito/user_pool.py +47 -0
  261. cartography/models/aws/dynamodb/tables.py +2 -0
  262. cartography/models/aws/ec2/instances.py +25 -1
  263. cartography/models/aws/ec2/networkinterfaces.py +4 -0
  264. cartography/models/aws/ec2/security_group_rules.py +109 -0
  265. cartography/models/aws/ec2/security_groups.py +90 -0
  266. cartography/models/aws/ec2/snapshots.py +58 -0
  267. cartography/models/aws/ec2/subnet_instance.py +2 -0
  268. cartography/models/aws/ec2/subnet_networkinterface.py +2 -0
  269. cartography/models/aws/ec2/subnets.py +65 -0
  270. cartography/models/aws/ec2/volumes.py +20 -0
  271. cartography/models/aws/ec2/vpc.py +46 -0
  272. cartography/models/aws/ec2/vpc_cidr.py +102 -0
  273. cartography/models/aws/ec2/vpc_peering.py +157 -0
  274. cartography/models/aws/ecr/__init__.py +0 -0
  275. cartography/models/aws/ecr/image.py +146 -0
  276. cartography/models/aws/ecr/image_layer.py +107 -0
  277. cartography/models/aws/ecr/repository.py +72 -0
  278. cartography/models/aws/ecr/repository_image.py +95 -0
  279. cartography/models/aws/ecs/__init__.py +0 -0
  280. cartography/models/aws/ecs/clusters.py +64 -0
  281. cartography/models/aws/ecs/container_definitions.py +93 -0
  282. cartography/models/aws/ecs/container_instances.py +84 -0
  283. cartography/models/aws/ecs/containers.py +101 -0
  284. cartography/models/aws/ecs/services.py +134 -0
  285. cartography/models/aws/ecs/task_definitions.py +135 -0
  286. cartography/models/aws/ecs/tasks.py +134 -0
  287. cartography/models/aws/efs/access_point.py +77 -0
  288. cartography/models/aws/efs/file_system.py +60 -0
  289. cartography/models/aws/efs/mount_target.py +29 -2
  290. cartography/models/aws/elasticache/__init__.py +0 -0
  291. cartography/models/aws/elasticache/cluster.py +65 -0
  292. cartography/models/aws/elasticache/topic.py +67 -0
  293. cartography/models/aws/eventbridge/__init__.py +0 -0
  294. cartography/models/aws/eventbridge/rule.py +77 -0
  295. cartography/models/aws/eventbridge/target.py +71 -0
  296. cartography/models/aws/glue/__init__.py +0 -0
  297. cartography/models/aws/glue/connection.py +51 -0
  298. cartography/models/aws/glue/job.py +69 -0
  299. cartography/models/aws/guardduty/__init__.py +1 -0
  300. cartography/models/aws/guardduty/detectors.py +50 -0
  301. cartography/models/aws/guardduty/findings.py +121 -0
  302. cartography/models/aws/iam/access_key.py +103 -0
  303. cartography/models/aws/iam/account_role.py +24 -0
  304. cartography/models/aws/iam/federated_principal.py +60 -0
  305. cartography/models/aws/iam/group.py +60 -0
  306. cartography/models/aws/iam/group_membership.py +27 -0
  307. cartography/models/aws/iam/inline_policy.py +78 -0
  308. cartography/models/aws/iam/managed_policy.py +51 -0
  309. cartography/models/aws/iam/policy_statement.py +57 -0
  310. cartography/models/aws/iam/role.py +83 -0
  311. cartography/models/aws/iam/root_principal.py +52 -0
  312. cartography/models/aws/iam/service_principal.py +30 -0
  313. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  314. cartography/models/aws/iam/user.py +59 -0
  315. cartography/models/aws/identitycenter/awsidentitycenter.py +1 -0
  316. cartography/models/aws/identitycenter/awspermissionset.py +70 -0
  317. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  318. cartography/models/aws/identitycenter/awsssouser.py +49 -9
  319. cartography/models/aws/inspector/findings.py +37 -0
  320. cartography/models/aws/inspector/packages.py +1 -31
  321. cartography/models/aws/kms/__init__.py +0 -0
  322. cartography/models/aws/kms/aliases.py +86 -0
  323. cartography/models/aws/kms/grants.py +65 -0
  324. cartography/models/aws/kms/keys.py +88 -0
  325. cartography/models/aws/lambda_function/__init__.py +0 -0
  326. cartography/models/aws/lambda_function/alias.py +74 -0
  327. cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
  328. cartography/models/aws/lambda_function/lambda_function.py +91 -0
  329. cartography/models/aws/lambda_function/layer.py +72 -0
  330. cartography/models/aws/rds/__init__.py +0 -0
  331. cartography/models/aws/rds/cluster.py +91 -0
  332. cartography/models/aws/rds/event_subscription.py +146 -0
  333. cartography/models/aws/rds/instance.py +156 -0
  334. cartography/models/aws/rds/snapshot.py +108 -0
  335. cartography/models/aws/rds/subnet_group.py +101 -0
  336. cartography/models/aws/route53/__init__.py +0 -0
  337. cartography/models/aws/route53/dnsrecord.py +235 -0
  338. cartography/models/aws/route53/nameserver.py +63 -0
  339. cartography/models/aws/route53/subzone.py +40 -0
  340. cartography/models/aws/route53/zone.py +47 -0
  341. cartography/models/aws/s3/notification.py +24 -0
  342. cartography/models/aws/secretsmanager/secret.py +106 -0
  343. cartography/models/aws/secretsmanager/secret_version.py +0 -2
  344. cartography/models/aws/sns/topic_subscription.py +74 -0
  345. cartography/models/aws/sqs/__init__.py +0 -0
  346. cartography/models/aws/sqs/queue.py +89 -0
  347. cartography/models/azure/__init__.py +0 -0
  348. cartography/models/azure/aks_cluster.py +54 -0
  349. cartography/models/azure/aks_nodepool.py +54 -0
  350. cartography/models/azure/app_service.py +59 -0
  351. cartography/models/azure/container_instance.py +57 -0
  352. cartography/models/azure/cosmosdb/__init__.py +0 -0
  353. cartography/models/azure/cosmosdb/account.py +77 -0
  354. cartography/models/azure/cosmosdb/accountfailoverpolicy.py +77 -0
  355. cartography/models/azure/cosmosdb/cassandrakeyspace.py +82 -0
  356. cartography/models/azure/cosmosdb/cassandratable.py +81 -0
  357. cartography/models/azure/cosmosdb/corspolicy.py +74 -0
  358. cartography/models/azure/cosmosdb/dblocation.py +120 -0
  359. cartography/models/azure/cosmosdb/mongodbcollection.py +82 -0
  360. cartography/models/azure/cosmosdb/mongodbdatabase.py +78 -0
  361. cartography/models/azure/cosmosdb/privateendpointconnection.py +81 -0
  362. cartography/models/azure/cosmosdb/sqlcontainer.py +88 -0
  363. cartography/models/azure/cosmosdb/sqldatabase.py +78 -0
  364. cartography/models/azure/cosmosdb/tableresource.py +76 -0
  365. cartography/models/azure/cosmosdb/virtualnetworkrule.py +78 -0
  366. cartography/models/azure/data_factory/__init__.py +0 -0
  367. cartography/models/azure/data_factory/data_factory.py +51 -0
  368. cartography/models/azure/data_factory/data_factory_dataset.py +94 -0
  369. cartography/models/azure/data_factory/data_factory_linked_service.py +78 -0
  370. cartography/models/azure/data_factory/data_factory_pipeline.py +93 -0
  371. cartography/models/azure/data_lake_filesystem.py +51 -0
  372. cartography/models/azure/event_grid_topic.py +57 -0
  373. cartography/models/azure/function_app.py +59 -0
  374. cartography/models/azure/load_balancer/__init__.py +0 -0
  375. cartography/models/azure/load_balancer/load_balancer.py +49 -0
  376. cartography/models/azure/load_balancer/load_balancer_backend_pool.py +73 -0
  377. cartography/models/azure/load_balancer/load_balancer_frontend_ip.py +75 -0
  378. cartography/models/azure/load_balancer/load_balancer_inbound_nat_rule.py +78 -0
  379. cartography/models/azure/load_balancer/load_balancer_rule.py +108 -0
  380. cartography/models/azure/logic_apps.py +56 -0
  381. cartography/models/azure/monitor.py +54 -0
  382. cartography/models/azure/network_interface.py +112 -0
  383. cartography/models/azure/network_security_group.py +50 -0
  384. cartography/models/azure/permission_relationships.py +60 -0
  385. cartography/models/azure/principal.py +41 -0
  386. cartography/models/azure/public_ip_address.py +50 -0
  387. cartography/models/azure/rbac.py +268 -0
  388. cartography/models/azure/resource_groups.py +52 -0
  389. cartography/models/azure/security_center.py +50 -0
  390. cartography/models/azure/sql/__init__.py +0 -0
  391. cartography/models/azure/sql/databasethreatdetectionpolicy.py +85 -0
  392. cartography/models/azure/sql/elasticpool.py +77 -0
  393. cartography/models/azure/sql/failovergroup.py +73 -0
  394. cartography/models/azure/sql/recoverabledatabase.py +75 -0
  395. cartography/models/azure/sql/replicationlink.py +81 -0
  396. cartography/models/azure/sql/restorabledroppeddatabase.py +82 -0
  397. cartography/models/azure/sql/restorepoint.py +74 -0
  398. cartography/models/azure/sql/serveradadministrator.py +74 -0
  399. cartography/models/azure/sql/serverdnsalias.py +71 -0
  400. cartography/models/azure/sql/sqldatabase.py +85 -0
  401. cartography/models/azure/sql/sqlserver.py +50 -0
  402. cartography/models/azure/sql/transparentdataencryption.py +76 -0
  403. cartography/models/azure/storage/__init__.py +0 -0
  404. cartography/models/azure/storage/account.py +59 -0
  405. cartography/models/azure/storage/blobcontainer.py +85 -0
  406. cartography/models/azure/storage/blobservice.py +71 -0
  407. cartography/models/azure/storage/fileservice.py +71 -0
  408. cartography/models/azure/storage/fileshare.py +82 -0
  409. cartography/models/azure/storage/queue.py +71 -0
  410. cartography/models/azure/storage/queueservice.py +73 -0
  411. cartography/models/azure/storage/table.py +72 -0
  412. cartography/models/azure/storage/tableservice.py +73 -0
  413. cartography/models/azure/subnet.py +101 -0
  414. cartography/models/azure/subscription.py +47 -0
  415. cartography/models/azure/tags/__init__.py +0 -0
  416. cartography/models/azure/tags/storage_tag.py +40 -0
  417. cartography/models/azure/tags/tag.py +37 -0
  418. cartography/models/azure/tenant.py +17 -0
  419. cartography/models/azure/virtual_network.py +49 -0
  420. cartography/models/azure/vm/__init__.py +0 -0
  421. cartography/models/azure/vm/datadisk.py +80 -0
  422. cartography/models/azure/vm/disk.py +55 -0
  423. cartography/models/azure/vm/snapshot.py +56 -0
  424. cartography/models/azure/vm/virtualmachine.py +59 -0
  425. cartography/models/bigfix/bigfix_computer.py +1 -1
  426. cartography/models/cloudflare/member.py +4 -0
  427. cartography/models/core/common.py +1 -0
  428. cartography/models/core/nodes.py +15 -2
  429. cartography/models/core/relationships.py +44 -0
  430. cartography/models/crowdstrike/hosts.py +1 -1
  431. cartography/models/digitalocean/droplet.py +2 -0
  432. cartography/models/duo/endpoint.py +1 -1
  433. cartography/models/duo/phone.py +2 -2
  434. cartography/models/duo/user.py +4 -0
  435. cartography/models/entra/app_role_assignment.py +115 -0
  436. cartography/models/entra/application.py +49 -0
  437. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  438. cartography/models/entra/group.py +117 -0
  439. cartography/models/entra/service_principal.py +104 -0
  440. cartography/models/entra/user.py +42 -51
  441. cartography/models/gcp/__init__.py +0 -0
  442. cartography/models/gcp/bigtable/__init__.py +0 -0
  443. cartography/models/gcp/bigtable/app_profile.py +94 -0
  444. cartography/models/gcp/bigtable/backup.py +91 -0
  445. cartography/models/gcp/bigtable/cluster.py +73 -0
  446. cartography/models/gcp/bigtable/instance.py +52 -0
  447. cartography/models/gcp/bigtable/table.py +69 -0
  448. cartography/models/gcp/compute/__init__.py +0 -0
  449. cartography/models/gcp/compute/subnet.py +74 -0
  450. cartography/models/gcp/compute/vpc.py +50 -0
  451. cartography/models/gcp/crm/__init__.py +0 -0
  452. cartography/models/gcp/crm/folders.py +98 -0
  453. cartography/models/gcp/crm/organizations.py +21 -0
  454. cartography/models/gcp/crm/projects.py +100 -0
  455. cartography/models/gcp/dns.py +109 -0
  456. cartography/models/gcp/gke.py +69 -0
  457. cartography/models/gcp/iam.py +3 -0
  458. cartography/models/gcp/permission_relationships.py +61 -0
  459. cartography/models/gcp/policy_bindings.py +93 -0
  460. cartography/models/gcp/storage/__init__.py +0 -0
  461. cartography/models/gcp/storage/bucket.py +119 -0
  462. cartography/models/github/commits.py +63 -0
  463. cartography/models/github/dependencies.py +73 -0
  464. cartography/models/github/manifests.py +49 -0
  465. cartography/models/github/users.py +10 -0
  466. cartography/models/googleworkspace/__init__.py +0 -0
  467. cartography/models/googleworkspace/device.py +132 -0
  468. cartography/models/googleworkspace/group.py +382 -0
  469. cartography/models/googleworkspace/oauth_app.py +124 -0
  470. cartography/models/googleworkspace/tenant.py +30 -0
  471. cartography/models/googleworkspace/user.py +113 -0
  472. cartography/models/gsuite/__init__.py +0 -0
  473. cartography/models/gsuite/group.py +218 -0
  474. cartography/models/gsuite/tenant.py +29 -0
  475. cartography/models/gsuite/user.py +107 -0
  476. cartography/models/kandji/device.py +1 -2
  477. cartography/models/keycloak/__init__.py +0 -0
  478. cartography/models/keycloak/authenticationexecution.py +160 -0
  479. cartography/models/keycloak/authenticationflow.py +54 -0
  480. cartography/models/keycloak/client.py +179 -0
  481. cartography/models/keycloak/group.py +101 -0
  482. cartography/models/keycloak/identityprovider.py +89 -0
  483. cartography/models/keycloak/organization.py +116 -0
  484. cartography/models/keycloak/organizationdomain.py +73 -0
  485. cartography/models/keycloak/realm.py +173 -0
  486. cartography/models/keycloak/role.py +126 -0
  487. cartography/models/keycloak/scope.py +73 -0
  488. cartography/models/keycloak/user.py +55 -0
  489. cartography/models/kubernetes/__init__.py +0 -0
  490. cartography/models/kubernetes/clusterrolebindings.py +138 -0
  491. cartography/models/kubernetes/clusterroles.py +52 -0
  492. cartography/models/kubernetes/clusters.py +26 -0
  493. cartography/models/kubernetes/containers.py +133 -0
  494. cartography/models/kubernetes/groups.py +107 -0
  495. cartography/models/kubernetes/namespaces.py +51 -0
  496. cartography/models/kubernetes/oidc.py +51 -0
  497. cartography/models/kubernetes/pods.py +80 -0
  498. cartography/models/kubernetes/rolebindings.py +159 -0
  499. cartography/models/kubernetes/roles.py +76 -0
  500. cartography/models/kubernetes/secrets.py +79 -0
  501. cartography/models/kubernetes/serviceaccounts.py +77 -0
  502. cartography/models/kubernetes/services.py +108 -0
  503. cartography/models/kubernetes/users.py +105 -0
  504. cartography/models/lastpass/user.py +4 -0
  505. cartography/models/ontology/__init__.py +0 -0
  506. cartography/models/ontology/device.py +137 -0
  507. cartography/models/ontology/mapping/__init__.py +76 -0
  508. cartography/models/ontology/mapping/data/__init__.py +0 -0
  509. cartography/models/ontology/mapping/data/apikeys.py +93 -0
  510. cartography/models/ontology/mapping/data/computeinstance.py +95 -0
  511. cartography/models/ontology/mapping/data/containers.py +88 -0
  512. cartography/models/ontology/mapping/data/databases.py +182 -0
  513. cartography/models/ontology/mapping/data/devices.py +194 -0
  514. cartography/models/ontology/mapping/data/thirdpartyapps.py +140 -0
  515. cartography/models/ontology/mapping/data/useraccounts.py +416 -0
  516. cartography/models/ontology/mapping/data/users.py +63 -0
  517. cartography/models/ontology/mapping/specs.py +85 -0
  518. cartography/models/ontology/user.py +51 -0
  519. cartography/models/openai/adminapikey.py +4 -0
  520. cartography/models/openai/apikey.py +4 -0
  521. cartography/models/openai/user.py +4 -0
  522. cartography/models/scaleway/__init__.py +0 -0
  523. cartography/models/scaleway/iam/__init__.py +0 -0
  524. cartography/models/scaleway/iam/apikey.py +100 -0
  525. cartography/models/scaleway/iam/application.py +52 -0
  526. cartography/models/scaleway/iam/group.py +95 -0
  527. cartography/models/scaleway/iam/user.py +64 -0
  528. cartography/models/scaleway/instance/__init__.py +0 -0
  529. cartography/models/scaleway/instance/flexibleip.py +52 -0
  530. cartography/models/scaleway/instance/instance.py +120 -0
  531. cartography/models/scaleway/organization.py +19 -0
  532. cartography/models/scaleway/project.py +48 -0
  533. cartography/models/scaleway/storage/__init__.py +0 -0
  534. cartography/models/scaleway/storage/snapshot.py +78 -0
  535. cartography/models/scaleway/storage/volume.py +51 -0
  536. cartography/models/sentinelone/__init__.py +1 -0
  537. cartography/models/sentinelone/account.py +40 -0
  538. cartography/models/sentinelone/agent.py +50 -0
  539. cartography/models/sentinelone/application.py +44 -0
  540. cartography/models/sentinelone/application_version.py +96 -0
  541. cartography/models/sentinelone/cve.py +73 -0
  542. cartography/models/slack/__init__.py +0 -0
  543. cartography/models/slack/channels.py +92 -0
  544. cartography/models/slack/group.py +129 -0
  545. cartography/models/slack/team.py +22 -0
  546. cartography/models/slack/user.py +62 -0
  547. cartography/models/snipeit/asset.py +2 -0
  548. cartography/models/snipeit/user.py +4 -0
  549. cartography/models/spacelift/__init__.py +0 -0
  550. cartography/models/spacelift/cloudtrailevent.py +120 -0
  551. cartography/models/spacelift/run.py +162 -0
  552. cartography/models/spacelift/space.py +131 -0
  553. cartography/models/spacelift/spaceliftaccount.py +31 -0
  554. cartography/models/spacelift/spaceliftgitcommit.py +157 -0
  555. cartography/models/spacelift/stack.py +96 -0
  556. cartography/models/spacelift/user.py +63 -0
  557. cartography/models/spacelift/worker.py +97 -0
  558. cartography/models/spacelift/workerpool.py +90 -0
  559. cartography/models/tailscale/device.py +2 -1
  560. cartography/models/tailscale/user.py +6 -1
  561. cartography/models/trivy/__init__.py +0 -0
  562. cartography/models/trivy/findings.py +66 -0
  563. cartography/models/trivy/fix.py +66 -0
  564. cartography/models/trivy/package.py +71 -0
  565. cartography/rules/README.md +1 -0
  566. cartography/rules/__init__.py +0 -0
  567. cartography/rules/cli.py +261 -0
  568. cartography/rules/data/__init__.py +0 -0
  569. cartography/rules/data/rules/__init__.py +46 -0
  570. cartography/rules/data/rules/cloud_security_product_deactivated.py +49 -0
  571. cartography/rules/data/rules/compute_instance_exposed.py +51 -0
  572. cartography/rules/data/rules/database_instance_exposed.py +53 -0
  573. cartography/rules/data/rules/delegation_boundary_modifiable.py +90 -0
  574. cartography/rules/data/rules/identity_administration_privileges.py +100 -0
  575. cartography/rules/data/rules/inactive_user_active_accounts.py +48 -0
  576. cartography/rules/data/rules/malicious_npm_dependencies_shai_hulud.py +2222 -0
  577. cartography/rules/data/rules/mfa_missing.py +46 -0
  578. cartography/rules/data/rules/object_storage_public.py +100 -0
  579. cartography/rules/data/rules/policy_administration_privileges.py +104 -0
  580. cartography/rules/data/rules/unmanaged_accounts.py +43 -0
  581. cartography/rules/data/rules/workload_identity_admin_capabilities.py +193 -0
  582. cartography/rules/formatters.py +108 -0
  583. cartography/rules/runners.py +216 -0
  584. cartography/rules/spec/__init__.py +0 -0
  585. cartography/rules/spec/model.py +267 -0
  586. cartography/rules/spec/result.py +38 -0
  587. cartography/sync.py +25 -5
  588. cartography/util.py +101 -31
  589. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/METADATA +61 -22
  590. cartography-0.123.0.dist-info/RECORD +856 -0
  591. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/entry_points.txt +1 -0
  592. cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
  593. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  594. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  595. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  596. cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +0 -16
  597. cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
  598. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  599. cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
  600. cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
  601. cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
  602. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  603. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  604. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  605. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  606. cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
  607. cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -45
  608. cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
  609. cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -25
  610. cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -15
  611. cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -25
  612. cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -25
  613. cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -15
  614. cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -85
  615. cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -15
  616. cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -15
  617. cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -25
  618. cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -125
  619. cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -95
  620. cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -14
  621. cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -9
  622. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  623. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  624. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  625. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  626. cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
  627. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  628. cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
  629. cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -23
  630. cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -11
  631. cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -70
  632. cartography/intel/gcp/crm.py +0 -355
  633. cartography/intel/gsuite/api.py +0 -342
  634. cartography-0.104.0rc2.dist-info/RECORD +0 -455
  635. /cartography/data/jobs/{analysis → scoped_analysis}/aws_s3acl_analysis.json +0 -0
  636. /cartography/models/aws/{apigateway.py → apigateway/apigateway.py} +0 -0
  637. /cartography/models/aws/{apigatewaycertificate.py → apigateway/apigatewaycertificate.py} +0 -0
  638. /cartography/models/aws/{apigatewayresource.py → apigateway/apigatewayresource.py} +0 -0
  639. /cartography/models/aws/{apigatewaystage.py → apigateway/apigatewaystage.py} +0 -0
  640. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/WHEEL +0 -0
  641. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/licenses/LICENSE +0 -0
  642. {cartography-0.104.0rc2.dist-info → cartography-0.123.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,597 @@
1
+ import logging
2
+ from itertools import chain
3
+ from typing import Any
4
+ from typing import Dict
5
+ from typing import List
6
+
7
+ import neo4j
8
+ from kubernetes.client import V1ClusterRole
9
+ from kubernetes.client import V1ClusterRoleBinding
10
+ from kubernetes.client import V1Role
11
+ from kubernetes.client import V1RoleBinding
12
+ from kubernetes.client import V1ServiceAccount
13
+
14
+ from cartography.client.core.tx import load
15
+ from cartography.graph.job import GraphJob
16
+ from cartography.intel.kubernetes.util import get_epoch
17
+ from cartography.intel.kubernetes.util import k8s_paginate
18
+ from cartography.intel.kubernetes.util import K8sClient
19
+ from cartography.models.kubernetes.clusterrolebindings import (
20
+ KubernetesClusterRoleBindingSchema,
21
+ )
22
+ from cartography.models.kubernetes.clusterroles import KubernetesClusterRoleSchema
23
+ from cartography.models.kubernetes.groups import KubernetesGroupSchema
24
+ from cartography.models.kubernetes.rolebindings import KubernetesRoleBindingSchema
25
+ from cartography.models.kubernetes.roles import KubernetesRoleSchema
26
+ from cartography.models.kubernetes.serviceaccounts import KubernetesServiceAccountSchema
27
+ from cartography.models.kubernetes.users import KubernetesUserSchema
28
+ from cartography.util import timeit
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ @timeit
34
+ def get_service_accounts(k8s_client: K8sClient) -> List[V1ServiceAccount]:
35
+
36
+ return k8s_paginate(k8s_client.core.list_service_account_for_all_namespaces)
37
+
38
+
39
+ @timeit
40
+ def get_roles(k8s_client: K8sClient) -> List[V1Role]:
41
+
42
+ return k8s_paginate(k8s_client.rbac.list_role_for_all_namespaces)
43
+
44
+
45
+ @timeit
46
+ def get_role_bindings(k8s_client: K8sClient) -> List[V1RoleBinding]:
47
+
48
+ return k8s_paginate(k8s_client.rbac.list_role_binding_for_all_namespaces)
49
+
50
+
51
+ @timeit
52
+ def get_cluster_roles(k8s_client: K8sClient) -> List[V1ClusterRole]:
53
+
54
+ return k8s_paginate(k8s_client.rbac.list_cluster_role)
55
+
56
+
57
+ @timeit
58
+ def get_cluster_role_bindings(k8s_client: K8sClient) -> List[V1ClusterRoleBinding]:
59
+
60
+ return k8s_paginate(k8s_client.rbac.list_cluster_role_binding)
61
+
62
+
63
+ def transform_service_accounts(
64
+ service_accounts: List[V1ServiceAccount], cluster_name: str
65
+ ) -> List[Dict[str, Any]]:
66
+ """
67
+ Transform Kubernetes ServiceAccounts into a list of dictionaries.
68
+ Uses cluster-scoped IDs to prevent collisions across multiple clusters.
69
+ """
70
+ result = []
71
+ for sa in service_accounts:
72
+ result.append(
73
+ {
74
+ "id": f"{cluster_name}/{sa.metadata.namespace}/{sa.metadata.name}",
75
+ "name": sa.metadata.name,
76
+ "namespace": sa.metadata.namespace,
77
+ "uid": sa.metadata.uid,
78
+ "creation_timestamp": get_epoch(sa.metadata.creation_timestamp),
79
+ "resource_version": sa.metadata.resource_version,
80
+ }
81
+ )
82
+ return result
83
+
84
+
85
+ def transform_roles(roles: List[V1Role], cluster_name: str) -> List[Dict[str, Any]]:
86
+ """
87
+ Transform Kubernetes Roles into a list of dictionaries.
88
+ Flattens rules into separate api_groups, resources, and verbs lists.
89
+ """
90
+ result = []
91
+ for role in roles:
92
+ # Flatten all rules into combined sets
93
+ all_api_groups: set[str] = set()
94
+ all_resources: set[str] = set()
95
+ all_verbs: set[str] = set()
96
+
97
+ for rule in role.rules or []:
98
+ # Update api_groups, handling None and empty string cases
99
+ all_api_groups.update(
100
+ {
101
+ "core" if api_group == "" else api_group
102
+ for api_group in rule.api_groups or []
103
+ }
104
+ )
105
+ all_resources.update(rule.resources or [])
106
+ all_verbs.update(rule.verbs or [])
107
+
108
+ result.append(
109
+ {
110
+ "id": f"{cluster_name}/{role.metadata.namespace}/{role.metadata.name}",
111
+ "name": role.metadata.name,
112
+ "namespace": role.metadata.namespace,
113
+ "uid": role.metadata.uid,
114
+ "creation_timestamp": get_epoch(role.metadata.creation_timestamp),
115
+ "resource_version": role.metadata.resource_version,
116
+ "api_groups": sorted(
117
+ all_api_groups
118
+ ), # sorts to keep consistent ordering and converts to list to appease neo4j
119
+ "resources": sorted(all_resources),
120
+ "verbs": sorted(all_verbs),
121
+ }
122
+ )
123
+ return result
124
+
125
+
126
+ def transform_role_bindings(
127
+ role_bindings: List[V1RoleBinding], cluster_name: str
128
+ ) -> List[Dict[str, Any]]:
129
+ """
130
+ Transform Kubernetes RoleBindings into a list of dictionaries.
131
+ Creates one RoleBinding node per Kubernetes RoleBinding with lists of subject IDs.
132
+ """
133
+ result = []
134
+ for rb in role_bindings:
135
+ # Collect all subjects by type
136
+ service_account_subjects = [
137
+ subject
138
+ for subject in (rb.subjects or [])
139
+ if subject.kind == "ServiceAccount"
140
+ ]
141
+ user_subjects = [
142
+ subject for subject in (rb.subjects or []) if subject.kind == "User"
143
+ ]
144
+ group_subjects = [
145
+ subject for subject in (rb.subjects or []) if subject.kind == "Group"
146
+ ]
147
+
148
+ # Only create a RoleBinding node if it has at least one subject
149
+ if rb.subjects:
150
+ result.append(
151
+ {
152
+ "id": f"{cluster_name}/{rb.metadata.namespace}/{rb.metadata.name}",
153
+ "name": rb.metadata.name,
154
+ "namespace": rb.metadata.namespace,
155
+ "uid": rb.metadata.uid,
156
+ "creation_timestamp": get_epoch(rb.metadata.creation_timestamp),
157
+ "resource_version": rb.metadata.resource_version,
158
+ "role_name": rb.role_ref.name,
159
+ "role_kind": rb.role_ref.kind,
160
+ "service_account_ids": [
161
+ f"{cluster_name}/{subject.namespace}/{subject.name}"
162
+ for subject in service_account_subjects
163
+ ],
164
+ "user_ids": [
165
+ f"{cluster_name}/{subject.name}" for subject in user_subjects
166
+ ],
167
+ "group_ids": [
168
+ f"{cluster_name}/{subject.name}" for subject in group_subjects
169
+ ],
170
+ "role_id": f"{cluster_name}/{rb.metadata.namespace}/{rb.role_ref.name}",
171
+ }
172
+ )
173
+ return result
174
+
175
+
176
+ def transform_cluster_roles(
177
+ cluster_roles: List[V1ClusterRole], cluster_name: str
178
+ ) -> List[Dict[str, Any]]:
179
+ """
180
+ Transform Kubernetes ClusterRoles into a list of dictionaries.
181
+ Flattens rules into separate api_groups, resources, and verbs lists.
182
+ """
183
+ result = []
184
+ for cluster_role in cluster_roles:
185
+ # Flatten all rules into combined sets
186
+ all_api_groups: set[str] = set()
187
+ all_resources: set[str] = set()
188
+ all_verbs: set[str] = set()
189
+
190
+ for rule in cluster_role.rules or []:
191
+ # Update api_groups, handling None and empty string cases
192
+ all_api_groups.update(
193
+ {
194
+ "core" if api_group == "" else api_group
195
+ for api_group in rule.api_groups or []
196
+ }
197
+ )
198
+ all_resources.update(rule.resources or [])
199
+ all_verbs.update(rule.verbs or [])
200
+
201
+ result.append(
202
+ {
203
+ "id": f"{cluster_name}/{cluster_role.metadata.name}",
204
+ "name": cluster_role.metadata.name,
205
+ "uid": cluster_role.metadata.uid,
206
+ "creation_timestamp": get_epoch(
207
+ cluster_role.metadata.creation_timestamp
208
+ ),
209
+ "resource_version": cluster_role.metadata.resource_version,
210
+ "api_groups": sorted(
211
+ all_api_groups
212
+ ), # sorts to keep consistent ordering and converts to list to appease neo4j
213
+ "resources": sorted(all_resources),
214
+ "verbs": sorted(all_verbs),
215
+ }
216
+ )
217
+ return result
218
+
219
+
220
+ def transform_cluster_role_bindings(
221
+ cluster_role_bindings: List[V1ClusterRoleBinding], cluster_name: str
222
+ ) -> List[Dict[str, Any]]:
223
+ """
224
+ Transform Kubernetes ClusterRoleBindings into a list of dictionaries.
225
+ Creates one ClusterRoleBinding node per Kubernetes ClusterRoleBinding with lists of subject IDs.
226
+ """
227
+ result = []
228
+ for crb in cluster_role_bindings:
229
+ # Collect all subjects by type
230
+ service_account_subjects = [
231
+ subject
232
+ for subject in (crb.subjects or [])
233
+ if subject.kind == "ServiceAccount"
234
+ ]
235
+ user_subjects = [
236
+ subject for subject in (crb.subjects or []) if subject.kind == "User"
237
+ ]
238
+ group_subjects = [
239
+ subject for subject in (crb.subjects or []) if subject.kind == "Group"
240
+ ]
241
+
242
+ # Only create a ClusterRoleBinding node if it has at least one subject
243
+ if crb.subjects:
244
+ result.append(
245
+ {
246
+ "id": f"{cluster_name}/{crb.metadata.name}",
247
+ "name": crb.metadata.name,
248
+ "uid": crb.metadata.uid,
249
+ "creation_timestamp": get_epoch(crb.metadata.creation_timestamp),
250
+ "resource_version": crb.metadata.resource_version,
251
+ "role_name": crb.role_ref.name,
252
+ "role_kind": crb.role_ref.kind,
253
+ "service_account_ids": [
254
+ f"{cluster_name}/{subject.namespace}/{subject.name}"
255
+ for subject in service_account_subjects
256
+ ],
257
+ "user_ids": [
258
+ f"{cluster_name}/{subject.name}" for subject in user_subjects
259
+ ],
260
+ "group_ids": [
261
+ f"{cluster_name}/{subject.name}" for subject in group_subjects
262
+ ],
263
+ "role_id": f"{cluster_name}/{crb.role_ref.name}",
264
+ }
265
+ )
266
+ return result
267
+
268
+
269
+ def transform_users(
270
+ role_bindings: List[V1RoleBinding],
271
+ cluster_role_bindings: List[V1ClusterRoleBinding],
272
+ cluster_name: str,
273
+ ) -> List[Dict[str, Any]]:
274
+ """
275
+ Transform Kubernetes Users from RoleBindings and ClusterRoleBindings into a list of dicts.
276
+ """
277
+ # Extract all users from rolebindings and clusterrolebindings
278
+ all_users = {
279
+ subject.name
280
+ for binding in chain(
281
+ role_bindings, cluster_role_bindings
282
+ ) # iterate through combined bindings and role bindings
283
+ for subject in (
284
+ binding.subjects or []
285
+ ) # iterates through each binding's subjects to get unique users
286
+ if subject.kind == "User"
287
+ }
288
+
289
+ return [
290
+ {
291
+ "id": f"{cluster_name}/{user_name}",
292
+ "name": user_name,
293
+ "cluster_name": cluster_name,
294
+ }
295
+ for user_name in sorted(all_users)
296
+ ]
297
+
298
+
299
+ def transform_groups(
300
+ role_bindings: List[V1RoleBinding],
301
+ cluster_role_bindings: List[V1ClusterRoleBinding],
302
+ cluster_name: str,
303
+ ) -> List[Dict[str, Any]]:
304
+ """
305
+ Transform Kubernetes Groups from RoleBindings and ClusterRoleBindings into a list of dicts.
306
+ """
307
+ # Extract all groups from rolebindings and clusterrolebindings
308
+ all_groups = {
309
+ subject.name
310
+ for binding in chain(role_bindings, cluster_role_bindings)
311
+ for subject in (binding.subjects or [])
312
+ if subject.kind == "Group"
313
+ }
314
+
315
+ return [
316
+ {
317
+ "id": f"{cluster_name}/{group_name}",
318
+ "name": group_name,
319
+ "cluster_name": cluster_name,
320
+ }
321
+ for group_name in sorted(all_groups)
322
+ ]
323
+
324
+
325
+ @timeit
326
+ def load_service_accounts(
327
+ session: neo4j.Session,
328
+ service_accounts: List[Dict[str, Any]],
329
+ update_tag: int,
330
+ cluster_id: str,
331
+ cluster_name: str,
332
+ ) -> None:
333
+ logger.info(f"Loading {len(service_accounts)} KubernetesServiceAccounts")
334
+ load(
335
+ session,
336
+ KubernetesServiceAccountSchema(),
337
+ service_accounts,
338
+ lastupdated=update_tag,
339
+ CLUSTER_ID=cluster_id,
340
+ CLUSTER_NAME=cluster_name,
341
+ )
342
+
343
+
344
+ @timeit
345
+ def load_roles(
346
+ session: neo4j.Session,
347
+ roles: List[Dict[str, Any]],
348
+ update_tag: int,
349
+ cluster_id: str,
350
+ cluster_name: str,
351
+ ) -> None:
352
+ logger.info(f"Loading {len(roles)} KubernetesRoles")
353
+ load(
354
+ session,
355
+ KubernetesRoleSchema(),
356
+ roles,
357
+ lastupdated=update_tag,
358
+ CLUSTER_ID=cluster_id,
359
+ CLUSTER_NAME=cluster_name,
360
+ )
361
+
362
+
363
+ @timeit
364
+ def load_role_bindings(
365
+ session: neo4j.Session,
366
+ role_bindings: List[Dict[str, Any]],
367
+ update_tag: int,
368
+ cluster_id: str,
369
+ cluster_name: str,
370
+ ) -> None:
371
+ logger.info(f"Loading {len(role_bindings)} KubernetesRoleBindings")
372
+ load(
373
+ session,
374
+ KubernetesRoleBindingSchema(),
375
+ role_bindings,
376
+ lastupdated=update_tag,
377
+ CLUSTER_ID=cluster_id,
378
+ CLUSTER_NAME=cluster_name,
379
+ )
380
+
381
+
382
+ @timeit
383
+ def load_cluster_roles(
384
+ session: neo4j.Session,
385
+ cluster_roles: List[Dict[str, Any]],
386
+ update_tag: int,
387
+ cluster_id: str,
388
+ cluster_name: str,
389
+ ) -> None:
390
+ logger.info(f"Loading {len(cluster_roles)} KubernetesClusterRoles")
391
+ load(
392
+ session,
393
+ KubernetesClusterRoleSchema(),
394
+ cluster_roles,
395
+ lastupdated=update_tag,
396
+ CLUSTER_ID=cluster_id,
397
+ CLUSTER_NAME=cluster_name,
398
+ )
399
+
400
+
401
+ @timeit
402
+ def load_cluster_role_bindings(
403
+ session: neo4j.Session,
404
+ cluster_role_bindings: List[Dict[str, Any]],
405
+ update_tag: int,
406
+ cluster_id: str,
407
+ cluster_name: str,
408
+ ) -> None:
409
+ logger.info(f"Loading {len(cluster_role_bindings)} KubernetesClusterRoleBindings")
410
+ load(
411
+ session,
412
+ KubernetesClusterRoleBindingSchema(),
413
+ cluster_role_bindings,
414
+ lastupdated=update_tag,
415
+ CLUSTER_ID=cluster_id,
416
+ CLUSTER_NAME=cluster_name,
417
+ )
418
+
419
+
420
+ @timeit
421
+ def load_users(
422
+ session: neo4j.Session,
423
+ users: List[Dict[str, Any]],
424
+ update_tag: int,
425
+ cluster_id: str,
426
+ cluster_name: str,
427
+ ) -> None:
428
+ logger.info(f"Loading {len(users)} KubernetesUsers")
429
+ load(
430
+ session,
431
+ KubernetesUserSchema(),
432
+ users,
433
+ lastupdated=update_tag,
434
+ CLUSTER_ID=cluster_id,
435
+ CLUSTER_NAME=cluster_name,
436
+ )
437
+
438
+
439
+ @timeit
440
+ def load_groups(
441
+ session: neo4j.Session,
442
+ groups: List[Dict[str, Any]],
443
+ update_tag: int,
444
+ cluster_id: str,
445
+ cluster_name: str,
446
+ ) -> None:
447
+ logger.info(f"Loading {len(groups)} KubernetesGroups")
448
+ load(
449
+ session,
450
+ KubernetesGroupSchema(),
451
+ groups,
452
+ lastupdated=update_tag,
453
+ CLUSTER_ID=cluster_id,
454
+ CLUSTER_NAME=cluster_name,
455
+ )
456
+
457
+
458
+ @timeit
459
+ def cleanup(session: neo4j.Session, common_job_parameters: Dict[str, Any]) -> None:
460
+ logger.debug("Running cleanup job for Kubernetes RBAC resources")
461
+ cleanup_job = GraphJob.from_node_schema(
462
+ KubernetesServiceAccountSchema(), common_job_parameters
463
+ )
464
+ cleanup_job.run(session)
465
+
466
+ cleanup_job = GraphJob.from_node_schema(
467
+ KubernetesRoleSchema(), common_job_parameters
468
+ )
469
+ cleanup_job.run(session)
470
+
471
+ cleanup_job = GraphJob.from_node_schema(
472
+ KubernetesRoleBindingSchema(), common_job_parameters
473
+ )
474
+ cleanup_job.run(session)
475
+
476
+ cleanup_job = GraphJob.from_node_schema(
477
+ KubernetesClusterRoleSchema(), common_job_parameters
478
+ )
479
+ cleanup_job.run(session)
480
+
481
+ cleanup_job = GraphJob.from_node_schema(
482
+ KubernetesClusterRoleBindingSchema(), common_job_parameters
483
+ )
484
+ cleanup_job.run(session)
485
+
486
+ cleanup_job = GraphJob.from_node_schema(
487
+ KubernetesUserSchema(), common_job_parameters
488
+ )
489
+ cleanup_job.run(session)
490
+
491
+ cleanup_job = GraphJob.from_node_schema(
492
+ KubernetesGroupSchema(), common_job_parameters
493
+ )
494
+ cleanup_job.run(session)
495
+
496
+
497
+ @timeit
498
+ def sync_kubernetes_rbac(
499
+ session: neo4j.Session,
500
+ client: K8sClient,
501
+ update_tag: int,
502
+ common_job_parameters: Dict[str, Any],
503
+ ) -> None:
504
+ logger.info(f"Syncing Kubernetes RBAC resources for cluster {client.name}")
505
+
506
+ # Get namespace-scoped resources
507
+ service_accounts = get_service_accounts(client)
508
+ roles = get_roles(client)
509
+ role_bindings = get_role_bindings(client)
510
+
511
+ # Get cluster-scoped resources
512
+ cluster_roles = get_cluster_roles(client)
513
+ cluster_role_bindings = get_cluster_role_bindings(client)
514
+
515
+ # Transform namespace-scoped resources
516
+ transformed_service_accounts = transform_service_accounts(
517
+ service_accounts, client.name
518
+ )
519
+ transformed_roles = transform_roles(roles, client.name)
520
+ transformed_role_bindings = transform_role_bindings(role_bindings, client.name)
521
+
522
+ # Transform cluster-scoped resources
523
+ transformed_cluster_roles = transform_cluster_roles(cluster_roles, client.name)
524
+ transformed_cluster_role_bindings = transform_cluster_role_bindings(
525
+ cluster_role_bindings, client.name
526
+ )
527
+
528
+ # Transform users from all bindings
529
+ transformed_users = transform_users(
530
+ role_bindings, cluster_role_bindings, client.name
531
+ )
532
+
533
+ # Transform groups from all bindings
534
+ transformed_groups = transform_groups(
535
+ role_bindings, cluster_role_bindings, client.name
536
+ )
537
+
538
+ cluster_id = common_job_parameters["CLUSTER_ID"]
539
+ cluster_name = client.name
540
+
541
+ load_users(
542
+ session=session,
543
+ users=transformed_users,
544
+ update_tag=update_tag,
545
+ cluster_id=cluster_id,
546
+ cluster_name=cluster_name,
547
+ )
548
+
549
+ load_groups(
550
+ session=session,
551
+ groups=transformed_groups,
552
+ update_tag=update_tag,
553
+ cluster_id=cluster_id,
554
+ cluster_name=cluster_name,
555
+ )
556
+
557
+ load_service_accounts(
558
+ session=session,
559
+ service_accounts=transformed_service_accounts,
560
+ update_tag=update_tag,
561
+ cluster_id=cluster_id,
562
+ cluster_name=cluster_name,
563
+ )
564
+
565
+ load_roles(
566
+ session=session,
567
+ roles=transformed_roles,
568
+ update_tag=update_tag,
569
+ cluster_id=cluster_id,
570
+ cluster_name=cluster_name,
571
+ )
572
+
573
+ load_cluster_roles(
574
+ session=session,
575
+ cluster_roles=transformed_cluster_roles,
576
+ update_tag=update_tag,
577
+ cluster_id=cluster_id,
578
+ cluster_name=cluster_name,
579
+ )
580
+
581
+ load_role_bindings(
582
+ session=session,
583
+ role_bindings=transformed_role_bindings,
584
+ update_tag=update_tag,
585
+ cluster_id=cluster_id,
586
+ cluster_name=cluster_name,
587
+ )
588
+
589
+ load_cluster_role_bindings(
590
+ session=session,
591
+ cluster_role_bindings=transformed_cluster_role_bindings,
592
+ update_tag=update_tag,
593
+ cluster_id=cluster_id,
594
+ cluster_name=cluster_name,
595
+ )
596
+
597
+ cleanup(session, common_job_parameters)