cartography 0.113.0__py3-none-any.whl → 0.115.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.
- cartography/_version.py +2 -2
- cartography/cli.py +10 -2
- cartography/client/core/tx.py +11 -0
- cartography/config.py +4 -0
- cartography/data/indexes.cypher +0 -27
- cartography/intel/aws/config.py +7 -3
- cartography/intel/aws/ecr.py +9 -9
- cartography/intel/aws/iam.py +741 -492
- cartography/intel/aws/identitycenter.py +240 -13
- cartography/intel/aws/lambda_function.py +69 -2
- cartography/intel/aws/organizations.py +10 -9
- cartography/intel/aws/permission_relationships.py +7 -17
- cartography/intel/aws/redshift.py +9 -4
- cartography/intel/aws/route53.py +53 -3
- cartography/intel/aws/securityhub.py +3 -1
- cartography/intel/azure/__init__.py +24 -0
- cartography/intel/azure/app_service.py +105 -0
- cartography/intel/azure/functions.py +124 -0
- cartography/intel/azure/logic_apps.py +101 -0
- cartography/intel/create_indexes.py +2 -1
- cartography/intel/dns.py +5 -2
- cartography/intel/entra/__init__.py +31 -0
- cartography/intel/entra/app_role_assignments.py +277 -0
- cartography/intel/entra/applications.py +4 -238
- cartography/intel/entra/federation/__init__.py +0 -0
- cartography/intel/entra/federation/aws_identity_center.py +77 -0
- cartography/intel/entra/service_principals.py +217 -0
- cartography/intel/gcp/__init__.py +136 -440
- cartography/intel/gcp/clients.py +65 -0
- cartography/intel/gcp/compute.py +18 -44
- cartography/intel/gcp/crm/__init__.py +0 -0
- cartography/intel/gcp/crm/folders.py +108 -0
- cartography/intel/gcp/crm/orgs.py +65 -0
- cartography/intel/gcp/crm/projects.py +109 -0
- cartography/intel/gcp/dns.py +2 -1
- cartography/intel/gcp/gke.py +72 -113
- cartography/intel/github/__init__.py +41 -0
- cartography/intel/github/commits.py +423 -0
- cartography/intel/github/repos.py +76 -45
- cartography/intel/gsuite/api.py +17 -4
- cartography/intel/okta/applications.py +9 -4
- cartography/intel/okta/awssaml.py +5 -2
- cartography/intel/okta/factors.py +3 -1
- cartography/intel/okta/groups.py +5 -2
- cartography/intel/okta/organization.py +3 -1
- cartography/intel/okta/origins.py +3 -1
- cartography/intel/okta/roles.py +5 -2
- cartography/intel/okta/users.py +3 -1
- cartography/models/aws/iam/access_key.py +103 -0
- cartography/models/aws/iam/account_role.py +24 -0
- cartography/models/aws/iam/federated_principal.py +60 -0
- cartography/models/aws/iam/group.py +60 -0
- cartography/models/aws/iam/group_membership.py +26 -0
- cartography/models/aws/iam/inline_policy.py +78 -0
- cartography/models/aws/iam/managed_policy.py +51 -0
- cartography/models/aws/iam/policy_statement.py +57 -0
- cartography/models/aws/iam/role.py +83 -0
- cartography/models/aws/iam/root_principal.py +52 -0
- cartography/models/aws/iam/service_principal.py +30 -0
- cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
- cartography/models/aws/iam/user.py +54 -0
- cartography/models/aws/identitycenter/awspermissionset.py +24 -1
- cartography/models/aws/identitycenter/awssogroup.py +70 -0
- cartography/models/aws/identitycenter/awsssouser.py +37 -1
- cartography/models/aws/lambda_function/lambda_function.py +2 -0
- cartography/models/azure/__init__.py +0 -0
- cartography/models/azure/app_service.py +59 -0
- cartography/models/azure/function_app.py +59 -0
- cartography/models/azure/logic_apps.py +56 -0
- cartography/models/entra/entra_user_to_aws_sso.py +41 -0
- cartography/models/entra/service_principal.py +104 -0
- cartography/models/entra/user.py +18 -0
- cartography/models/gcp/compute/subnet.py +74 -0
- cartography/models/gcp/crm/__init__.py +0 -0
- cartography/models/gcp/crm/folders.py +98 -0
- cartography/models/gcp/crm/organizations.py +21 -0
- cartography/models/gcp/crm/projects.py +100 -0
- cartography/models/gcp/gke.py +69 -0
- cartography/models/github/commits.py +63 -0
- {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/METADATA +8 -5
- {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/RECORD +85 -56
- cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
- cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
- cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
- cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
- cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
- cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
- cartography/intel/gcp/crm.py +0 -355
- {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/WHEEL +0 -0
- {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/top_level.txt +0 -0
cartography/intel/gsuite/api.py
CHANGED
|
@@ -6,6 +6,7 @@ import neo4j
|
|
|
6
6
|
from googleapiclient.discovery import Resource
|
|
7
7
|
from googleapiclient.errors import HttpError
|
|
8
8
|
|
|
9
|
+
from cartography.client.core.tx import run_write_query
|
|
9
10
|
from cartography.util import run_cleanup_job
|
|
10
11
|
from cartography.util import timeit
|
|
11
12
|
|
|
@@ -171,7 +172,12 @@ def load_gsuite_groups(
|
|
|
171
172
|
g.lastupdated = $UpdateTag
|
|
172
173
|
"""
|
|
173
174
|
logger.info(f"Ingesting {len(groups)} gsuite groups")
|
|
174
|
-
|
|
175
|
+
run_write_query(
|
|
176
|
+
neo4j_session,
|
|
177
|
+
ingestion_qry,
|
|
178
|
+
GroupData=groups,
|
|
179
|
+
UpdateTag=gsuite_update_tag,
|
|
180
|
+
)
|
|
175
181
|
|
|
176
182
|
|
|
177
183
|
@timeit
|
|
@@ -215,7 +221,12 @@ def load_gsuite_users(
|
|
|
215
221
|
u.lastupdated = $UpdateTag
|
|
216
222
|
"""
|
|
217
223
|
logger.info(f"Ingesting {len(users)} gsuite users")
|
|
218
|
-
|
|
224
|
+
run_write_query(
|
|
225
|
+
neo4j_session,
|
|
226
|
+
ingestion_qry,
|
|
227
|
+
UserData=users,
|
|
228
|
+
UpdateTag=gsuite_update_tag,
|
|
229
|
+
)
|
|
219
230
|
|
|
220
231
|
|
|
221
232
|
@timeit
|
|
@@ -234,7 +245,8 @@ def load_gsuite_members(
|
|
|
234
245
|
SET
|
|
235
246
|
r.lastupdated = $UpdateTag
|
|
236
247
|
"""
|
|
237
|
-
|
|
248
|
+
run_write_query(
|
|
249
|
+
neo4j_session,
|
|
238
250
|
ingestion_qry,
|
|
239
251
|
MemberData=members,
|
|
240
252
|
GroupID=group.get("id"),
|
|
@@ -249,7 +261,8 @@ def load_gsuite_members(
|
|
|
249
261
|
SET
|
|
250
262
|
r.lastupdated = $UpdateTag
|
|
251
263
|
"""
|
|
252
|
-
|
|
264
|
+
run_write_query(
|
|
265
|
+
neo4j_session,
|
|
253
266
|
membership_qry,
|
|
254
267
|
MemberData=members,
|
|
255
268
|
GroupID=group.get("id"),
|
|
@@ -10,6 +10,7 @@ import neo4j
|
|
|
10
10
|
from okta.framework.ApiClient import ApiClient
|
|
11
11
|
from okta.framework.OktaError import OktaError
|
|
12
12
|
|
|
13
|
+
from cartography.client.core.tx import run_write_query
|
|
13
14
|
from cartography.intel.okta.utils import check_rate_limit
|
|
14
15
|
from cartography.intel.okta.utils import create_api_client
|
|
15
16
|
from cartography.intel.okta.utils import is_last_page
|
|
@@ -293,7 +294,8 @@ def _load_okta_applications(
|
|
|
293
294
|
SET org_r.lastupdated = $okta_update_tag
|
|
294
295
|
"""
|
|
295
296
|
|
|
296
|
-
|
|
297
|
+
run_write_query(
|
|
298
|
+
neo4j_session,
|
|
297
299
|
ingest_statement,
|
|
298
300
|
ORG_ID=okta_org_id,
|
|
299
301
|
APP_LIST=app_list,
|
|
@@ -327,7 +329,8 @@ def _load_application_user(
|
|
|
327
329
|
SET r.lastupdated = $okta_update_tag
|
|
328
330
|
"""
|
|
329
331
|
|
|
330
|
-
|
|
332
|
+
run_write_query(
|
|
333
|
+
neo4j_session,
|
|
331
334
|
ingest,
|
|
332
335
|
APP_ID=app_id,
|
|
333
336
|
USER_LIST=user_list,
|
|
@@ -361,7 +364,8 @@ def _load_application_group(
|
|
|
361
364
|
SET r.lastupdated = $okta_update_tag
|
|
362
365
|
"""
|
|
363
366
|
|
|
364
|
-
|
|
367
|
+
run_write_query(
|
|
368
|
+
neo4j_session,
|
|
365
369
|
ingest,
|
|
366
370
|
APP_ID=app_id,
|
|
367
371
|
GROUP_LIST=group_list,
|
|
@@ -400,7 +404,8 @@ def _load_application_reply_urls(
|
|
|
400
404
|
SET r.lastupdated = $okta_update_tag
|
|
401
405
|
"""
|
|
402
406
|
|
|
403
|
-
|
|
407
|
+
run_write_query(
|
|
408
|
+
neo4j_session,
|
|
404
409
|
ingest,
|
|
405
410
|
APP_ID=app_id,
|
|
406
411
|
URL_LIST=reply_urls,
|
|
@@ -10,6 +10,7 @@ import neo4j
|
|
|
10
10
|
|
|
11
11
|
from cartography.client.core.tx import read_list_of_dicts_tx
|
|
12
12
|
from cartography.client.core.tx import read_single_value_tx
|
|
13
|
+
from cartography.client.core.tx import run_write_query
|
|
13
14
|
from cartography.util import timeit
|
|
14
15
|
|
|
15
16
|
AccountRole = namedtuple("AccountRole", ["account_id", "role_name"])
|
|
@@ -116,7 +117,8 @@ def _load_okta_group_to_aws_roles(
|
|
|
116
117
|
SET r.lastupdated = $okta_update_tag
|
|
117
118
|
"""
|
|
118
119
|
|
|
119
|
-
|
|
120
|
+
run_write_query(
|
|
121
|
+
neo4j_session,
|
|
120
122
|
ingest_statement,
|
|
121
123
|
GROUP_TO_ROLE=group_to_role,
|
|
122
124
|
okta_update_tag=okta_update_tag,
|
|
@@ -140,7 +142,8 @@ def _load_human_can_assume_role(
|
|
|
140
142
|
SET r.lastupdated = $okta_update_tag
|
|
141
143
|
"""
|
|
142
144
|
|
|
143
|
-
|
|
145
|
+
run_write_query(
|
|
146
|
+
neo4j_session,
|
|
144
147
|
ingest_statement,
|
|
145
148
|
okta_update_tag=okta_update_tag,
|
|
146
149
|
)
|
|
@@ -8,6 +8,7 @@ from okta import FactorsClient
|
|
|
8
8
|
from okta.framework.OktaError import OktaError
|
|
9
9
|
from okta.models.factor.Factor import Factor
|
|
10
10
|
|
|
11
|
+
from cartography.client.core.tx import run_write_query
|
|
11
12
|
from cartography.intel.okta.sync_state import OktaSyncState
|
|
12
13
|
from cartography.util import timeit
|
|
13
14
|
|
|
@@ -130,7 +131,8 @@ def _load_user_factors(
|
|
|
130
131
|
SET r.lastupdated = $okta_update_tag
|
|
131
132
|
"""
|
|
132
133
|
|
|
133
|
-
|
|
134
|
+
run_write_query(
|
|
135
|
+
neo4j_session,
|
|
134
136
|
ingest,
|
|
135
137
|
USER_ID=user_id,
|
|
136
138
|
FACTOR_LIST=factors,
|
cartography/intel/okta/groups.py
CHANGED
|
@@ -11,6 +11,7 @@ from okta.framework.OktaError import OktaError
|
|
|
11
11
|
from okta.framework.PagedResults import PagedResults
|
|
12
12
|
from okta.models.usergroup import UserGroup
|
|
13
13
|
|
|
14
|
+
from cartography.client.core.tx import run_write_query
|
|
14
15
|
from cartography.intel.okta.sync_state import OktaSyncState
|
|
15
16
|
from cartography.intel.okta.utils import check_rate_limit
|
|
16
17
|
from cartography.intel.okta.utils import create_api_client
|
|
@@ -204,7 +205,8 @@ def _load_okta_groups(
|
|
|
204
205
|
SET org_r.lastupdated = $okta_update_tag
|
|
205
206
|
"""
|
|
206
207
|
|
|
207
|
-
|
|
208
|
+
run_write_query(
|
|
209
|
+
neo4j_session,
|
|
208
210
|
ingest_statement,
|
|
209
211
|
ORG_ID=okta_org_id,
|
|
210
212
|
GROUP_LIST=group_list,
|
|
@@ -251,7 +253,8 @@ def load_okta_group_members(
|
|
|
251
253
|
SET r.lastupdated = $okta_update_tag
|
|
252
254
|
"""
|
|
253
255
|
logging.info(f"Loading {len(member_list)} members of group {group_id}")
|
|
254
|
-
|
|
256
|
+
run_write_query(
|
|
257
|
+
neo4j_session,
|
|
255
258
|
ingest,
|
|
256
259
|
GROUP_ID=group_id,
|
|
257
260
|
MEMBER_LIST=member_list,
|
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
|
|
4
4
|
import neo4j
|
|
5
5
|
|
|
6
|
+
from cartography.client.core.tx import run_write_query
|
|
6
7
|
from cartography.util import timeit
|
|
7
8
|
|
|
8
9
|
logger = logging.getLogger(__name__)
|
|
@@ -27,7 +28,8 @@ def create_okta_organization(
|
|
|
27
28
|
SET org.lastupdated = $okta_update_tag
|
|
28
29
|
"""
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
run_write_query(
|
|
32
|
+
neo4j_session,
|
|
31
33
|
ingest,
|
|
32
34
|
ORG_NAME=organization,
|
|
33
35
|
okta_update_tag=okta_update_tag,
|
|
@@ -7,6 +7,7 @@ from typing import List
|
|
|
7
7
|
import neo4j
|
|
8
8
|
from okta.framework.ApiClient import ApiClient
|
|
9
9
|
|
|
10
|
+
from cartography.client.core.tx import run_write_query
|
|
10
11
|
from cartography.intel.okta.utils import create_api_client
|
|
11
12
|
from cartography.util import timeit
|
|
12
13
|
|
|
@@ -96,7 +97,8 @@ def _load_trusted_origins(
|
|
|
96
97
|
SET r.lastupdated = $okta_update_tag
|
|
97
98
|
"""
|
|
98
99
|
|
|
99
|
-
|
|
100
|
+
run_write_query(
|
|
101
|
+
neo4j_session,
|
|
100
102
|
ingest,
|
|
101
103
|
ORG_ID=okta_org_id,
|
|
102
104
|
TRUSTED_LIST=trusted_list,
|
cartography/intel/okta/roles.py
CHANGED
|
@@ -7,6 +7,7 @@ from typing import List
|
|
|
7
7
|
import neo4j
|
|
8
8
|
from okta.framework.ApiClient import ApiClient
|
|
9
9
|
|
|
10
|
+
from cartography.client.core.tx import run_write_query
|
|
10
11
|
from cartography.intel.okta.sync_state import OktaSyncState
|
|
11
12
|
from cartography.intel.okta.utils import check_rate_limit
|
|
12
13
|
from cartography.intel.okta.utils import create_api_client
|
|
@@ -117,7 +118,8 @@ def _load_user_role(
|
|
|
117
118
|
SET r2.lastupdated = $okta_update_tag
|
|
118
119
|
"""
|
|
119
120
|
|
|
120
|
-
|
|
121
|
+
run_write_query(
|
|
122
|
+
neo4j_session,
|
|
121
123
|
ingest,
|
|
122
124
|
USER_ID=user_id,
|
|
123
125
|
ROLES_DATA=roles_data,
|
|
@@ -149,7 +151,8 @@ def _load_group_role(
|
|
|
149
151
|
SET r2.lastupdated = $okta_update_tag
|
|
150
152
|
"""
|
|
151
153
|
|
|
152
|
-
|
|
154
|
+
run_write_query(
|
|
155
|
+
neo4j_session,
|
|
153
156
|
ingest,
|
|
154
157
|
GROUP_ID=group_id,
|
|
155
158
|
ROLES_DATA=roles_data,
|
cartography/intel/okta/users.py
CHANGED
|
@@ -8,6 +8,7 @@ import neo4j
|
|
|
8
8
|
from okta import UsersClient
|
|
9
9
|
from okta.models.user import User
|
|
10
10
|
|
|
11
|
+
from cartography.client.core.tx import run_write_query
|
|
11
12
|
from cartography.intel.okta.sync_state import OktaSyncState
|
|
12
13
|
from cartography.intel.okta.utils import check_rate_limit
|
|
13
14
|
from cartography.util import timeit
|
|
@@ -174,7 +175,8 @@ def _load_okta_users(
|
|
|
174
175
|
SET h.lastupdated = $okta_update_tag
|
|
175
176
|
"""
|
|
176
177
|
|
|
177
|
-
|
|
178
|
+
run_write_query(
|
|
179
|
+
neo4j_session,
|
|
178
180
|
ingest_statement,
|
|
179
181
|
ORG_ID=okta_org_id,
|
|
180
182
|
USER_LIST=user_list,
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
11
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class AccountAccessKeyNodeProperties(CartographyNodeProperties):
|
|
16
|
+
# Required unique identifier
|
|
17
|
+
id: PropertyRef = PropertyRef("accesskeyid")
|
|
18
|
+
accesskeyid: PropertyRef = PropertyRef("accesskeyid", extra_index=True)
|
|
19
|
+
|
|
20
|
+
# Automatic fields (set by cartography)
|
|
21
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
22
|
+
|
|
23
|
+
# Business fields from AWS IAM access keys
|
|
24
|
+
createdate: PropertyRef = PropertyRef("createdate")
|
|
25
|
+
status: PropertyRef = PropertyRef("status")
|
|
26
|
+
lastuseddate: PropertyRef = PropertyRef("lastuseddate")
|
|
27
|
+
lastusedservice: PropertyRef = PropertyRef("lastusedservice")
|
|
28
|
+
lastusedregion: PropertyRef = PropertyRef("lastusedregion")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class AWSUserToAccountAccessKeyRelProperties(CartographyRelProperties):
|
|
33
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class AWSUserToAccountAccessKeyRel(CartographyRelSchema):
|
|
38
|
+
target_node_label: str = "AccountAccessKey"
|
|
39
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
40
|
+
{
|
|
41
|
+
"accesskeyid": PropertyRef("accesskeyid"),
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
45
|
+
rel_label: str = "AWS_ACCESS_KEY"
|
|
46
|
+
properties: AWSUserToAccountAccessKeyRelProperties = (
|
|
47
|
+
AWSUserToAccountAccessKeyRelProperties()
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass(frozen=True)
|
|
52
|
+
class AccountAccessKeyToAWSUserRelProperties(CartographyRelProperties):
|
|
53
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass(frozen=True)
|
|
57
|
+
class AccountAccessKeyToAWSUserRel(CartographyRelSchema):
|
|
58
|
+
target_node_label: str = "AWSUser"
|
|
59
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
60
|
+
{
|
|
61
|
+
"arn": PropertyRef("user_arn"),
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
65
|
+
rel_label: str = "AWS_ACCESS_KEY"
|
|
66
|
+
properties: AccountAccessKeyToAWSUserRelProperties = (
|
|
67
|
+
AccountAccessKeyToAWSUserRelProperties()
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass(frozen=True)
|
|
72
|
+
class AccountAccessKeyToAWSAccountRelProperties(CartographyRelProperties):
|
|
73
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@dataclass(frozen=True)
|
|
77
|
+
class AccountAccessKeyToAWSAccountRel(CartographyRelSchema):
|
|
78
|
+
target_node_label: str = "AWSAccount"
|
|
79
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
80
|
+
{
|
|
81
|
+
"id": PropertyRef("AWS_ID", set_in_kwargs=True),
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
85
|
+
rel_label: str = "RESOURCE"
|
|
86
|
+
properties: AccountAccessKeyToAWSAccountRelProperties = (
|
|
87
|
+
AccountAccessKeyToAWSAccountRelProperties()
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@dataclass(frozen=True)
|
|
92
|
+
class AccountAccessKeySchema(CartographyNodeSchema):
|
|
93
|
+
label: str = "AccountAccessKey"
|
|
94
|
+
properties: AccountAccessKeyNodeProperties = AccountAccessKeyNodeProperties()
|
|
95
|
+
sub_resource_relationship: AccountAccessKeyToAWSAccountRel = (
|
|
96
|
+
AccountAccessKeyToAWSAccountRel()
|
|
97
|
+
)
|
|
98
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
99
|
+
[
|
|
100
|
+
AccountAccessKeyToAWSUserRel(),
|
|
101
|
+
AccountAccessKeyToAWSAccountRel(),
|
|
102
|
+
]
|
|
103
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True)
|
|
9
|
+
class AWSAccountAWSRoleNodeProperties(CartographyNodeProperties):
|
|
10
|
+
# Required unique identifier
|
|
11
|
+
id: PropertyRef = PropertyRef("id")
|
|
12
|
+
|
|
13
|
+
# Automatic fields (set by cartography)
|
|
14
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class AWSAccountAWSRoleSchema(CartographyNodeSchema):
|
|
19
|
+
"""
|
|
20
|
+
An AWSAccount that was discovered from a trusted principal in an IAM role.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
label: str = "AWSAccount"
|
|
24
|
+
properties: AWSAccountAWSRoleNodeProperties = AWSAccountAWSRoleNodeProperties()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.nodes import ExtraNodeLabels
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
8
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
9
|
+
from cartography.models.core.relationships import LinkDirection
|
|
10
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
11
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class AWSFederatedPrincipalNodeProperties(CartographyNodeProperties):
|
|
16
|
+
# Required unique identifier
|
|
17
|
+
id: PropertyRef = PropertyRef("arn")
|
|
18
|
+
arn: PropertyRef = PropertyRef("arn", extra_index=True)
|
|
19
|
+
|
|
20
|
+
# Automatic fields (set by cartography)
|
|
21
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
22
|
+
|
|
23
|
+
# Business fields from AWS IAM federated principals
|
|
24
|
+
type: PropertyRef = PropertyRef("type")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class AWSFederatedPrincipalToAWSAccountRelProperties(CartographyRelProperties):
|
|
29
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class AWSFederatedPrincipalToAWSAccountRel(CartographyRelSchema):
|
|
34
|
+
target_node_label: str = "AWSAccount"
|
|
35
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
36
|
+
{
|
|
37
|
+
"id": PropertyRef("AWS_ID", set_in_kwargs=True),
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
41
|
+
rel_label: str = "RESOURCE"
|
|
42
|
+
properties: AWSFederatedPrincipalToAWSAccountRelProperties = (
|
|
43
|
+
AWSFederatedPrincipalToAWSAccountRelProperties()
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True)
|
|
48
|
+
class AWSFederatedPrincipalSchema(CartographyNodeSchema):
|
|
49
|
+
"""
|
|
50
|
+
E.g. "arn:aws:iam::123456789012:saml-provider/my-saml-provider".
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
label: str = "AWSFederatedPrincipal"
|
|
54
|
+
properties: AWSFederatedPrincipalNodeProperties = (
|
|
55
|
+
AWSFederatedPrincipalNodeProperties()
|
|
56
|
+
)
|
|
57
|
+
sub_resource_relationship: AWSFederatedPrincipalToAWSAccountRel = (
|
|
58
|
+
AWSFederatedPrincipalToAWSAccountRel()
|
|
59
|
+
)
|
|
60
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(["AWSPrincipal"])
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.aws.iam.group_membership import AWSGroupToAWSUserRel
|
|
4
|
+
from cartography.models.core.common import PropertyRef
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
6
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
7
|
+
from cartography.models.core.nodes import ExtraNodeLabels
|
|
8
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
9
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
10
|
+
from cartography.models.core.relationships import LinkDirection
|
|
11
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
12
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
13
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class AWSGroupNodeProperties(CartographyNodeProperties):
|
|
18
|
+
# Required unique identifier
|
|
19
|
+
id: PropertyRef = PropertyRef("arn")
|
|
20
|
+
arn: PropertyRef = PropertyRef("arn", extra_index=True)
|
|
21
|
+
|
|
22
|
+
# Automatic fields (set by cartography)
|
|
23
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
24
|
+
|
|
25
|
+
# Business fields from AWS IAM groups
|
|
26
|
+
groupid: PropertyRef = PropertyRef("groupid")
|
|
27
|
+
name: PropertyRef = PropertyRef("name")
|
|
28
|
+
path: PropertyRef = PropertyRef("path")
|
|
29
|
+
createdate: PropertyRef = PropertyRef("createdate")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class AWSGroupToAWSAccountRelProperties(CartographyRelProperties):
|
|
34
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(frozen=True)
|
|
38
|
+
class AWSGroupToAWSAccountRel(CartographyRelSchema):
|
|
39
|
+
target_node_label: str = "AWSAccount"
|
|
40
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
41
|
+
{
|
|
42
|
+
"id": PropertyRef("AWS_ID", set_in_kwargs=True),
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
46
|
+
rel_label: str = "RESOURCE"
|
|
47
|
+
properties: AWSGroupToAWSAccountRelProperties = AWSGroupToAWSAccountRelProperties()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass(frozen=True)
|
|
51
|
+
class AWSGroupSchema(CartographyNodeSchema):
|
|
52
|
+
label: str = "AWSGroup"
|
|
53
|
+
properties: AWSGroupNodeProperties = AWSGroupNodeProperties()
|
|
54
|
+
sub_resource_relationship: AWSGroupToAWSAccountRel = AWSGroupToAWSAccountRel()
|
|
55
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
56
|
+
[
|
|
57
|
+
AWSGroupToAWSUserRel(),
|
|
58
|
+
]
|
|
59
|
+
)
|
|
60
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(["AWSPrincipal"])
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
5
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
6
|
+
from cartography.models.core.relationships import LinkDirection
|
|
7
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
8
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class AWSGroupToAWSUserRelProperties(CartographyRelProperties):
|
|
13
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class AWSGroupToAWSUserRel(CartographyRelSchema):
|
|
18
|
+
target_node_label: str = "AWSUser"
|
|
19
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
20
|
+
{
|
|
21
|
+
"arn": PropertyRef("user_arn"),
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
25
|
+
rel_label: str = "MEMBER_AWS_GROUP"
|
|
26
|
+
properties: AWSGroupToAWSUserRelProperties = AWSGroupToAWSUserRelProperties()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.nodes import ExtraNodeLabels
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
8
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
9
|
+
from cartography.models.core.relationships import LinkDirection
|
|
10
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
11
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
12
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class AWSInlinePolicyNodeProperties(CartographyNodeProperties):
|
|
17
|
+
id: PropertyRef = PropertyRef("id")
|
|
18
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
19
|
+
name: PropertyRef = PropertyRef("name")
|
|
20
|
+
type: PropertyRef = PropertyRef("type")
|
|
21
|
+
arn: PropertyRef = PropertyRef("arn", extra_index=True)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class AWSInlinePolicyToAWSPrincipalRelProperties(CartographyRelProperties):
|
|
26
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class AWSInlinePolicyToAWSPrincipalRel(CartographyRelSchema):
|
|
31
|
+
target_node_label: str = "AWSPrincipal"
|
|
32
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
33
|
+
{
|
|
34
|
+
"arn": PropertyRef("principal_arns", one_to_many=True),
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
38
|
+
rel_label: str = "POLICY"
|
|
39
|
+
properties: AWSInlinePolicyToAWSPrincipalRelProperties = (
|
|
40
|
+
AWSInlinePolicyToAWSPrincipalRelProperties()
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass(frozen=True)
|
|
45
|
+
class AWSInlinePolicyToAWSAccountRelProperties(CartographyRelProperties):
|
|
46
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass(frozen=True)
|
|
50
|
+
class AWSInlinePolicyToAWSAccountRel(CartographyRelSchema):
|
|
51
|
+
target_node_label: str = "AWSAccount"
|
|
52
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
53
|
+
{
|
|
54
|
+
"id": PropertyRef("AWS_ID", set_in_kwargs=True),
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
58
|
+
rel_label: str = "RESOURCE"
|
|
59
|
+
properties: AWSInlinePolicyToAWSAccountRelProperties = (
|
|
60
|
+
AWSInlinePolicyToAWSAccountRelProperties()
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass(frozen=True)
|
|
65
|
+
class AWSInlinePolicySchema(CartographyNodeSchema):
|
|
66
|
+
"""
|
|
67
|
+
Inline policies are defined on the given principal and are therefore scoped to that principal's account.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
label: str = "AWSInlinePolicy"
|
|
71
|
+
properties: AWSInlinePolicyNodeProperties = AWSInlinePolicyNodeProperties()
|
|
72
|
+
sub_resource_relationship: AWSInlinePolicyToAWSAccountRel = (
|
|
73
|
+
AWSInlinePolicyToAWSAccountRel()
|
|
74
|
+
)
|
|
75
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
76
|
+
[AWSInlinePolicyToAWSPrincipalRel()]
|
|
77
|
+
)
|
|
78
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(["AWSPolicy"])
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.nodes import ExtraNodeLabels
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
8
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
9
|
+
from cartography.models.core.relationships import LinkDirection
|
|
10
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
11
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
12
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class AWSManagedPolicyNodeProperties(CartographyNodeProperties):
|
|
17
|
+
id: PropertyRef = PropertyRef("id")
|
|
18
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
19
|
+
name: PropertyRef = PropertyRef("name")
|
|
20
|
+
type: PropertyRef = PropertyRef("type")
|
|
21
|
+
arn: PropertyRef = PropertyRef("arn", extra_index=True)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class AWSManagedPolicyToAWSPrincipalRelProperties(CartographyRelProperties):
|
|
26
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class AWSManagedPolicyToAWSPrincipalRel(CartographyRelSchema):
|
|
31
|
+
target_node_label: str = "AWSPrincipal"
|
|
32
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
33
|
+
{
|
|
34
|
+
"arn": PropertyRef("principal_arns", one_to_many=True),
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
38
|
+
rel_label: str = "POLICY"
|
|
39
|
+
properties: AWSManagedPolicyToAWSPrincipalRelProperties = (
|
|
40
|
+
AWSManagedPolicyToAWSPrincipalRelProperties()
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass(frozen=True)
|
|
45
|
+
class AWSManagedPolicySchema(CartographyNodeSchema):
|
|
46
|
+
label: str = "AWSManagedPolicy"
|
|
47
|
+
properties: AWSManagedPolicyNodeProperties = AWSManagedPolicyNodeProperties()
|
|
48
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
49
|
+
[AWSManagedPolicyToAWSPrincipalRel()]
|
|
50
|
+
)
|
|
51
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(["AWSPolicy"])
|