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,46 @@
1
+ from cartography.rules.spec.model import Fact
2
+ from cartography.rules.spec.model import Finding
3
+ from cartography.rules.spec.model import Maturity
4
+ from cartography.rules.spec.model import Module
5
+ from cartography.rules.spec.model import Rule
6
+
7
+ # Facts
8
+ _missing_mfa_cloudflare = Fact(
9
+ id="missing-mfa-cloudflare",
10
+ name="Cloudflare members with disabled MFA",
11
+ description="Finds Cloudflare member accounts that have Multi-Factor Authentication disabled.",
12
+ module=Module.CLOUDFLARE,
13
+ cypher_query="""
14
+ MATCH (m:CloudflareMember)
15
+ WHERE m.two_factor_authentication_enabled = false
16
+ RETURN m.id AS id, m.email AS email, m.firstname AS firstname, m.lastname AS lastname, m.status AS status
17
+ """,
18
+ cypher_visual_query="""
19
+ MATCH (m:CloudflareMember)
20
+ WHERE m.two_factor_authentication_enabled = false
21
+ RETURN m
22
+ """,
23
+ maturity=Maturity.EXPERIMENTAL,
24
+ )
25
+
26
+
27
+ # Rule
28
+ class MFARuleOutput(Finding):
29
+ email: str | None = None
30
+ id: str | None = None
31
+ firstname: str | None = None
32
+ lastname: str | None = None
33
+
34
+
35
+ missing_mfa_rule = Rule(
36
+ id="mfa-missing",
37
+ name="User accounts missing MFA",
38
+ description="Detects user accounts that do not have Multi-Factor Authentication enabled.",
39
+ output_model=MFARuleOutput,
40
+ tags=("identity",),
41
+ facts=(
42
+ # TODO: _missing_mfa_slack,
43
+ _missing_mfa_cloudflare,
44
+ ),
45
+ version="0.1.0",
46
+ )
@@ -0,0 +1,100 @@
1
+ from cartography.rules.spec.model import Fact
2
+ from cartography.rules.spec.model import Finding
3
+ from cartography.rules.spec.model import Maturity
4
+ from cartography.rules.spec.model import Module
5
+ from cartography.rules.spec.model import Rule
6
+
7
+ # AWS Facts
8
+ _aws_s3_public = Fact(
9
+ id="aws_s3_public",
10
+ name="Internet-Accessible S3 Storage Attack Surface",
11
+ description=("AWS S3 buckets accessible from the internet"),
12
+ cypher_query="""
13
+ MATCH (b:S3Bucket)
14
+ WHERE b.anonymous_access = true
15
+ OR (b.anonymous_actions IS NOT NULL AND size(b.anonymous_actions) > 0)
16
+ OR EXISTS {
17
+ MATCH (b)-[:POLICY_STATEMENT]->(stmt:S3PolicyStatement)
18
+ WHERE stmt.effect = 'Allow'
19
+ AND (stmt.principal = '*' OR stmt.principal CONTAINS 'AllUsers')
20
+ }
21
+ RETURN
22
+ b.id as id,
23
+ b.name AS name,
24
+ b.region AS region,
25
+ b.anonymous_access AS public_access,
26
+ b.anonymous_actions AS public_actions
27
+ """,
28
+ cypher_visual_query="""
29
+ MATCH (b:S3Bucket)
30
+ WHERE b.anonymous_access = true
31
+ OR (b.anonymous_actions IS NOT NULL AND size(b.anonymous_actions) > 0)
32
+ OR EXISTS {
33
+ MATCH (b)-[:POLICY_STATEMENT]->(stmt:S3PolicyStatement)
34
+ WHERE stmt.effect = 'Allow'
35
+ AND (stmt.principal = '*' OR stmt.principal CONTAINS 'AllUsers')
36
+ }
37
+ WITH b
38
+ OPTIONAL MATCH p=(b)-[:POLICY_STATEMENT]->(:S3PolicyStatement)
39
+ RETURN *
40
+ """,
41
+ module=Module.AWS,
42
+ maturity=Maturity.EXPERIMENTAL,
43
+ )
44
+
45
+ # Azure Facts
46
+ _azure_storage_public_blob_access = Fact(
47
+ id="azure_storage_public_blob_access",
48
+ name="Azure Storage Accounts with Public Blob Containers",
49
+ description=(
50
+ "Azure Storage Accounts that have blob containers with public access. "
51
+ "If a storage blob container has public_access set to 'Container' or 'Blob', "
52
+ "it means that the container is publicly accessible."
53
+ ),
54
+ cypher_query="""
55
+ MATCH (sa:AzureStorageAccount)-[:USES]->(bs:AzureStorageBlobService)-[:CONTAINS]->(bc:AzureStorageBlobContainer)
56
+ WHERE bc.publicaccess IN ['Container', 'Blob']
57
+ RETURN
58
+ sa.id AS account_id,
59
+ sa.name AS account,
60
+ sa.resourcegroup AS resource_group,
61
+ sa.location AS region,
62
+ bc.id as id,
63
+ bc.name AS name,
64
+ bc.publicaccess AS public_access_element,
65
+ bc.publicaccess IN ['Container', 'Blob'] AS public_access
66
+ """,
67
+ cypher_visual_query="""
68
+ MATCH p=(sa:AzureStorageAccount)-[:USES]->(bs:AzureStorageBlobService)-[:CONTAINS]->(bc:AzureStorageBlobContainer)
69
+ WHERE bc.publicaccess IN ['Container', 'Blob']
70
+ RETURN *
71
+ """,
72
+ module=Module.AZURE,
73
+ maturity=Maturity.EXPERIMENTAL,
74
+ )
75
+
76
+
77
+ # Rule
78
+ class ObjectStoragePublic(Finding):
79
+ name: str | None = None
80
+ id: str | None = None
81
+ account: str | None = None
82
+ account_id: str | None = None
83
+ region: str | None = None
84
+ public_access: bool | None = None
85
+
86
+
87
+ object_storage_public = Rule(
88
+ id="object_storage_public",
89
+ name="Public Object Storage Attack Surface",
90
+ description=(
91
+ "Publicly accessible object storage services such as AWS S3 buckets and Azure Storage Blob Containers"
92
+ ),
93
+ output_model=ObjectStoragePublic,
94
+ facts=(
95
+ _aws_s3_public,
96
+ _azure_storage_public_blob_access,
97
+ ),
98
+ tags=("infrastructure", "attack_surface"),
99
+ version="0.1.0",
100
+ )
@@ -0,0 +1,104 @@
1
+ from cartography.rules.spec.model import Fact
2
+ from cartography.rules.spec.model import Finding
3
+ from cartography.rules.spec.model import Maturity
4
+ from cartography.rules.spec.model import Module
5
+ from cartography.rules.spec.model import Rule
6
+
7
+ # AWS
8
+ _aws_policy_manipulation_capabilities = Fact(
9
+ id="aws_policy_manipulation_capabilities",
10
+ name="Principals with IAM Policy Creation and Modification Capabilities",
11
+ description=(
12
+ "AWS IAM principals that can create, modify, or attach IAM policies to other principals. "
13
+ ),
14
+ cypher_query="""
15
+ MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
16
+ MATCH (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(allow_stmt:AWSPolicyStatement {effect:"Allow"})
17
+ WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
18
+ AND NOT principal.name CONTAINS 'QuickSetup'
19
+ AND principal.name <> 'OrganizationAccountAccessRole'
20
+ WITH a, principal, policy, allow_stmt,
21
+ [label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
22
+ [
23
+ 'iam:CreatePolicy','iam:CreatePolicyVersion',
24
+ 'iam:AttachUserPolicy','iam:AttachRolePolicy','iam:AttachGroupPolicy',
25
+ 'iam:DetachUserPolicy','iam:DetachRolePolicy','iam:DetachGroupPolicy',
26
+ 'iam:PutUserPolicy','iam:PutRolePolicy','iam:PutGroupPolicy'
27
+ ] AS patterns
28
+ // Step 1 - Collect (action, resource) pairs for allowed statements
29
+ UNWIND allow_stmt.action AS allow_action
30
+ WITH a, principal, principal_type, policy, allow_stmt, allow_action, patterns
31
+ WHERE ANY(p IN patterns WHERE allow_action = p)
32
+ OR allow_action = 'iam:*'
33
+ OR allow_action = '*'
34
+ WITH a, principal, principal_type, policy, allow_stmt, allow_action, allow_stmt.resource AS allow_resources
35
+ // Step 2 - Gather all Deny statements for the same principal
36
+ OPTIONAL MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(deny_stmt:AWSPolicyStatement {effect:"Deny"})
37
+ WITH a, principal, principal_type, policy, allow_action, allow_resources,
38
+ REDUCE(acc = [], ds IN collect(deny_stmt.action) | acc + ds) AS all_deny_actions
39
+ // Step 3 - Filter out denied actions (handles *, iam:*, exact, and prefix wildcards)
40
+ WHERE NOT (
41
+ '*' IN all_deny_actions OR
42
+ 'iam:*' IN all_deny_actions OR
43
+ allow_action IN all_deny_actions OR
44
+ ANY(d IN all_deny_actions WHERE d ENDS WITH('*') AND allow_action STARTS WITH split(d,'*')[0])
45
+ )
46
+ // Step 4 - Preserve (action, resource) mapping
47
+ UNWIND allow_resources AS resource
48
+ RETURN DISTINCT
49
+ a.name AS account,
50
+ a.id AS account_id,
51
+ principal.name AS principal_name,
52
+ principal.arn AS principal_identifier,
53
+ principal_type,
54
+ policy.name AS policy_name,
55
+ allow_action AS action,
56
+ resource
57
+ ORDER BY account, principal_name, action, resource
58
+ """,
59
+ cypher_visual_query="""
60
+ MATCH p1=(a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
61
+ MATCH p2=(principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
62
+ WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
63
+ AND NOT principal.name CONTAINS 'QuickSetup'
64
+ AND principal.name <> 'OrganizationAccountAccessRole'
65
+ AND stmt.effect = 'Allow'
66
+ AND ANY(action IN stmt.action WHERE
67
+ action CONTAINS 'iam:CreatePolicy' OR action CONTAINS 'iam:CreatePolicyVersion'
68
+ OR action CONTAINS 'iam:AttachUserPolicy' OR action CONTAINS 'iam:AttachRolePolicy'
69
+ OR action CONTAINS 'iam:AttachGroupPolicy' OR action CONTAINS 'iam:DetachUserPolicy'
70
+ OR action CONTAINS 'iam:DetachRolePolicy' OR action CONTAINS 'iam:DetachGroupPolicy'
71
+ OR action CONTAINS 'iam:PutUserPolicy' OR action CONTAINS 'iam:PutRolePolicy'
72
+ OR action CONTAINS 'iam:PutGroupPolicy' OR action = 'iam:*' OR action = '*'
73
+ )
74
+ RETURN *
75
+ """,
76
+ module=Module.AWS,
77
+ maturity=Maturity.EXPERIMENTAL,
78
+ )
79
+
80
+
81
+ # Findings
82
+ class PolicyAdministrationPrivileges(Finding):
83
+ principal_name: str | None = None
84
+ principal_identifier: str | None = None
85
+ account: str | None = None
86
+ account_id: str | None = None
87
+ principal_type: str | None = None
88
+ policy_name: str | None = None
89
+ action: str | None = None
90
+ resource: str | None = None
91
+
92
+
93
+ policy_administration_privileges = Rule(
94
+ id="policy_administration_privileges",
95
+ name="Policy Administration Privileges",
96
+ description=(
97
+ "Principals can create, attach/detach, or write IAM policies—often enabling "
98
+ "indirect privilege escalation."
99
+ ),
100
+ output_model=PolicyAdministrationPrivileges,
101
+ facts=(_aws_policy_manipulation_capabilities,),
102
+ tags=("iam", "privilege_escalation"),
103
+ version="0.1.0",
104
+ )
@@ -0,0 +1,43 @@
1
+ from cartography.rules.spec.model import Fact
2
+ from cartography.rules.spec.model import Finding
3
+ from cartography.rules.spec.model import Maturity
4
+ from cartography.rules.spec.model import Module
5
+ from cartography.rules.spec.model import Rule
6
+
7
+ # Facts
8
+ _unmanaged_accounts_ontology = Fact(
9
+ id="unmanaged-accounts-ontology",
10
+ name="User accounts not linked to a user identity",
11
+ description="Finds user accounts that are not linked to an ontology user node.",
12
+ cypher_query="""
13
+ MATCH (a:UserAccount)
14
+ WHERE NOT (a)<-[:HAS_ACCOUNT]-(:User)
15
+ AND (a.active = true OR a.active IS NULL)
16
+ return a.id as id, a._ont_email AS email, a._ont_source AS source
17
+ """,
18
+ cypher_visual_query="""
19
+ MATCH (a:UserAccount)
20
+ WHERE NOT (a)<-[:HAS_ACCOUNT]-(:User)
21
+ AND (a.active = true OR a.active IS NULL)
22
+ return a
23
+ """,
24
+ module=Module.CROSS_CLOUD,
25
+ maturity=Maturity.EXPERIMENTAL,
26
+ )
27
+
28
+
29
+ # Rule
30
+ class UnmanagedAccountRuleOutput(Finding):
31
+ id: str | None = None
32
+ email: str | None = None
33
+
34
+
35
+ unmanaged_accounts = Rule(
36
+ id="unmanaged-account",
37
+ name="User accounts not linked to a user identity",
38
+ description="Detects accounts that are not linked to a known user identity (inactive accounts are excluded).",
39
+ output_model=UnmanagedAccountRuleOutput,
40
+ tags=("identity", "iam", "compliance"),
41
+ facts=(_unmanaged_accounts_ontology,),
42
+ version="0.1.1",
43
+ )
@@ -0,0 +1,193 @@
1
+ from cartography.rules.spec.model import Fact
2
+ from cartography.rules.spec.model import Finding
3
+ from cartography.rules.spec.model import Maturity
4
+ from cartography.rules.spec.model import Module
5
+ from cartography.rules.spec.model import Rule
6
+
7
+ # AWS
8
+ _aws_service_account_manipulation_via_ec2 = Fact(
9
+ id="aws_service_account_manipulation_via_ec2",
10
+ name="Service Resources with Account Manipulation Through Instance Profiles",
11
+ description=(
12
+ "AWS EC2 instances with attached IAM roles that can manipulate other AWS accounts. "
13
+ "Also indicates whether the instance is internet-exposed."
14
+ ),
15
+ cypher_query="""
16
+ MATCH (a:AWSAccount)-[:RESOURCE]->(ec2:EC2Instance)
17
+ MATCH (ec2)-[:INSTANCE_PROFILE]->(profile:AWSInstanceProfile)
18
+ MATCH (profile)-[:ASSOCIATED_WITH]->(role:AWSRole)
19
+ MATCH (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(allow_stmt:AWSPolicyStatement {effect:"Allow"})
20
+ WITH a, ec2, role, allow_stmt,
21
+ ['iam:Create','iam:Attach','iam:Put','iam:Update','iam:Add'] AS patterns
22
+ // Step 1: Collect allowed actions that match IAM modification patterns
23
+ WITH a, ec2, role, patterns,
24
+ [action IN allow_stmt.action
25
+ WHERE ANY(p IN patterns WHERE action STARTS WITH p)
26
+ OR action = 'iam:*'
27
+ OR action = '*'
28
+ ] AS matched_allow_actions
29
+ WHERE size(matched_allow_actions) > 0
30
+ // Step 2: Collect deny statements for the same role
31
+ OPTIONAL MATCH (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(deny_stmt:AWSPolicyStatement {effect:"Deny"})
32
+ WITH a, ec2, role, patterns, matched_allow_actions,
33
+ // Flatten the deny action lists manually
34
+ REDUCE(acc = [], ds IN collect(deny_stmt.action) | acc + ds) AS all_deny_actions
35
+ // Step 3: Compute effective = allows minus denies
36
+ WITH a, ec2, role, matched_allow_actions, all_deny_actions,
37
+ [action IN matched_allow_actions
38
+ WHERE NOT (
39
+ // Full wildcard Deny *
40
+ '*' IN all_deny_actions OR
41
+ // IAM category wildcard Deny iam:*
42
+ 'iam:*' IN all_deny_actions OR
43
+ // Exact match deny
44
+ action IN all_deny_actions OR
45
+ // Prefix wildcards like Deny iam:Update*
46
+ ANY(d IN all_deny_actions WHERE d ENDS WITH('*') AND action STARTS WITH split(d,'*')[0])
47
+ )
48
+ ] AS effective_actions
49
+ WHERE size(effective_actions) > 0
50
+ // Step 4: Optional internet exposure context
51
+ OPTIONAL MATCH (ec2 {exposed_internet: True})
52
+ -[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)
53
+ <-[:MEMBER_OF_EC2_SECURITY_GROUP]-(ip:IpPermissionInbound)
54
+ UNWIND effective_actions AS action
55
+ WITH a, ec2, role, sg, ip, COLLECT(DISTINCT action) AS actions
56
+ RETURN DISTINCT
57
+ ec2.id AS workload_id,
58
+ a.name AS account,
59
+ a.id AS account_id,
60
+ role.name AS role_name,
61
+ actions,
62
+ ec2.exposed_internet AS internet_accessible,
63
+ ec2.publicipaddress AS public_ip_address,
64
+ ip.fromport AS from_port,
65
+ ip.toport AS to_port
66
+ ORDER BY account, workload_id, internet_accessible, from_port
67
+ """,
68
+ cypher_visual_query="""
69
+ MATCH p = (a:AWSAccount)-[:RESOURCE]->(ec2:EC2Instance)
70
+ MATCH p1 = (ec2)-[:INSTANCE_PROFILE]->(profile:AWSInstanceProfile)
71
+ MATCH p2 = (profile)-[:ASSOCIATED_WITH]->(role:AWSRole)
72
+ MATCH p3 = (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
73
+ WHERE stmt.effect = 'Allow'
74
+ AND ANY(action IN stmt.action WHERE
75
+ action STARTS WITH 'iam:Create'
76
+ OR action STARTS WITH 'iam:Attach'
77
+ OR action STARTS WITH 'iam:Put'
78
+ OR action STARTS WITH 'iam:Update'
79
+ OR action STARTS WITH 'iam:Add'
80
+ OR action = 'iam:*'
81
+ OR action = '*'
82
+ )
83
+ WITH p, p1, p2, p3, ec2
84
+ // Include the SG and rules for the instances that are internet open
85
+ MATCH p4=(ec2{exposed_internet: true})-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(ip:IpPermissionInbound)
86
+ RETURN *
87
+ """,
88
+ module=Module.AWS,
89
+ maturity=Maturity.EXPERIMENTAL,
90
+ )
91
+
92
+ _aws_service_account_manipulation_via_lambda = Fact(
93
+ id="aws_service_account_manipulation",
94
+ name="Service Resources with Account Manipulation Through Lambda Roles",
95
+ description=(
96
+ "AWS Lambda functions with IAM roles that can manipulate other AWS accounts."
97
+ ),
98
+ cypher_query="""
99
+ // Find Lambda functions with IAM modification or account manipulation capabilities
100
+ MATCH (a:AWSAccount)-[:RESOURCE]->(lambda:AWSLambda)
101
+ MATCH (lambda)-[:STS_ASSUMEROLE_ALLOW]->(role:AWSRole)
102
+ MATCH (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(allow_stmt:AWSPolicyStatement {effect:"Allow"})
103
+ WITH a, lambda, role, allow_stmt,
104
+ ['iam:Create','iam:Attach','iam:Put','iam:Update','iam:Add'] AS patterns
105
+ // Step 1: Gather allowed actions that match IAM modification patterns
106
+ WITH a, lambda, role, patterns,
107
+ [action IN allow_stmt.action
108
+ WHERE ANY(p IN patterns WHERE action STARTS WITH p)
109
+ OR action = 'iam:*'
110
+ OR action = '*'
111
+ ] AS matched_allow_actions
112
+ WHERE size(matched_allow_actions) > 0
113
+ // Step 2: Gather all deny actions from the same role
114
+ OPTIONAL MATCH (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(deny_stmt:AWSPolicyStatement {effect:"Deny"})
115
+ WITH a, lambda, role, patterns, matched_allow_actions,
116
+ REDUCE(acc = [], ds IN collect(deny_stmt.action) | acc + ds) AS all_deny_actions
117
+ // Step 3: Subtract Deny actions from Allow actions
118
+ WITH a, lambda, role, matched_allow_actions, all_deny_actions,
119
+ [action IN matched_allow_actions
120
+ WHERE NOT (
121
+ // Global wildcard deny
122
+ '*' IN all_deny_actions OR
123
+ // IAM wildcard deny
124
+ 'iam:*' IN all_deny_actions OR
125
+ // Exact match deny
126
+ action IN all_deny_actions OR
127
+ // Prefix wildcards like Deny iam:Update*
128
+ ANY(d IN all_deny_actions WHERE d ENDS WITH('*') AND action STARTS WITH split(d,'*')[0])
129
+ )
130
+ ] AS effective_actions
131
+ WHERE size(effective_actions) > 0
132
+ // Step 4: Return only Lambdas with effective IAM modification capabilities
133
+ UNWIND effective_actions AS action
134
+ WITH a, lambda, role, COLLECT(DISTINCT action) AS actions
135
+ RETURN DISTINCT
136
+ lambda.arn AS workload_id,
137
+ lambda.name AS workload_name,
138
+ a.name AS account,
139
+ a.id AS account_id,
140
+ role.name AS role_name,
141
+ actions,
142
+ lambda.anonymous_access AS internet_accessible,
143
+ lambda.description AS description
144
+ ORDER BY account, workload_id, internet_accessible
145
+ """,
146
+ cypher_visual_query="""
147
+ MATCH p = (a:AWSAccount)-[:RESOURCE]->(lambda:AWSLambda)
148
+ MATCH p1 = (lambda)-[:STS_ASSUMEROLE_ALLOW]->(role:AWSRole)
149
+ MATCH p2 = (role)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
150
+ WHERE stmt.effect = 'Allow'
151
+ AND ANY(action IN stmt.action WHERE
152
+ action STARTS WITH 'iam:Create'
153
+ OR action STARTS WITH 'iam:Attach'
154
+ OR action STARTS WITH 'iam:Put'
155
+ OR action STARTS WITH 'iam:Update'
156
+ OR action STARTS WITH 'iam:Add'
157
+ OR action = 'iam:*'
158
+ OR action = '*'
159
+ )
160
+ RETURN *
161
+ """,
162
+ module=Module.AWS,
163
+ maturity=Maturity.EXPERIMENTAL,
164
+ )
165
+
166
+
167
+ # Rule
168
+ class WorkloadIdentityAdminCapabilities(Finding):
169
+ workload_name: str | None = None
170
+ workload_id: str | None = None
171
+ account: str | None = None
172
+ account_id: str | None = None
173
+ role_name: str | None = None
174
+ actions: list[str] | None = None
175
+ internet_accessible: bool | None = None
176
+ public_ip_address: str | None = None
177
+
178
+
179
+ workload_identity_admin_capabilities = Rule(
180
+ id="workload_identity_admin_capabilities",
181
+ name="Workload Identity-Admin Capabilities",
182
+ description=(
183
+ "A compute workload (VM or function) holds permissions to administer identities/policies. "
184
+ "If internet-exposed, the blast radius is higher."
185
+ ),
186
+ output_model=WorkloadIdentityAdminCapabilities,
187
+ facts=(
188
+ _aws_service_account_manipulation_via_ec2,
189
+ _aws_service_account_manipulation_via_lambda,
190
+ ),
191
+ tags=("iam", "privilege_escalation"),
192
+ version="0.1.0",
193
+ )
@@ -0,0 +1,108 @@
1
+ """
2
+ Output formatting utilities for Cartography rules.
3
+ """
4
+
5
+ import json
6
+ import re
7
+ from dataclasses import asdict
8
+ from dataclasses import is_dataclass
9
+ from urllib.parse import quote
10
+
11
+ from pydantic import BaseModel
12
+
13
+ from cartography.rules.data.rules import RULES
14
+ from cartography.rules.spec.result import RuleResult
15
+
16
+
17
+ def _generate_neo4j_browser_url(neo4j_uri: str, cypher_query: str) -> str:
18
+ """Generate a clickable Neo4j Browser URL with pre-populated query."""
19
+ # Handle different Neo4j URI protocols
20
+ if neo4j_uri.startswith("bolt://"):
21
+ browser_uri = neo4j_uri.replace("bolt://", "http://", 1)
22
+ elif neo4j_uri.startswith("bolt+s://"):
23
+ browser_uri = neo4j_uri.replace("bolt+s://", "https://", 1)
24
+ elif neo4j_uri.startswith("bolt+ssc://"):
25
+ browser_uri = neo4j_uri.replace("bolt+ssc://", "https://", 1)
26
+ elif neo4j_uri.startswith("neo4j://"):
27
+ browser_uri = neo4j_uri.replace("neo4j://", "http://", 1)
28
+ elif neo4j_uri.startswith("neo4j+s://"):
29
+ browser_uri = neo4j_uri.replace("neo4j+s://", "https://", 1)
30
+ elif neo4j_uri.startswith("neo4j+ssc://"):
31
+ browser_uri = neo4j_uri.replace("neo4j+ssc://", "https://", 1)
32
+ else:
33
+ browser_uri = neo4j_uri
34
+
35
+ # Handle port mapping for local instances
36
+ if ":7687" in browser_uri and (
37
+ "localhost" in browser_uri or "127.0.0.1" in browser_uri
38
+ ):
39
+ browser_uri = browser_uri.replace(":7687", ":7474")
40
+
41
+ # For Neo4j Aura (cloud), remove the port as it uses standard HTTPS port
42
+ if ".databases.neo4j.io" in browser_uri:
43
+ # Remove any port number for Aura URLs
44
+ browser_uri = re.sub(r":\d+", "", browser_uri)
45
+
46
+ # Ensure the URL ends properly
47
+ if not browser_uri.endswith("/"):
48
+ browser_uri += "/"
49
+
50
+ # URL encode the cypher query
51
+ encoded_query = quote(cypher_query.strip())
52
+
53
+ # Construct the Neo4j Browser URL with pre-populated query
54
+ return f"{browser_uri}browser/?cmd=edit&arg={encoded_query}"
55
+
56
+
57
+ def to_serializable(obj):
58
+ # Pydantic model (v2)
59
+ if isinstance(obj, BaseModel):
60
+ return to_serializable(obj.model_dump())
61
+
62
+ # Dataclass
63
+ if is_dataclass(obj):
64
+ return to_serializable(asdict(obj))
65
+
66
+ # Dict
67
+ if isinstance(obj, dict):
68
+ return {k: to_serializable(v) for k, v in obj.items()}
69
+
70
+ # List / Tuple / Set
71
+ if isinstance(obj, (list, tuple, set)):
72
+ return [to_serializable(v) for v in obj]
73
+
74
+ # Primitive
75
+ return obj
76
+
77
+
78
+ def _format_and_output_results(
79
+ all_results: list[RuleResult],
80
+ rule_names: list[str],
81
+ output_format: str,
82
+ total_facts: int,
83
+ total_findings: int,
84
+ ):
85
+ """Format and output the results of framework execution."""
86
+ if output_format == "json":
87
+ combined_output = [asdict(result) for result in all_results]
88
+ print(json.dumps(to_serializable(combined_output), indent=2))
89
+ else:
90
+ # Text summary
91
+ print("\n" + "=" * 60)
92
+ if len(rule_names) == 1:
93
+ print(f"EXECUTION SUMMARY - {RULES[rule_names[0]].name}")
94
+ else:
95
+ print("OVERALL SUMMARY")
96
+ print("=" * 60)
97
+
98
+ if len(rule_names) > 1:
99
+ print(f"Rules executed: {len(rule_names)}")
100
+ print(f"Total facts: {total_facts}")
101
+ print(f"Total findings: {total_findings}")
102
+
103
+ if total_findings > 0:
104
+ print(
105
+ f"\n\033[36mRule execution completed with {total_findings} total findings\033[0m"
106
+ )
107
+ else:
108
+ print("\n\033[90mRule execution completed with no findings\033[0m")