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
@@ -1,15 +1,23 @@
1
+ import json
1
2
  import logging
2
3
  from typing import Any
3
4
  from typing import Dict
4
5
  from typing import List
5
- from typing import Tuple
6
6
 
7
7
  import boto3
8
8
  import botocore
9
9
  import neo4j
10
-
10
+ from policyuniverse.policy import Policy
11
+
12
+ from cartography.client.core.tx import load
13
+ from cartography.graph.job import GraphJob
14
+ from cartography.models.aws.lambda_function.alias import AWSLambdaFunctionAliasSchema
15
+ from cartography.models.aws.lambda_function.event_source_mapping import (
16
+ AWSLambdaEventSourceMappingSchema,
17
+ )
18
+ from cartography.models.aws.lambda_function.lambda_function import AWSLambdaSchema
19
+ from cartography.models.aws.lambda_function.layer import AWSLambdaLayerSchema
11
20
  from cartography.util import aws_handle_regions
12
- from cartography.util import run_cleanup_job
13
21
  from cartography.util import timeit
14
22
 
15
23
  logger = logging.getLogger(__name__)
@@ -30,6 +38,56 @@ def get_lambda_data(boto3_session: boto3.session.Session, region: str) -> List[D
30
38
  return lambda_functions
31
39
 
32
40
 
41
+ def transform_lambda_functions(
42
+ lambda_functions: List[Dict],
43
+ permissions_by_arn: Dict[str, Dict[str, Any]],
44
+ region: str,
45
+ ) -> List[Dict]:
46
+ transformed_functions = []
47
+
48
+ for function_data in lambda_functions:
49
+ transformed_function = function_data.copy()
50
+
51
+ # In API response, TracingConfig is a nested object so flatten it for use in the data model
52
+ tracing_config = function_data.get("TracingConfig", {})
53
+ transformed_function["TracingConfigMode"] = tracing_config.get("Mode")
54
+
55
+ transformed_function["Region"] = region
56
+
57
+ function_arn = function_data["FunctionArn"]
58
+ permission_data = permissions_by_arn[function_arn]
59
+ transformed_function["AnonymousAccess"] = permission_data["AnonymousAccess"]
60
+ transformed_function["AnonymousActions"] = permission_data["AnonymousActions"]
61
+
62
+ transformed_functions.append(transformed_function)
63
+
64
+ return transformed_functions
65
+
66
+
67
+ def transform_lambda_aliases(aliases: List[Dict], function_arn: str) -> List[Dict]:
68
+ """
69
+ Transform lambda function aliases by adding the parent function ARN.
70
+ """
71
+ transformed_aliases = []
72
+ for alias in aliases:
73
+ transformed_alias = alias.copy()
74
+ transformed_alias["FunctionArn"] = function_arn
75
+ transformed_aliases.append(transformed_alias)
76
+ return transformed_aliases
77
+
78
+
79
+ def transform_lambda_layers(layers: List[Dict], function_arn: str) -> List[Dict]:
80
+ """
81
+ Transform lambda layers by adding the parent function ARN.
82
+ """
83
+ transformed_layers = []
84
+ for layer in layers:
85
+ transformed_layer = layer.copy()
86
+ transformed_layer["FunctionArn"] = function_arn
87
+ transformed_layers.append(transformed_layer)
88
+ return transformed_layers
89
+
90
+
33
91
  @timeit
34
92
  def load_lambda_functions(
35
93
  neo4j_session: neo4j.Session,
@@ -38,53 +96,16 @@ def load_lambda_functions(
38
96
  current_aws_account_id: str,
39
97
  aws_update_tag: int,
40
98
  ) -> None:
41
- ingest_lambda_functions = """
42
- UNWIND $lambda_functions_list AS lf
43
- MERGE (lambda:AWSLambda{id: lf.FunctionArn})
44
- ON CREATE SET lambda.firstseen = timestamp()
45
- SET lambda.name = lf.FunctionName,
46
- lambda.modifieddate = lf.LastModified,
47
- lambda.runtime = lf.Runtime,
48
- lambda.description = lf.Description,
49
- lambda.timeout = lf.Timeout,
50
- lambda.memory = lf.MemorySize,
51
- lambda.codesize = lf.CodeSize,
52
- lambda.handler = lf.Handler,
53
- lambda.version = lf.Version,
54
- lambda.tracingconfigmode = lf.TracingConfig.Mode,
55
- lambda.revisionid = lf.RevisionId,
56
- lambda.state = lf.State,
57
- lambda.statereason = lf.StateReason,
58
- lambda.statereasoncode = lf.StateReasonCode,
59
- lambda.lastupdatestatus = lf.LastUpdateStatus,
60
- lambda.lastupdatestatusreason = lf.LastUpdateStatusReason,
61
- lambda.lastupdatestatusreasoncode = lf.LastUpdateStatusReasonCode,
62
- lambda.packagetype = lf.PackageType,
63
- lambda.signingprofileversionarn = lf.SigningProfileVersionArn,
64
- lambda.signingjobarn = lf.SigningJobArn,
65
- lambda.codesha256 = lf.CodeSha256,
66
- lambda.architectures = lf.Architectures,
67
- lambda.masterarn = lf.MasterArn,
68
- lambda.kmskeyarn = lf.KMSKeyArn,
69
- lambda.lastupdated = $aws_update_tag
70
- WITH lambda, lf
71
- MATCH (owner:AWSAccount{id: $AWS_ACCOUNT_ID})
72
- MERGE (owner)-[r:RESOURCE]->(lambda)
73
- ON CREATE SET r.firstseen = timestamp()
74
- SET r.lastupdated = $aws_update_tag
75
- WITH lambda, lf
76
- MATCH (role:AWSPrincipal{arn: lf.Role})
77
- MERGE (lambda)-[r:STS_ASSUME_ROLE_ALLOW]->(role)
78
- ON CREATE SET r.firstseen = timestamp()
79
- SET r.lastupdated = $aws_update_tag
80
99
  """
81
-
82
- neo4j_session.run(
83
- ingest_lambda_functions,
84
- lambda_functions_list=data,
100
+ Load AWS Lambda functions using the data model
101
+ """
102
+ load(
103
+ neo4j_session,
104
+ AWSLambdaSchema(),
105
+ data,
106
+ AWS_ID=current_aws_account_id,
85
107
  Region=region,
86
- AWS_ACCOUNT_ID=current_aws_account_id,
87
- aws_update_tag=aws_update_tag,
108
+ lastupdated=aws_update_tag,
88
109
  )
89
110
 
90
111
 
@@ -118,169 +139,228 @@ def get_event_source_mappings(
118
139
 
119
140
  @timeit
120
141
  @aws_handle_regions
121
- def get_lambda_function_details(
122
- boto3_session: boto3.session.Session,
123
- data: List[Dict],
142
+ def get_lambda_permissions(
143
+ lambda_functions: List[Dict],
144
+ boto3_session: boto3.Session,
124
145
  region: str,
125
- ) -> List[Tuple[str, List[Any], List[Any], List[Any]]]:
146
+ ) -> Dict[str, Dict[str, Any]]:
147
+ """
148
+ Get Lambda permissions for the given functions in the specified region.
149
+ """
126
150
  client = boto3_session.client("lambda", region_name=region)
127
- details = []
128
- for lambda_function in data:
129
- function_aliases = get_function_aliases(lambda_function, client)
130
- event_source_mappings = get_event_source_mappings(lambda_function, client)
131
- layers = lambda_function.get("Layers", [])
132
- details.append(
133
- (
134
- lambda_function["FunctionArn"],
135
- function_aliases,
136
- event_source_mappings,
137
- layers,
138
- ),
139
- )
140
- return details
151
+ all_permissions = {}
152
+ for function in lambda_functions:
153
+ function_name = function["FunctionName"]
154
+ function_arn = function["FunctionArn"]
155
+
156
+ all_permissions[function_arn] = {
157
+ "AnonymousAccess": None,
158
+ "AnonymousActions": None,
159
+ }
160
+
161
+ try:
162
+ response = client.get_policy(FunctionName=function_name)
163
+ policy = response.get("Policy")
164
+
165
+ if policy:
166
+ parsed_policy = parse_policy(function_arn, policy)
167
+ all_permissions[function_arn] = {
168
+ "AnonymousAccess": parsed_policy.get("AnonymousAccess"),
169
+ "AnonymousActions": parsed_policy.get("AnonymousActions"),
170
+ }
171
+ except client.exceptions.ResourceNotFoundException:
172
+ logger.debug(f"No policy found for Lambda function {function_name}")
173
+ pass
174
+ except Exception as e:
175
+ logger.warning(
176
+ f"Error getting policy for Lambda function {function_name}: {e}"
177
+ )
178
+
179
+ return all_permissions
180
+
181
+
182
+ def parse_policy(function_arn: str, policy: str) -> Dict[str, Any]:
183
+ """
184
+ Parse the Lambda permission policy to extract anonymous access and actions.
185
+ """
186
+ policy_obj = Policy(json.loads(policy))
187
+ inet_actions = policy_obj.internet_accessible_actions()
188
+
189
+ return {
190
+ "AnonymousAccess": policy_obj.is_internet_accessible(),
191
+ "AnonymousActions": list(inet_actions) if inet_actions else [],
192
+ }
193
+
194
+
195
+ @timeit
196
+ def load_lambda_function_aliases(
197
+ neo4j_session: neo4j.Session,
198
+ lambda_aliases: List[Dict],
199
+ region: str,
200
+ current_aws_account_id: str,
201
+ update_tag: int,
202
+ ) -> None:
203
+ """
204
+ Load AWS Lambda function aliases using the data model
205
+ """
206
+ load(
207
+ neo4j_session,
208
+ AWSLambdaFunctionAliasSchema(),
209
+ lambda_aliases,
210
+ AWS_ID=current_aws_account_id,
211
+ Region=region,
212
+ lastupdated=update_tag,
213
+ )
141
214
 
142
215
 
143
216
  @timeit
144
- def load_lambda_function_details(
217
+ def load_lambda_event_source_mappings(
145
218
  neo4j_session: neo4j.Session,
146
- lambda_function_details: List[Tuple[str, List[Dict], List[Dict], List[Dict]]],
219
+ lambda_event_source_mappings: List[Dict],
220
+ current_aws_account_id: str,
147
221
  update_tag: int,
148
222
  ) -> None:
149
- lambda_aliases: List[Dict] = []
150
- lambda_event_source_mappings: List[Dict] = []
151
- lambda_layers: List[Dict] = []
152
- for function_arn, aliases, event_source_mappings, layers in lambda_function_details:
153
- if len(aliases) > 0:
154
- for alias in aliases:
155
- alias["FunctionArn"] = function_arn
156
- lambda_aliases.extend(aliases)
157
- if len(event_source_mappings) > 0:
158
- lambda_event_source_mappings.extend(event_source_mappings)
159
- if len(layers) > 0:
160
- for layer in layers:
161
- layer["FunctionArn"] = function_arn
162
- lambda_layers.extend(layers)
163
-
164
- _load_lambda_function_aliases(neo4j_session, lambda_aliases, update_tag)
165
- _load_lambda_event_source_mappings(
223
+ """
224
+ Load AWS Lambda event source mappings using the data model approach.
225
+ """
226
+ load(
166
227
  neo4j_session,
228
+ AWSLambdaEventSourceMappingSchema(),
167
229
  lambda_event_source_mappings,
168
- update_tag,
230
+ AWS_ID=current_aws_account_id,
231
+ lastupdated=update_tag,
169
232
  )
170
- _load_lambda_layers(neo4j_session, lambda_layers, update_tag)
171
233
 
172
234
 
173
235
  @timeit
174
- def _load_lambda_function_aliases(
236
+ def load_lambda_layers(
175
237
  neo4j_session: neo4j.Session,
176
- lambda_aliases: List[Dict],
238
+ lambda_layers: List[Dict],
239
+ current_aws_account_id: str,
177
240
  update_tag: int,
178
241
  ) -> None:
179
- ingest_aliases = """
180
- UNWIND $aliases_list AS alias
181
- MERGE (a:AWSLambdaFunctionAlias{id: alias.AliasArn})
182
- ON CREATE SET a.firstseen = timestamp()
183
- SET a.aliasname = alias.Name,
184
- a.functionversion = alias.FunctionVersion,
185
- a.description = alias.Description,
186
- a.revisionid = alias.RevisionId,
187
- a.lastupdated = $aws_update_tag
188
- WITH a, alias
189
- MATCH (lambda:AWSLambda{id: alias.FunctionArn})
190
- MERGE (lambda)-[r:KNOWN_AS]->(a)
191
- ON CREATE SET r.firstseen = timestamp()
192
- SET r.lastupdated = $aws_update_tag
193
242
  """
243
+ Load AWS Lambda layers using the data model approach.
244
+ """
245
+ load(
246
+ neo4j_session,
247
+ AWSLambdaLayerSchema(),
248
+ lambda_layers,
249
+ AWS_ID=current_aws_account_id,
250
+ lastupdated=update_tag,
251
+ )
252
+
253
+
254
+ @timeit
255
+ def cleanup_lambda(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
256
+ """
257
+ Clean up Lambda resources
258
+ """
259
+ logger.info("Running Lambda cleanup")
260
+
261
+ # Clean up child entities first
262
+ GraphJob.from_node_schema(
263
+ AWSLambdaFunctionAliasSchema(), common_job_parameters
264
+ ).run(neo4j_session)
265
+ GraphJob.from_node_schema(
266
+ AWSLambdaEventSourceMappingSchema(), common_job_parameters
267
+ ).run(neo4j_session)
268
+ GraphJob.from_node_schema(AWSLambdaLayerSchema(), common_job_parameters).run(
269
+ neo4j_session
270
+ )
194
271
 
195
- neo4j_session.run(
196
- ingest_aliases,
197
- aliases_list=lambda_aliases,
198
- aws_update_tag=update_tag,
272
+ # Clean up parent Lambda nodes last
273
+ GraphJob.from_node_schema(AWSLambdaSchema(), common_job_parameters).run(
274
+ neo4j_session
199
275
  )
200
276
 
201
277
 
202
278
  @timeit
203
- def _load_lambda_event_source_mappings(
279
+ def sync_aliases(
204
280
  neo4j_session: neo4j.Session,
205
- lambda_event_source_mappings: List[Dict],
281
+ lambda_functions: List[Dict],
282
+ client: Any,
283
+ region: str,
284
+ current_aws_account_id: str,
206
285
  update_tag: int,
207
286
  ) -> None:
208
- ingest_esms = """
209
- UNWIND $esm_list AS esm
210
- MERGE (e:AWSLambdaEventSourceMapping{id: esm.UUID})
211
- ON CREATE SET e.firstseen = timestamp()
212
- SET e.batchsize = esm.BatchSize,
213
- e.startingposition = esm.StartingPosition,
214
- e.startingpositiontimestamp = esm.StartingPositionTimestamp,
215
- e.parallelizationfactor = esm.ParallelizationFactor,
216
- e.maximumbatchingwindowinseconds = esm.MaximumBatchingWindowInSeconds,
217
- e.eventsourcearn = esm.EventSourceArn,
218
- e.lastmodified = esm.LastModified,
219
- e.lastprocessingresult = esm.LastProcessingResult,
220
- e.state = esm.State,
221
- e.maximumrecordage = esm.MaximumRecordAgeInSeconds,
222
- e.bisectbatchonfunctionerror = esm.BisectBatchOnFunctionError,
223
- e.maximumretryattempts = esm.MaximumRetryAttempts,
224
- e.tumblingwindowinseconds = esm.TumblingWindowInSeconds,
225
- e.lastupdated = $aws_update_tag
226
- WITH e, esm
227
- MATCH (lambda:AWSLambda{id: esm.FunctionArn})
228
- MERGE (lambda)-[r:RESOURCE]->(e)
229
- ON CREATE SET r.firstseen = timestamp()
230
- SET r.lastupdated = $aws_update_tag
231
287
  """
288
+ Sync Lambda function aliases for all functions in the region.
289
+ """
290
+ all_aliases = []
232
291
 
233
- neo4j_session.run(
234
- ingest_esms,
235
- esm_list=lambda_event_source_mappings,
236
- aws_update_tag=update_tag,
292
+ for lambda_function in lambda_functions:
293
+ function_arn = lambda_function["FunctionArn"]
294
+
295
+ # Get, transform, and collect aliases
296
+ aliases = get_function_aliases(lambda_function, client)
297
+ if aliases:
298
+ transformed_aliases = transform_lambda_aliases(aliases, function_arn)
299
+ all_aliases.extend(transformed_aliases)
300
+
301
+ # Load all aliases
302
+ load_lambda_function_aliases(
303
+ neo4j_session, all_aliases, region, current_aws_account_id, update_tag
237
304
  )
238
305
 
239
306
 
240
307
  @timeit
241
- def _load_lambda_layers(
308
+ def sync_event_source_mappings(
242
309
  neo4j_session: neo4j.Session,
243
- lambda_layers: List[Dict],
310
+ lambda_functions: List[Dict],
311
+ client: Any,
312
+ current_aws_account_id: str,
244
313
  update_tag: int,
245
314
  ) -> None:
246
- ingest_layers = """
247
- UNWIND $layers_list AS layer
248
- MERGE (l:AWSLambdaLayer{id: layer.Arn})
249
- ON CREATE SET l.firstseen = timestamp()
250
- SET l.codesize = layer.CodeSize,
251
- l.signingprofileversionarn = layer.SigningProfileVersionArn,
252
- l.signingjobarn = layer.SigningJobArn,
253
- l.lastupdated = $aws_update_tag
254
- WITH l, layer
255
- MATCH (lambda:AWSLambda{id: layer.FunctionArn})
256
- MERGE (lambda)-[r:HAS]->(l)
257
- ON CREATE SET r.firstseen = timestamp()
258
- SET r.lastupdated = $aws_update_tag
259
315
  """
316
+ Sync Lambda event source mappings for all functions in the region.
317
+ """
318
+ all_esms = []
319
+
320
+ for lambda_function in lambda_functions:
321
+ # Get and collect event source mappings (no transformation needed)
322
+ esms = get_event_source_mappings(lambda_function, client)
323
+ if esms:
324
+ all_esms.extend(esms)
260
325
 
261
- neo4j_session.run(
262
- ingest_layers,
263
- layers_list=lambda_layers,
264
- aws_update_tag=update_tag,
326
+ # Load all event source mappings
327
+ load_lambda_event_source_mappings(
328
+ neo4j_session, all_esms, current_aws_account_id, update_tag
265
329
  )
266
330
 
267
331
 
268
332
  @timeit
269
- def cleanup_lambda(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
270
- run_cleanup_job(
271
- "aws_import_lambda_cleanup.json",
272
- neo4j_session,
273
- common_job_parameters,
274
- )
333
+ def sync_lambda_layers(
334
+ neo4j_session: neo4j.Session,
335
+ lambda_functions: List[Dict],
336
+ current_aws_account_id: str,
337
+ update_tag: int,
338
+ ) -> None:
339
+ """
340
+ Sync Lambda layers for all functions in the region.
341
+ """
342
+ all_layers = []
343
+
344
+ for lambda_function in lambda_functions:
345
+ function_arn = lambda_function["FunctionArn"]
346
+
347
+ # Get, transform, and collect layers (from function data)
348
+ layers = lambda_function.get("Layers", [])
349
+ if layers:
350
+ transformed_layers = transform_lambda_layers(layers, function_arn)
351
+ all_layers.extend(transformed_layers)
352
+
353
+ # Load all layers
354
+ load_lambda_layers(neo4j_session, all_layers, current_aws_account_id, update_tag)
275
355
 
276
356
 
277
357
  @timeit
278
- def sync_lambda_functions(
358
+ def sync(
279
359
  neo4j_session: neo4j.Session,
280
360
  boto3_session: boto3.session.Session,
281
361
  regions: List[str],
282
362
  current_aws_account_id: str,
283
- aws_update_tag: int,
363
+ update_tag: int,
284
364
  common_job_parameters: Dict,
285
365
  ) -> None:
286
366
  for region in regions:
@@ -289,42 +369,45 @@ def sync_lambda_functions(
289
369
  region,
290
370
  current_aws_account_id,
291
371
  )
372
+
373
+ # Get and load core lambda functions
292
374
  data = get_lambda_data(boto3_session, region)
375
+ permissions_by_arn = get_lambda_permissions(data, boto3_session, region)
376
+ transformed_data = transform_lambda_functions(data, permissions_by_arn, region)
293
377
  load_lambda_functions(
294
378
  neo4j_session,
295
- data,
379
+ transformed_data,
296
380
  region,
297
381
  current_aws_account_id,
298
- aws_update_tag,
382
+ update_tag,
299
383
  )
300
- lambda_function_details = get_lambda_function_details(
301
- boto3_session,
384
+
385
+ # Create Lambda client for sub-entity requests
386
+ client = boto3_session.client("lambda", region_name=region)
387
+
388
+ # Sync all sub-entities
389
+ sync_aliases(
390
+ neo4j_session,
302
391
  data,
392
+ client,
303
393
  region,
394
+ current_aws_account_id,
395
+ update_tag,
304
396
  )
305
- load_lambda_function_details(
397
+
398
+ sync_event_source_mappings(
306
399
  neo4j_session,
307
- lambda_function_details,
308
- aws_update_tag,
400
+ data,
401
+ client,
402
+ current_aws_account_id,
403
+ update_tag,
309
404
  )
310
405
 
311
- cleanup_lambda(neo4j_session, common_job_parameters)
312
-
406
+ sync_lambda_layers(
407
+ neo4j_session,
408
+ data,
409
+ current_aws_account_id,
410
+ update_tag,
411
+ )
313
412
 
314
- @timeit
315
- def sync(
316
- neo4j_session: neo4j.Session,
317
- boto3_session: boto3.session.Session,
318
- regions: List[str],
319
- current_aws_account_id: str,
320
- update_tag: int,
321
- common_job_parameters: Dict,
322
- ) -> None:
323
- sync_lambda_functions(
324
- neo4j_session,
325
- boto3_session,
326
- regions,
327
- current_aws_account_id,
328
- update_tag,
329
- common_job_parameters,
330
- )
413
+ cleanup_lambda(neo4j_session, common_job_parameters)
@@ -5,6 +5,8 @@ import boto3
5
5
  import botocore.exceptions
6
6
  import neo4j
7
7
 
8
+ from cartography.client.core.tx import run_write_query
9
+ from cartography.intel.aws.iam import sync_root_principal
8
10
  from cartography.util import timeit
9
11
 
10
12
  logger = logging.getLogger(__name__)
@@ -110,24 +112,23 @@ def load_aws_accounts(
110
112
  ON CREATE SET aa.firstseen = timestamp()
111
113
  SET aa.lastupdated = $aws_update_tag, aa.name = $ACCOUNT_NAME, aa.inscope=true
112
114
  REMOVE aa.foreign
113
- WITH aa
114
- MERGE (root:AWSPrincipal{arn: $RootArn})
115
- ON CREATE SET root.firstseen = timestamp(), root.type = 'AWS'
116
- SET root.lastupdated = $aws_update_tag
117
- WITH aa, root
118
- MERGE (aa)-[r:RESOURCE]->(root)
119
- ON CREATE SET r.firstseen = timestamp()
120
- SET r.lastupdated = $aws_update_tag;
121
115
  """
122
116
  for account_name, account_id in aws_accounts.items():
123
117
  root_arn = f"arn:aws:iam::{account_id}:root"
124
- neo4j_session.run(
118
+ run_write_query(
119
+ neo4j_session,
125
120
  query,
126
121
  ACCOUNT_ID=account_id,
127
122
  ACCOUNT_NAME=account_name,
128
123
  RootArn=root_arn,
129
124
  aws_update_tag=aws_update_tag,
130
125
  )
126
+ # Every AWS account has a root principal
127
+ sync_root_principal(
128
+ neo4j_session,
129
+ account_id,
130
+ aws_update_tag,
131
+ )
131
132
 
132
133
 
133
134
  @timeit
@@ -12,6 +12,9 @@ import boto3
12
12
  import neo4j
13
13
  import yaml
14
14
 
15
+ from cartography.client.core.tx import read_list_of_dicts_tx
16
+ from cartography.client.core.tx import read_list_of_values_tx
17
+ from cartography.client.core.tx import run_write_query
15
18
  from cartography.graph.statement import GraphStatement
16
19
  from cartography.util import timeit
17
20
 
@@ -210,18 +213,6 @@ def calculate_permission_relationships(
210
213
  return allowed_mappings
211
214
 
212
215
 
213
- def parse_statement_node(node_group: List[Any]) -> List[Any]:
214
- """Parse a dict from group of Neo4J node
215
-
216
- Arguments:
217
- node_group {[Neo4j.Node]} -- the node to parse
218
-
219
- Returns:
220
- [list] -- A list of statements from the node
221
- """
222
- return [n._properties for n in node_group]
223
-
224
-
225
216
  def compile_regex(item: str) -> Pattern:
226
217
  r"""Compile a clause into a regex. Clause checking in AWS is case insensitive
227
218
  The following regex symbols will be replaced to make AWS * and ? matching a regex
@@ -280,7 +271,8 @@ def get_principals_for_account(neo4j_session: neo4j.Session, account_id: str) ->
280
271
  RETURN
281
272
  DISTINCT principal.arn as principal_arn, policy.id as policy_id, collect(statements) as statements
282
273
  """
283
- results = neo4j_session.run(
274
+ results = neo4j_session.execute_read(
275
+ read_list_of_dicts_tx,
284
276
  get_policy_query,
285
277
  AccountId=account_id,
286
278
  )
@@ -291,9 +283,7 @@ def get_principals_for_account(neo4j_session: neo4j.Session, account_id: str) ->
291
283
  statements = r["statements"]
292
284
  if principal_arn not in principals:
293
285
  principals[principal_arn] = {}
294
- principals[principal_arn][policy_id] = compile_statement(
295
- parse_statement_node(statements),
296
- )
286
+ principals[principal_arn][policy_id] = compile_statement(statements)
297
287
  return principals
298
288
 
299
289
 
@@ -311,12 +301,11 @@ def get_resource_arns(
311
301
  get_resource_query_template = get_resource_query.safe_substitute(
312
302
  node_label=node_label,
313
303
  )
314
- results = neo4j_session.run(
304
+ return neo4j_session.execute_read(
305
+ read_list_of_values_tx,
315
306
  get_resource_query_template,
316
307
  AccountId=account_id,
317
308
  )
318
- arns = [r["arn"] for r in results]
319
- return arns
320
309
 
321
310
 
322
311
  def load_principal_mappings(
@@ -341,7 +330,8 @@ def load_principal_mappings(
341
330
  node_label=node_label,
342
331
  relationship_name=relationship_name,
343
332
  )
344
- neo4j_session.run(
333
+ run_write_query(
334
+ neo4j_session,
345
335
  map_policy_query_template,
346
336
  Mapping=principal_mappings,
347
337
  aws_update_tag=update_tag,