cartography 0.114.0__py3-none-any.whl → 0.116.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 +2 -2
- cartography/client/core/tx.py +12 -1
- cartography/intel/aws/config.py +7 -3
- cartography/intel/aws/ecr.py +9 -9
- cartography/intel/aws/ecr_image_layers.py +664 -0
- cartography/intel/aws/identitycenter.py +240 -13
- cartography/intel/aws/lambda_function.py +69 -2
- cartography/intel/aws/organizations.py +3 -1
- cartography/intel/aws/permission_relationships.py +3 -1
- cartography/intel/aws/redshift.py +9 -4
- cartography/intel/aws/resources.py +2 -0
- cartography/intel/aws/route53.py +53 -3
- cartography/intel/aws/securityhub.py +3 -1
- cartography/intel/azure/__init__.py +16 -0
- cartography/intel/azure/logic_apps.py +101 -0
- cartography/intel/azure/resource_groups.py +82 -0
- cartography/intel/create_indexes.py +2 -1
- cartography/intel/dns.py +5 -2
- cartography/intel/gcp/dns.py +2 -1
- cartography/intel/github/repos.py +3 -6
- 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/ecr/image.py +21 -0
- cartography/models/aws/ecr/image_layer.py +107 -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/logic_apps.py +56 -0
- cartography/models/azure/resource_groups.py +52 -0
- cartography/models/entra/user.py +18 -0
- cartography/rules/README.md +1 -0
- cartography/rules/__init__.py +0 -0
- cartography/rules/cli.py +342 -0
- cartography/rules/data/__init__.py +0 -0
- cartography/rules/data/frameworks/__init__.py +12 -0
- cartography/rules/data/frameworks/mitre_attack/__init__.py +14 -0
- cartography/rules/data/frameworks/mitre_attack/requirements/__init__.py +0 -0
- cartography/rules/data/frameworks/mitre_attack/requirements/t1190_exploit_public_facing_application/__init__.py +135 -0
- cartography/rules/formatters.py +46 -0
- cartography/rules/runners.py +338 -0
- cartography/rules/spec/__init__.py +0 -0
- cartography/rules/spec/model.py +88 -0
- cartography/rules/spec/result.py +46 -0
- {cartography-0.114.0.dist-info → cartography-0.116.0.dist-info}/METADATA +19 -4
- {cartography-0.114.0.dist-info → cartography-0.116.0.dist-info}/RECORD +58 -38
- {cartography-0.114.0.dist-info → cartography-0.116.0.dist-info}/entry_points.txt +1 -0
- {cartography-0.114.0.dist-info → cartography-0.116.0.dist-info}/WHEEL +0 -0
- {cartography-0.114.0.dist-info → cartography-0.116.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.114.0.dist-info → cartography-0.116.0.dist-info}/top_level.txt +0 -0
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,
|
|
@@ -7,6 +7,7 @@ from cartography.models.core.relationships import CartographyRelProperties
|
|
|
7
7
|
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
8
|
from cartography.models.core.relationships import LinkDirection
|
|
9
9
|
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
10
11
|
from cartography.models.core.relationships import TargetNodeMatcher
|
|
11
12
|
|
|
12
13
|
|
|
@@ -16,6 +17,7 @@ class ECRImageNodeProperties(CartographyNodeProperties):
|
|
|
16
17
|
digest: PropertyRef = PropertyRef("imageDigest")
|
|
17
18
|
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
18
19
|
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
20
|
+
layer_diff_ids: PropertyRef = PropertyRef("layer_diff_ids")
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
@dataclass(frozen=True)
|
|
@@ -34,8 +36,27 @@ class ECRImageToAWSAccountRel(CartographyRelSchema):
|
|
|
34
36
|
properties: ECRImageToAWSAccountRelProperties = ECRImageToAWSAccountRelProperties()
|
|
35
37
|
|
|
36
38
|
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class ECRImageHasLayerRelProperties(CartographyRelProperties):
|
|
41
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass(frozen=True)
|
|
45
|
+
class ECRImageHasLayerRel(CartographyRelSchema):
|
|
46
|
+
target_node_label: str = "ECRImageLayer"
|
|
47
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
48
|
+
{"diff_id": PropertyRef("layer_diff_ids", one_to_many=True)},
|
|
49
|
+
)
|
|
50
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
51
|
+
rel_label: str = "HAS_LAYER"
|
|
52
|
+
properties: ECRImageHasLayerRelProperties = ECRImageHasLayerRelProperties()
|
|
53
|
+
|
|
54
|
+
|
|
37
55
|
@dataclass(frozen=True)
|
|
38
56
|
class ECRImageSchema(CartographyNodeSchema):
|
|
39
57
|
label: str = "ECRImage"
|
|
40
58
|
properties: ECRImageNodeProperties = ECRImageNodeProperties()
|
|
41
59
|
sub_resource_relationship: ECRImageToAWSAccountRel = ECRImageToAWSAccountRel()
|
|
60
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
61
|
+
[ECRImageHasLayerRel()],
|
|
62
|
+
)
|
|
@@ -0,0 +1,107 @@
|
|
|
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 ECRImageLayerNodeProperties(CartographyNodeProperties):
|
|
17
|
+
id: PropertyRef = PropertyRef("diff_id")
|
|
18
|
+
diff_id: PropertyRef = PropertyRef("diff_id")
|
|
19
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
20
|
+
is_empty: PropertyRef = PropertyRef("is_empty")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class ECRImageLayerToAWSAccountRelProperties(CartographyRelProperties):
|
|
25
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class ECRImageLayerToAWSAccountRel(CartographyRelSchema):
|
|
30
|
+
target_node_label: str = "AWSAccount"
|
|
31
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
32
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)}
|
|
33
|
+
)
|
|
34
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
35
|
+
rel_label: str = "RESOURCE"
|
|
36
|
+
properties: ECRImageLayerToAWSAccountRelProperties = (
|
|
37
|
+
ECRImageLayerToAWSAccountRelProperties()
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(frozen=True)
|
|
42
|
+
class ECRImageLayerToNextRelProperties(CartographyRelProperties):
|
|
43
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass(frozen=True)
|
|
47
|
+
class ECRImageLayerToNextRel(CartographyRelSchema):
|
|
48
|
+
target_node_label: str = "ECRImageLayer"
|
|
49
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
50
|
+
{"diff_id": PropertyRef("next_diff_ids", one_to_many=True)}
|
|
51
|
+
)
|
|
52
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
53
|
+
rel_label: str = "NEXT"
|
|
54
|
+
properties: ECRImageLayerToNextRelProperties = ECRImageLayerToNextRelProperties()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True)
|
|
58
|
+
class ECRImageLayerHeadOfImageRelProperties(CartographyRelProperties):
|
|
59
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True)
|
|
63
|
+
class ECRImageLayerHeadOfImageRel(CartographyRelSchema):
|
|
64
|
+
target_node_label: str = "ECRImage"
|
|
65
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
66
|
+
{"id": PropertyRef("head_image_ids", one_to_many=True)}
|
|
67
|
+
)
|
|
68
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
69
|
+
rel_label: str = "HEAD"
|
|
70
|
+
properties: ECRImageLayerHeadOfImageRelProperties = (
|
|
71
|
+
ECRImageLayerHeadOfImageRelProperties()
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@dataclass(frozen=True)
|
|
76
|
+
class ECRImageLayerTailOfImageRelProperties(CartographyRelProperties):
|
|
77
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@dataclass(frozen=True)
|
|
81
|
+
class ECRImageLayerTailOfImageRel(CartographyRelSchema):
|
|
82
|
+
target_node_label: str = "ECRImage"
|
|
83
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
84
|
+
{"id": PropertyRef("tail_image_ids", one_to_many=True)}
|
|
85
|
+
)
|
|
86
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
87
|
+
rel_label: str = "TAIL"
|
|
88
|
+
properties: ECRImageLayerTailOfImageRelProperties = (
|
|
89
|
+
ECRImageLayerTailOfImageRelProperties()
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@dataclass(frozen=True)
|
|
94
|
+
class ECRImageLayerSchema(CartographyNodeSchema):
|
|
95
|
+
label: str = "ECRImageLayer"
|
|
96
|
+
properties: ECRImageLayerNodeProperties = ECRImageLayerNodeProperties()
|
|
97
|
+
sub_resource_relationship: ECRImageLayerToAWSAccountRel = (
|
|
98
|
+
ECRImageLayerToAWSAccountRel()
|
|
99
|
+
)
|
|
100
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
101
|
+
[
|
|
102
|
+
ECRImageLayerToNextRel(),
|
|
103
|
+
ECRImageLayerHeadOfImageRel(),
|
|
104
|
+
ECRImageLayerTailOfImageRel(),
|
|
105
|
+
]
|
|
106
|
+
)
|
|
107
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(["ImageLayer"])
|
|
@@ -82,7 +82,7 @@ class AWSPermissionSetToAWSAccountRel(CartographyRelSchema):
|
|
|
82
82
|
@dataclass(frozen=True)
|
|
83
83
|
class RoleAssignmentAllowedByRelProperties(CartographyRelProperties):
|
|
84
84
|
"""
|
|
85
|
-
Properties for the ALLOWED_BY relationship between AWSRole and
|
|
85
|
+
Properties for the ALLOWED_BY relationship between AWSRole and AWSSSO principals.
|
|
86
86
|
"""
|
|
87
87
|
|
|
88
88
|
# Mandatory fields for MatchLinks
|
|
@@ -121,6 +121,29 @@ class RoleAssignmentAllowedByMatchLink(CartographyRelSchema):
|
|
|
121
121
|
)
|
|
122
122
|
|
|
123
123
|
|
|
124
|
+
@dataclass(frozen=True)
|
|
125
|
+
class RoleAssignmentAllowedByGroupMatchLink(CartographyRelSchema):
|
|
126
|
+
"""
|
|
127
|
+
MatchLink schema for ALLOWED_BY relationships from group role assignments.
|
|
128
|
+
Creates relationships like: (AWSRole)-[:ALLOWED_BY]->(AWSSSOGroup)
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
source_node_label: str = "AWSRole"
|
|
132
|
+
source_node_matcher: SourceNodeMatcher = make_source_node_matcher(
|
|
133
|
+
{"arn": PropertyRef("RoleArn")},
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
target_node_label: str = "AWSSSOGroup"
|
|
137
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
138
|
+
{"id": PropertyRef("GroupId")},
|
|
139
|
+
)
|
|
140
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
141
|
+
rel_label: str = "ALLOWED_BY"
|
|
142
|
+
properties: RoleAssignmentAllowedByRelProperties = (
|
|
143
|
+
RoleAssignmentAllowedByRelProperties()
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
124
147
|
@dataclass(frozen=True)
|
|
125
148
|
class AWSPermissionSetSchema(CartographyNodeSchema):
|
|
126
149
|
label: str = "AWSPermissionSet"
|
|
@@ -0,0 +1,70 @@
|
|
|
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 SSOGroupProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef("GroupId")
|
|
17
|
+
display_name: PropertyRef = PropertyRef("DisplayName")
|
|
18
|
+
description: PropertyRef = PropertyRef("Description")
|
|
19
|
+
identity_store_id: PropertyRef = PropertyRef("IdentityStoreId")
|
|
20
|
+
external_id: PropertyRef = PropertyRef("ExternalId", extra_index=True)
|
|
21
|
+
region: PropertyRef = PropertyRef("Region")
|
|
22
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(frozen=True)
|
|
26
|
+
class AWSSSOGroupToAWSAccountRelProperties(CartographyRelProperties):
|
|
27
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class AWSSSOGroupToAWSAccountRel(CartographyRelSchema):
|
|
32
|
+
target_node_label: str = "AWSAccount"
|
|
33
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
34
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)},
|
|
35
|
+
)
|
|
36
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
37
|
+
rel_label: str = "RESOURCE"
|
|
38
|
+
properties: AWSSSOGroupToAWSAccountRelProperties = (
|
|
39
|
+
AWSSSOGroupToAWSAccountRelProperties()
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass(frozen=True)
|
|
44
|
+
class AWSSSOGroupToPermissionSetRelProperties(CartographyRelProperties):
|
|
45
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
class AWSSSOGroupToPermissionSetRel(CartographyRelSchema):
|
|
50
|
+
target_node_label: str = "AWSPermissionSet"
|
|
51
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
52
|
+
{"arn": PropertyRef("AssignedPermissionSets", one_to_many=True)},
|
|
53
|
+
)
|
|
54
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
55
|
+
rel_label: str = "HAS_PERMISSION_SET"
|
|
56
|
+
properties: AWSSSOGroupToPermissionSetRelProperties = (
|
|
57
|
+
AWSSSOGroupToPermissionSetRelProperties()
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass(frozen=True)
|
|
62
|
+
class AWSSSOGroupSchema(CartographyNodeSchema):
|
|
63
|
+
label: str = "AWSSSOGroup"
|
|
64
|
+
properties: SSOGroupProperties = SSOGroupProperties()
|
|
65
|
+
sub_resource_relationship: AWSSSOGroupToAWSAccountRel = AWSSSOGroupToAWSAccountRel()
|
|
66
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
67
|
+
[
|
|
68
|
+
AWSSSOGroupToPermissionSetRel(),
|
|
69
|
+
]
|
|
70
|
+
)
|
|
@@ -14,7 +14,7 @@ from cartography.models.core.relationships import TargetNodeMatcher
|
|
|
14
14
|
|
|
15
15
|
@dataclass(frozen=True)
|
|
16
16
|
class SSOUserProperties(CartographyNodeProperties):
|
|
17
|
-
id: PropertyRef = PropertyRef("UserId"
|
|
17
|
+
id: PropertyRef = PropertyRef("UserId")
|
|
18
18
|
user_name: PropertyRef = PropertyRef("UserName")
|
|
19
19
|
identity_store_id: PropertyRef = PropertyRef("IdentityStoreId")
|
|
20
20
|
external_id: PropertyRef = PropertyRef("ExternalId", extra_index=True)
|
|
@@ -57,6 +57,40 @@ class AWSSSOUserToAWSAccountRel(CartographyRelSchema):
|
|
|
57
57
|
)
|
|
58
58
|
|
|
59
59
|
|
|
60
|
+
@dataclass(frozen=True)
|
|
61
|
+
class AWSSSOUserToSSOGroupRelProperties(CartographyRelProperties):
|
|
62
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass(frozen=True)
|
|
66
|
+
class AWSSSOUserToSSOGroupRel(CartographyRelSchema):
|
|
67
|
+
target_node_label: str = "AWSSSOGroup"
|
|
68
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
69
|
+
{"id": PropertyRef("MemberOfGroups", one_to_many=True)},
|
|
70
|
+
)
|
|
71
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
72
|
+
rel_label: str = "MEMBER_OF_SSO_GROUP"
|
|
73
|
+
properties: AWSSSOUserToSSOGroupRelProperties = AWSSSOUserToSSOGroupRelProperties()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@dataclass(frozen=True)
|
|
77
|
+
class AWSSSOUserToPermissionSetRelProperties(CartographyRelProperties):
|
|
78
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True)
|
|
82
|
+
class AWSSSOUserToPermissionSetRel(CartographyRelSchema):
|
|
83
|
+
target_node_label: str = "AWSPermissionSet"
|
|
84
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
85
|
+
{"arn": PropertyRef("AssignedPermissionSets", one_to_many=True)},
|
|
86
|
+
)
|
|
87
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
88
|
+
rel_label: str = "HAS_PERMISSION_SET"
|
|
89
|
+
properties: AWSSSOUserToPermissionSetRelProperties = (
|
|
90
|
+
AWSSSOUserToPermissionSetRelProperties()
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
60
94
|
@dataclass(frozen=True)
|
|
61
95
|
class AWSSSOUserSchema(CartographyNodeSchema):
|
|
62
96
|
label: str = "AWSSSOUser"
|
|
@@ -66,5 +100,7 @@ class AWSSSOUserSchema(CartographyNodeSchema):
|
|
|
66
100
|
other_relationships: OtherRelationships = OtherRelationships(
|
|
67
101
|
[
|
|
68
102
|
SSOUserToOktaUserRel(),
|
|
103
|
+
AWSSSOUserToSSOGroupRel(),
|
|
104
|
+
AWSSSOUserToPermissionSetRel(),
|
|
69
105
|
],
|
|
70
106
|
)
|
|
@@ -39,6 +39,8 @@ class AWSLambdaNodeProperties(CartographyNodeProperties):
|
|
|
39
39
|
architectures: PropertyRef = PropertyRef("Architectures")
|
|
40
40
|
masterarn: PropertyRef = PropertyRef("MasterArn")
|
|
41
41
|
kmskeyarn: PropertyRef = PropertyRef("KMSKeyArn")
|
|
42
|
+
anonymous_access: PropertyRef = PropertyRef("AnonymousAccess")
|
|
43
|
+
anonymous_actions: PropertyRef = PropertyRef("AnonymousActions")
|
|
42
44
|
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
43
45
|
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
44
46
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
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.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
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# --- Node Definitions ---
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class AzureLogicAppProperties(CartographyNodeProperties):
|
|
19
|
+
id: PropertyRef = PropertyRef("id")
|
|
20
|
+
name: PropertyRef = PropertyRef("name")
|
|
21
|
+
location: PropertyRef = PropertyRef("location")
|
|
22
|
+
state: PropertyRef = PropertyRef("state")
|
|
23
|
+
created_time: PropertyRef = PropertyRef("createdTime")
|
|
24
|
+
changed_time: PropertyRef = PropertyRef("changedTime")
|
|
25
|
+
version: PropertyRef = PropertyRef("version")
|
|
26
|
+
access_endpoint: PropertyRef = PropertyRef("accessEndpoint")
|
|
27
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# --- Relationship Definitions ---
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class AzureLogicAppToSubscriptionRelProperties(CartographyRelProperties):
|
|
33
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class AzureLogicAppToSubscriptionRel(CartographyRelSchema):
|
|
38
|
+
target_node_label: str = "AzureSubscription"
|
|
39
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
40
|
+
{"id": PropertyRef("AZURE_SUBSCRIPTION_ID", set_in_kwargs=True)},
|
|
41
|
+
)
|
|
42
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
43
|
+
rel_label: str = "RESOURCE"
|
|
44
|
+
properties: AzureLogicAppToSubscriptionRelProperties = (
|
|
45
|
+
AzureLogicAppToSubscriptionRelProperties()
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# --- Main Schema ---
|
|
50
|
+
@dataclass(frozen=True)
|
|
51
|
+
class AzureLogicAppSchema(CartographyNodeSchema):
|
|
52
|
+
label: str = "AzureLogicApp"
|
|
53
|
+
properties: AzureLogicAppProperties = AzureLogicAppProperties()
|
|
54
|
+
sub_resource_relationship: AzureLogicAppToSubscriptionRel = (
|
|
55
|
+
AzureLogicAppToSubscriptionRel()
|
|
56
|
+
)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
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.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
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# --- Node Definitions ---
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class AzureResourceGroupProperties(CartographyNodeProperties):
|
|
19
|
+
id: PropertyRef = PropertyRef("id")
|
|
20
|
+
name: PropertyRef = PropertyRef("name")
|
|
21
|
+
location: PropertyRef = PropertyRef("location")
|
|
22
|
+
provisioning_state: PropertyRef = PropertyRef("provisioning_state")
|
|
23
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# --- Relationship Definitions ---
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class AzureResourceGroupToSubscriptionRelProperties(CartographyRelProperties):
|
|
29
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class AzureResourceGroupToSubscriptionRel(CartographyRelSchema):
|
|
34
|
+
target_node_label: str = "AzureSubscription"
|
|
35
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
36
|
+
{"id": PropertyRef("AZURE_SUBSCRIPTION_ID", set_in_kwargs=True)},
|
|
37
|
+
)
|
|
38
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
39
|
+
rel_label: str = "RESOURCE"
|
|
40
|
+
properties: AzureResourceGroupToSubscriptionRelProperties = (
|
|
41
|
+
AzureResourceGroupToSubscriptionRelProperties()
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# --- Main Schema ---
|
|
46
|
+
@dataclass(frozen=True)
|
|
47
|
+
class AzureResourceGroupSchema(CartographyNodeSchema):
|
|
48
|
+
label: str = "AzureResourceGroup"
|
|
49
|
+
properties: AzureResourceGroupProperties = AzureResourceGroupProperties()
|
|
50
|
+
sub_resource_relationship: AzureResourceGroupToSubscriptionRel = (
|
|
51
|
+
AzureResourceGroupToSubscriptionRel()
|
|
52
|
+
)
|
cartography/models/entra/user.py
CHANGED
|
@@ -8,6 +8,7 @@ from cartography.models.core.relationships import CartographyRelProperties
|
|
|
8
8
|
from cartography.models.core.relationships import CartographyRelSchema
|
|
9
9
|
from cartography.models.core.relationships import LinkDirection
|
|
10
10
|
from cartography.models.core.relationships import make_target_node_matcher
|
|
11
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
11
12
|
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
13
|
|
|
13
14
|
# The user resource in Microsoft Graph exposes hundreds of properties but, in
|
|
@@ -47,6 +48,18 @@ class EntraTenantToUserRelProperties(CartographyRelProperties):
|
|
|
47
48
|
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
48
49
|
|
|
49
50
|
|
|
51
|
+
@dataclass(frozen=True)
|
|
52
|
+
# (:EntraUser)-[:REPORTS_TO]->(:EntraUser)
|
|
53
|
+
class EntraUserReportsToRel(CartographyRelSchema):
|
|
54
|
+
target_node_label: str = "EntraUser"
|
|
55
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
56
|
+
{"id": PropertyRef("manager_id")},
|
|
57
|
+
)
|
|
58
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
59
|
+
rel_label: str = "REPORTS_TO"
|
|
60
|
+
properties: EntraTenantToUserRelProperties = EntraTenantToUserRelProperties()
|
|
61
|
+
|
|
62
|
+
|
|
50
63
|
@dataclass(frozen=True)
|
|
51
64
|
# (:EntraUser)<-[:RESOURCE]-(:AzureTenant)
|
|
52
65
|
class EntraUserToTenantRel(CartographyRelSchema):
|
|
@@ -64,6 +77,11 @@ class EntraUserSchema(CartographyNodeSchema):
|
|
|
64
77
|
label: str = "EntraUser"
|
|
65
78
|
properties: EntraUserNodeProperties = EntraUserNodeProperties()
|
|
66
79
|
sub_resource_relationship: EntraUserToTenantRel = EntraUserToTenantRel()
|
|
80
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
81
|
+
[
|
|
82
|
+
EntraUserReportsToRel(),
|
|
83
|
+
]
|
|
84
|
+
)
|
|
67
85
|
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(
|
|
68
86
|
[
|
|
69
87
|
"EntraIdentity",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
See [the rules docs](https://cartography-cncf.github.io/cartography/usage/rules.html) for how Cartography develops and approaches security rules.
|
|
File without changes
|