cartography 0.116.1__py3-none-any.whl → 0.118.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.

Potentially problematic release.


This version of cartography might be problematic. Click here for more details.

Files changed (70) hide show
  1. cartography/_version.py +2 -2
  2. cartography/cli.py +11 -0
  3. cartography/client/core/tx.py +23 -2
  4. cartography/config.py +5 -0
  5. cartography/graph/job.py +6 -2
  6. cartography/graph/statement.py +4 -0
  7. cartography/intel/aws/__init__.py +1 -0
  8. cartography/intel/aws/apigateway.py +18 -5
  9. cartography/intel/aws/ec2/elastic_ip_addresses.py +3 -1
  10. cartography/intel/aws/ec2/internet_gateways.py +4 -2
  11. cartography/intel/aws/ec2/load_balancer_v2s.py +11 -5
  12. cartography/intel/aws/ec2/network_interfaces.py +4 -0
  13. cartography/intel/aws/ec2/reserved_instances.py +3 -1
  14. cartography/intel/aws/ec2/tgw.py +11 -5
  15. cartography/intel/aws/ec2/volumes.py +1 -1
  16. cartography/intel/aws/ecr.py +202 -26
  17. cartography/intel/aws/ecr_image_layers.py +174 -21
  18. cartography/intel/aws/elasticsearch.py +13 -4
  19. cartography/intel/aws/identitycenter.py +93 -54
  20. cartography/intel/aws/inspector.py +26 -14
  21. cartography/intel/aws/permission_relationships.py +3 -3
  22. cartography/intel/aws/s3.py +26 -13
  23. cartography/intel/aws/ssm.py +3 -5
  24. cartography/intel/azure/__init__.py +16 -0
  25. cartography/intel/azure/compute.py +9 -4
  26. cartography/intel/azure/container_instances.py +95 -0
  27. cartography/intel/azure/cosmosdb.py +31 -15
  28. cartography/intel/azure/data_lake.py +124 -0
  29. cartography/intel/azure/sql.py +25 -12
  30. cartography/intel/azure/storage.py +19 -9
  31. cartography/intel/azure/subscription.py +3 -1
  32. cartography/intel/crowdstrike/spotlight.py +5 -2
  33. cartography/intel/entra/app_role_assignments.py +9 -2
  34. cartography/intel/gcp/__init__.py +26 -9
  35. cartography/intel/gcp/clients.py +8 -4
  36. cartography/intel/gcp/compute.py +39 -18
  37. cartography/intel/gcp/crm/folders.py +9 -3
  38. cartography/intel/gcp/crm/orgs.py +8 -3
  39. cartography/intel/gcp/crm/projects.py +14 -3
  40. cartography/intel/github/teams.py +3 -3
  41. cartography/intel/jamf/computers.py +7 -1
  42. cartography/intel/oci/iam.py +23 -9
  43. cartography/intel/oci/organizations.py +3 -1
  44. cartography/intel/oci/utils.py +28 -5
  45. cartography/intel/okta/awssaml.py +8 -7
  46. cartography/intel/pagerduty/escalation_policies.py +13 -6
  47. cartography/intel/pagerduty/schedules.py +9 -4
  48. cartography/intel/pagerduty/services.py +7 -3
  49. cartography/intel/pagerduty/teams.py +5 -2
  50. cartography/intel/pagerduty/users.py +3 -1
  51. cartography/intel/pagerduty/vendors.py +3 -1
  52. cartography/intel/trivy/__init__.py +109 -58
  53. cartography/models/aws/ec2/networkinterfaces.py +2 -0
  54. cartography/models/aws/ecr/image.py +38 -1
  55. cartography/models/aws/ecr/repository_image.py +1 -1
  56. cartography/models/azure/container_instance.py +55 -0
  57. cartography/models/azure/data_lake_filesystem.py +51 -0
  58. cartography/rules/cli.py +8 -6
  59. cartography/rules/data/frameworks/mitre_attack/__init__.py +7 -1
  60. cartography/rules/data/frameworks/mitre_attack/requirements/t1098_account_manipulation/__init__.py +317 -0
  61. cartography/rules/data/frameworks/mitre_attack/requirements/t1190_exploit_public_facing_application/__init__.py +1 -0
  62. cartography/rules/spec/model.py +13 -0
  63. cartography/sync.py +1 -1
  64. cartography/util.py +5 -1
  65. {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/METADATA +5 -4
  66. {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/RECORD +70 -65
  67. {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/WHEEL +0 -0
  68. {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/entry_points.txt +0 -0
  69. {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/licenses/LICENSE +0 -0
  70. {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,317 @@
1
+ from cartography.rules.spec.model import Fact
2
+ from cartography.rules.spec.model import Module
3
+ from cartography.rules.spec.model import Requirement
4
+
5
+ # AWS
6
+ _aws_account_manipulation_permissions = Fact(
7
+ id="aws_account_manipulation_permissions",
8
+ name="IAM Principals with Account Creation and Modification Permissions",
9
+ description=(
10
+ "AWS IAM users and roles with permissions to create, modify, or delete IAM "
11
+ "accounts and their associated policies."
12
+ ),
13
+ cypher_query="""
14
+ MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
15
+ MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
16
+ WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
17
+ AND NOT principal.name CONTAINS 'QuickSetup'
18
+ AND principal.name <> 'OrganizationAccountAccessRole'
19
+ AND stmt.effect = 'Allow'
20
+ WITH a, principal, stmt,
21
+ // Return labels that are not the general "AWSPrincipal" label
22
+ [label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
23
+ // Define the list of IAM actions to match on
24
+ [p IN ['iam:Create','iam:Attach','iam:Put','iam:Update','iam:Add'] |
25
+ p] AS patterns
26
+ WITH a, principal, principal_type, stmt,
27
+ // Filter on the desired IAM actions
28
+ [action IN stmt.action
29
+ WHERE ANY(prefix IN patterns WHERE action STARTS WITH prefix)
30
+ OR action = 'iam:*'
31
+ OR action = '*'
32
+ ] AS matched_actions
33
+ // Return only statement actions that we matched on
34
+ WHERE size(matched_actions) > 0
35
+ UNWIND matched_actions AS action
36
+ RETURN DISTINCT a.name AS account,
37
+ principal.name AS principal_name,
38
+ principal.arn AS principal_arn,
39
+ principal_type,
40
+ collect(action) as action,
41
+ stmt.resource AS resource
42
+ ORDER BY account, principal_name
43
+ """,
44
+ cypher_visual_query="""
45
+ MATCH p = (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
46
+ MATCH p1 = (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
47
+ WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
48
+ AND NOT principal.name CONTAINS 'QuickSetup'
49
+ AND NOT principal.name = 'OrganizationAccountAccessRole'
50
+ AND stmt.effect = 'Allow'
51
+ AND ANY(action IN stmt.action WHERE
52
+ action STARTS WITH 'iam:Create'
53
+ OR action STARTS WITH 'iam:Attach'
54
+ OR action STARTS WITH 'iam:Put'
55
+ OR action STARTS WITH 'iam:Update'
56
+ OR action STARTS WITH 'iam:Add'
57
+ OR action = 'iam:*'
58
+ OR action = '*'
59
+ )
60
+ RETURN *
61
+ """,
62
+ module=Module.AWS,
63
+ )
64
+
65
+ _aws_trust_relationship_manipulation = Fact(
66
+ id="aws_trust_relationship_manipulation",
67
+ name="Roles with Cross-Account Trust Relationship Modification Capabilities",
68
+ description=(
69
+ "AWS IAM principals with permissions to modify role trust policies "
70
+ "(specifically AssumeRolePolicyDocuments)."
71
+ ),
72
+ cypher_query="""
73
+ MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
74
+ MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
75
+ OPTIONAL MATCH (groupmember:AWSUser)
76
+ WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
77
+ AND NOT principal.name CONTAINS 'QuickSetup'
78
+ AND principal.name <> 'OrganizationAccountAccessRole'
79
+ AND stmt.effect = 'Allow'
80
+ WITH a, principal, stmt,
81
+ [label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
82
+ ['iam:UpdateAssumeRolePolicy','iam:CreateRole'] AS patterns
83
+ WITH a, principal, principal_type, stmt,
84
+ [action IN stmt.action
85
+ WHERE ANY(p IN patterns WHERE action = p)
86
+ OR action = 'iam:*' OR action = '*'
87
+ ] AS matched_actions
88
+ WHERE size(matched_actions) > 0
89
+ UNWIND matched_actions AS action
90
+ RETURN DISTINCT a.name AS account,
91
+ principal.name AS principal_name,
92
+ principal.arn AS principal_arn,
93
+ principal_type,
94
+ collect(distinct action) as action,
95
+ stmt.resource AS resource
96
+ ORDER BY account, principal_name
97
+ """,
98
+ cypher_visual_query="""
99
+ MATCH p = (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
100
+ MATCH p1 = (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
101
+ MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
102
+ WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
103
+ AND principal.name <> 'OrganizationAccountAccessRole'
104
+ AND stmt.effect = 'Allow'
105
+ RETURN *
106
+ """,
107
+ module=Module.AWS,
108
+ )
109
+
110
+ _aws_service_account_manipulation_via_ec2 = Fact(
111
+ id="aws_service_account_manipulation_via_ec2",
112
+ name="Service Resources with Account Manipulation Through Instance Profiles",
113
+ description=(
114
+ "AWS EC2 instances with attached IAM roles that can manipulate other AWS accounts. "
115
+ "Also indicates whether the instance is internet-exposed."
116
+ ),
117
+ cypher_query="""
118
+ MATCH (a:AWSAccount)-[:RESOURCE]->(ec2:EC2Instance)
119
+ MATCH (ec2)-[:INSTANCE_PROFILE]->(profile:AWSInstanceProfile)
120
+ MATCH (profile)-[:ASSOCIATED_WITH]->(role:AWSRole)
121
+ MATCH (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
122
+ WHERE stmt.effect = 'Allow'
123
+ WITH a, ec2, role,
124
+ // Define the list of IAM actions to match on
125
+ ['iam:Create', 'iam:Attach', 'iam:Put', 'iam:Update'] AS patterns,
126
+ // Filter on the desired IAM actions
127
+ [action IN stmt.action
128
+ WHERE ANY(p IN ['iam:Create','iam:Attach','iam:Put','iam:Update', 'iam:Add'] WHERE action STARTS WITH p)
129
+ OR action = 'iam:*'
130
+ OR action = '*'
131
+ ] AS actions
132
+ // For the instances that are internet open, include the SG and rules
133
+ OPTIONAL MATCH (ec2{exposed_internet:True})-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(ip:IpPermissionInbound)
134
+ // Return only statement actions that we matched on
135
+ WHERE size(actions) > 0
136
+ UNWIND actions AS flat_action
137
+ WITH a, ec2, role, sg, ip,
138
+ collect(DISTINCT flat_action) AS actions
139
+ RETURN DISTINCT a.name AS account,
140
+ a.id as account_id,
141
+ ec2.instanceid AS instance_id,
142
+ ec2.exposed_internet AS internet_accessible,
143
+ ec2.publicipaddress as public_ip_address,
144
+ role.name AS role_name,
145
+ collect(actions) as action,
146
+ ip.fromport as from_port,
147
+ ip.toport as to_port
148
+ ORDER BY account, instance_id, internet_accessible, from_port
149
+ """,
150
+ cypher_visual_query="""
151
+ MATCH p = (a:AWSAccount)-[:RESOURCE]->(ec2:EC2Instance)
152
+ MATCH p1 = (ec2)-[:INSTANCE_PROFILE]->(profile:AWSInstanceProfile)
153
+ MATCH p2 = (profile)-[:ASSOCIATED_WITH]->(role:AWSRole)
154
+ MATCH p3 = (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
155
+ WHERE stmt.effect = 'Allow'
156
+ AND ANY(action IN stmt.action WHERE
157
+ action STARTS WITH 'iam:Create'
158
+ OR action STARTS WITH 'iam:Attach'
159
+ OR action STARTS WITH 'iam:Put'
160
+ OR action STARTS WITH 'iam:Update'
161
+ OR action STARTS WITH 'iam:Add'
162
+ OR action = 'iam:*'
163
+ OR action = '*'
164
+ )
165
+ WITH p, p1, p2, p3, ec2
166
+ // Include the SG and rules for the instances that are internet open
167
+ MATCH p4=(ec2{exposed_internet: true})-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(ip:IpPermissionInbound)
168
+ RETURN *
169
+ """,
170
+ module=Module.AWS,
171
+ )
172
+
173
+ _aws_service_account_manipulation_via_lambda = Fact(
174
+ id="aws_service_account_manipulation",
175
+ name="Service Resources with Account Manipulation Through Lambda Roles",
176
+ description=(
177
+ "AWS Lambda functions with IAM roles that can manipulate other AWS accounts."
178
+ ),
179
+ cypher_query="""
180
+ // Find Lambda functions with account manipulation capabilities
181
+ MATCH (a:AWSAccount)-[:RESOURCE]->(lambda:AWSLambda)
182
+ MATCH (lambda)-[:STS_ASSUMEROLE_ALLOW]->(role:AWSRole)
183
+ MATCH (role)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
184
+ WHERE stmt.effect = 'Allow'
185
+ WITH a, lambda, role, stmt,
186
+ // Define the list of IAM actions to match on
187
+ ['iam:Create', 'iam:Attach', 'iam:Put', 'iam:Update'] AS patterns,
188
+ // Filter on the desired IAM actions
189
+ [action IN stmt.action
190
+ WHERE ANY(p IN ['iam:Create', 'iam:Attach', 'iam:Put', 'iam:Update', 'iam:Add'] WHERE action STARTS WITH p)
191
+ OR action = 'iam:*'
192
+ OR action = '*'
193
+ ] AS actions
194
+ // Return only statement actions that we matched on
195
+ WHERE size(actions) > 0
196
+ UNWIND actions AS flat_action
197
+ WITH a, lambda, role, stmt,
198
+ collect(DISTINCT flat_action) AS actions
199
+ RETURN DISTINCT a.name AS account,
200
+ a.id as account_id,
201
+ lambda.arn AS arn,
202
+ lambda.description AS description,
203
+ lambda.anonymous_access AS internet_accessible,
204
+ role.name AS role_name,
205
+ actions
206
+ ORDER BY account, arn, internet_accessible
207
+ """,
208
+ cypher_visual_query="""
209
+ MATCH p = (a:AWSAccount)-[:RESOURCE]->(lambda:AWSLambda)
210
+ MATCH p1 = (lambda)-[:STS_ASSUMEROLE_ALLOW]->(role:AWSRole)
211
+ MATCH p2 = (role)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
212
+ WHERE stmt.effect = 'Allow'
213
+ AND ANY(action IN stmt.action WHERE
214
+ action STARTS WITH 'iam:Create'
215
+ OR action STARTS WITH 'iam:Attach'
216
+ OR action STARTS WITH 'iam:Put'
217
+ OR action STARTS WITH 'iam:Update'
218
+ OR action STARTS WITH 'iam:Add'
219
+ OR action = 'iam:*'
220
+ OR action = '*'
221
+ )
222
+ RETURN *
223
+ """,
224
+ module=Module.AWS,
225
+ )
226
+
227
+ _aws_policy_manipulation_capabilities = Fact(
228
+ id="aws_policy_manipulation_capabilities",
229
+ name="Principals with IAM Policy Creation and Modification Capabilities",
230
+ description=(
231
+ "AWS IAM principals that can create, modify, or attach IAM policies to other principals. "
232
+ ),
233
+ cypher_query="""
234
+ MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
235
+ MATCH (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
236
+ WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
237
+ AND NOT principal.name CONTAINS 'QuickSetup'
238
+ AND principal.name <> 'OrganizationAccountAccessRole'
239
+ AND stmt.effect = 'Allow'
240
+
241
+ WITH a, principal, stmt,
242
+ // Return labels that are not the general "AWSPrincipal" label
243
+ [label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
244
+ // Define the list of IAM actions to match on
245
+ [p IN
246
+ ['iam:CreatePolicy', 'iam:CreatePolicyVersion', 'iam:AttachUserPolicy', 'iam:AttachRolePolicy', 'iam:AttachGroupPolicy',
247
+ 'iam:AttachRolePolicy', 'iam:AttachGroupPolicy', 'iam:DetachUserPolicy', 'iam:DetachRolePolicy', 'iam:DetachGroupPolicy',
248
+ 'iam:PutUserPolicy', 'iam:PutRolePolicy', 'iam:PutGroupPolicy'] |
249
+ p] AS patterns
250
+
251
+ // Return only statement actions that we matched on
252
+ WITH a, principal, principal_type, stmt,
253
+ [action IN stmt.action
254
+ WHERE ANY(p IN patterns WHERE action = p)
255
+ OR action = 'iam:*' OR action = '*'
256
+ ] AS matched_actions
257
+ WHERE size(matched_actions) > 0
258
+ UNWIND matched_actions AS action
259
+ RETURN DISTINCT a.name AS account,
260
+ principal.name AS principal_name,
261
+ principal.arn AS principal_arn,
262
+ principal_type,
263
+ collect(action) as action,
264
+ stmt.resource AS resource
265
+ ORDER BY account, principal_name
266
+ """,
267
+ cypher_visual_query="""
268
+ MATCH p1=(a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
269
+ MATCH p2=(principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
270
+ WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
271
+ AND NOT principal.name CONTAINS 'QuickSetup'
272
+ AND principal.name <> 'OrganizationAccountAccessRole'
273
+ AND stmt.effect = 'Allow'
274
+ AND ANY(action IN stmt.action WHERE
275
+ action CONTAINS 'iam:CreatePolicy' OR action CONTAINS 'iam:CreatePolicyVersion'
276
+ OR action CONTAINS 'iam:AttachUserPolicy' OR action CONTAINS 'iam:AttachRolePolicy'
277
+ OR action CONTAINS 'iam:AttachGroupPolicy' OR action CONTAINS 'iam:DetachUserPolicy'
278
+ OR action CONTAINS 'iam:DetachRolePolicy' OR action CONTAINS 'iam:DetachGroupPolicy'
279
+ OR action CONTAINS 'iam:PutUserPolicy' OR action CONTAINS 'iam:PutRolePolicy'
280
+ OR action CONTAINS 'iam:PutGroupPolicy' OR action = 'iam:*' OR action = '*'
281
+ )
282
+ RETURN *
283
+ """,
284
+ module=Module.AWS,
285
+ )
286
+
287
+
288
+ t1098 = Requirement(
289
+ id="t1098",
290
+ name="Account Manipulation",
291
+ description=(
292
+ "Adversaries may manipulate accounts to maintain or elevate access to victim systems. "
293
+ "Activity that subverts security policies. For example in cloud this is "
294
+ "updating IAM policies or adding new global admins."
295
+ ),
296
+ target_assets="Identities that can manipulate other identities",
297
+ facts=(
298
+ # AWS
299
+ _aws_account_manipulation_permissions,
300
+ _aws_trust_relationship_manipulation,
301
+ _aws_service_account_manipulation_via_ec2,
302
+ _aws_service_account_manipulation_via_lambda,
303
+ _aws_policy_manipulation_capabilities,
304
+ ),
305
+ requirement_url="https://attack.mitre.org/techniques/T1098/",
306
+ attributes={
307
+ "tactic": "persistence,privilege_escalation",
308
+ "technique_id": "T1098",
309
+ "services": [
310
+ "iam",
311
+ "sts",
312
+ "ec2",
313
+ "lambda",
314
+ ],
315
+ "providers": ["AWS"],
316
+ },
317
+ )
@@ -116,6 +116,7 @@ t1190 = Requirement(
116
116
  id="t1190",
117
117
  name="Exploit Public-Facing Application",
118
118
  description="Adversaries may attempt to take advantage of a weakness in an Internet-facing computer or program using software, data, or commands in order to cause unintended or unanticipated behavior.",
119
+ target_assets="Compute and storage resources that are accessible from the public internet",
119
120
  facts=(
120
121
  # AWS
121
122
  _aws_ec2_instance_internet_exposed,
@@ -58,9 +58,21 @@ class Requirement:
58
58
  """
59
59
 
60
60
  id: str
61
+ """A unique identifier for the requirement, e.g. T1098 in MITRE ATT&CK."""
61
62
  name: str
63
+ """A brief name for the requirement, e.g. "Account Manipulation"."""
62
64
  description: str
65
+ """A brief description of the requirement."""
66
+ target_assets: str
67
+ """
68
+ A short description of the assets that this requirement is related to. E.g. "Cloud
69
+ identities that can manipulate other identities". This field is used as
70
+ documentation: `description` tells us information about the requirement;
71
+ `target_assets` tells us what specific objects in cartography we will search for to
72
+ find Facts related to the requirement.
73
+ """
63
74
  facts: tuple[Fact, ...]
75
+ """The facts that are related to this requirement."""
64
76
  attributes: dict[str, Any] | None = None
65
77
  """
66
78
  Metadata attributes for the requirement. Example:
@@ -74,6 +86,7 @@ class Requirement:
74
86
  ```
75
87
  """
76
88
  requirement_url: str | None = None
89
+ """A URL reference to the requirement in the framework, e.g. https://attack.mitre.org/techniques/T1098/"""
77
90
 
78
91
 
79
92
  @dataclass(frozen=True)
cartography/sync.py CHANGED
@@ -52,7 +52,7 @@ from cartography.util import STATUS_SUCCESS
52
52
  logger = logging.getLogger(__name__)
53
53
 
54
54
 
55
- TOP_LEVEL_MODULES = OrderedDict(
55
+ TOP_LEVEL_MODULES: OrderedDict[str, Callable[..., None]] = OrderedDict(
56
56
  { # preserve order so that the default sync always runs `analysis` at the very end
57
57
  "create-indexes": cartography.intel.create_indexes.run,
58
58
  "airbyte": cartography.intel.airbyte.start_airbyte_ingestion,
cartography/util.py CHANGED
@@ -153,6 +153,9 @@ def merge_module_sync_metadata(
153
153
  :param synced_type: The sub-module's type
154
154
  :param update_tag: Timestamp used to determine data freshness
155
155
  """
156
+ # Import here to avoid circular import with cartography.client.core.tx
157
+ from cartography.client.core.tx import run_write_query
158
+
156
159
  template = Template(
157
160
  """
158
161
  MERGE (n:ModuleSyncMetadata{id:'${group_type}_${group_id}_${synced_type}'})
@@ -164,7 +167,8 @@ def merge_module_sync_metadata(
164
167
  n.lastupdated=$UPDATE_TAG
165
168
  """,
166
169
  )
167
- neo4j_session.run(
170
+ run_write_query(
171
+ neo4j_session,
168
172
  template.safe_substitute(
169
173
  group_type=group_type,
170
174
  group_id=group_id,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cartography
3
- Version: 0.116.1
3
+ Version: 0.118.0
4
4
  Summary: Explore assets and their relationships across your technical infrastructure.
5
5
  Maintainer: Cartography Contributors
6
6
  License-Expression: Apache-2.0
@@ -42,6 +42,7 @@ Requires-Dist: python-digitalocean>=1.16.0
42
42
  Requires-Dist: adal>=1.2.4
43
43
  Requires-Dist: azure-cli-core>=2.26.0
44
44
  Requires-Dist: azure-mgmt-compute>=5.0.0
45
+ Requires-Dist: azure-mgmt-containerinstance>=10.0.0
45
46
  Requires-Dist: azure-mgmt-resource>=10.2.0
46
47
  Requires-Dist: azure-mgmt-cosmosdb>=6.0.0
47
48
  Requires-Dist: azure-mgmt-web>=7.0.0
@@ -58,7 +59,7 @@ Requires-Dist: python-dateutil
58
59
  Requires-Dist: xmltodict
59
60
  Requires-Dist: duo-client
60
61
  Requires-Dist: cloudflare<5.0.0,>=4.1.0
61
- Requires-Dist: scaleway>=2.9.0
62
+ Requires-Dist: scaleway>=2.10.0
62
63
  Requires-Dist: google-cloud-resource-manager>=1.14.2
63
64
  Requires-Dist: types-aiobotocore-ecr
64
65
  Requires-Dist: typer>=0.9.0
@@ -88,7 +89,7 @@ You can learn more about the story behind Cartography in our [presentation at BS
88
89
 
89
90
  ## Supported platforms
90
91
  - [Airbyte](https://cartography-cncf.github.io/cartography/modules/airbyte/index.html) - Organization, Workspace, User, Source, Destination, Connection, Tag, Stream
91
- - [Amazon Web Services](https://cartography-cncf.github.io/cartography/modules/aws/index.html) - ACM, API Gateway, CloudWatch, CodeBuild, Config, Cognito, EC2, ECS, ECR (including image layers), EFS, Elasticsearch, Elastic Kubernetes Service (EKS), DynamoDB, Glue, GuardDuty, IAM, Inspector, KMS, Lambda, RDS, Redshift, Route53, S3, Secrets Manager(Secret Versions), Security Hub, SNS, SQS, SSM, STS, Tags
92
+ - [Amazon Web Services](https://cartography-cncf.github.io/cartography/modules/aws/index.html) - ACM, API Gateway, CloudWatch, CodeBuild, Config, Cognito, EC2, ECS, ECR (including multi-arch images, image layers, and attestations), EFS, Elasticsearch, Elastic Kubernetes Service (EKS), DynamoDB, Glue, GuardDuty, IAM, Inspector, KMS, Lambda, RDS, Redshift, Route53, S3, Secrets Manager(Secret Versions), Security Hub, SNS, SQS, SSM, STS, Tags
92
93
  - [Anthropic](https://cartography-cncf.github.io/cartography/modules/anthropic/index.html) - Organization, ApiKey, User, Workspace
93
94
  - [BigFix](https://cartography-cncf.github.io/cartography/modules/bigfix/index.html) - Computers
94
95
  - [Cloudflare](https://cartography-cncf.github.io/cartography/modules/cloudflare/index.html) - Account, Role, Member, Zone, DNSRecord
@@ -102,7 +103,7 @@ You can learn more about the story behind Cartography in our [presentation at BS
102
103
  - [Keycloak](https://cartography-cncf.github.io/cartography/modules/keycloak/index.html) - Realms, Users, Groups, Roles, Scopes, Clients, IdentityProviders, Authentication Flows, Authentication Executions, Organizations, Organization Domains
103
104
  - [Kubernetes](https://cartography-cncf.github.io/cartography/modules/kubernetes/index.html) - Cluster, Namespace, Service, Pod, Container, ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding, OIDCProvider
104
105
  - [Lastpass](https://cartography-cncf.github.io/cartography/modules/lastpass/index.html) - users
105
- - [Microsoft Azure](https://cartography-cncf.github.io/cartography/modules/azure/index.html) - App Service, CosmosDB, Functions, Logic Apps, Resource Group, SQL, Storage, Virtual Machine
106
+ - [Microsoft Azure](https://cartography-cncf.github.io/cartography/modules/azure/index.html) - App Service, Container Instance, CosmosDB, Functions, Logic Apps, Resource Group, SQL, Storage, Virtual Machine
106
107
  - [Microsoft Entra ID](https://cartography-cncf.github.io/cartography/modules/entra/index.html) - Users, Groups, Applications, OUs, App Roles, federation to AWS Identity Center
107
108
  - [NIST CVE](https://cartography-cncf.github.io/cartography/modules/cve/index.html) - Common Vulnerabilities and Exposures (CVE) data from NIST database
108
109
  - [Okta](https://cartography-cncf.github.io/cartography/modules/okta/index.html) - users, groups, organizations, roles, applications, factors, trusted origins, reply URIs, federation to AWS roles, federation to AWS Identity Center