cartography 0.103.0__py3-none-any.whl → 0.104.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 +21 -3
- cartography/config.py +4 -0
- cartography/graph/cleanupbuilder.py +151 -41
- cartography/intel/anthropic/__init__.py +62 -0
- cartography/intel/anthropic/apikeys.py +72 -0
- cartography/intel/anthropic/users.py +75 -0
- cartography/intel/anthropic/util.py +51 -0
- cartography/intel/anthropic/workspaces.py +95 -0
- cartography/intel/aws/cloudtrail.py +3 -38
- cartography/intel/aws/cloudwatch.py +1 -1
- cartography/intel/aws/ec2/load_balancer_v2s.py +4 -1
- cartography/intel/aws/resources.py +0 -2
- cartography/intel/aws/secretsmanager.py +150 -3
- cartography/intel/aws/ssm.py +71 -0
- cartography/intel/entra/ou.py +21 -5
- cartography/intel/openai/adminapikeys.py +1 -2
- cartography/intel/openai/apikeys.py +1 -1
- cartography/intel/openai/projects.py +4 -1
- cartography/intel/openai/serviceaccounts.py +1 -1
- cartography/intel/openai/users.py +0 -3
- cartography/intel/openai/util.py +17 -1
- cartography/models/anthropic/apikey.py +90 -0
- cartography/models/anthropic/organization.py +19 -0
- cartography/models/anthropic/user.py +48 -0
- cartography/models/anthropic/workspace.py +90 -0
- cartography/models/aws/cloudtrail/trail.py +24 -0
- cartography/models/aws/secretsmanager/__init__.py +0 -0
- cartography/models/aws/secretsmanager/secret_version.py +116 -0
- cartography/models/aws/ssm/parameters.py +84 -0
- cartography/models/core/nodes.py +15 -2
- cartography/models/openai/project.py +20 -1
- cartography/sync.py +2 -0
- {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/METADATA +4 -4
- {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/RECORD +40 -30
- {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/WHEEL +1 -1
- cartography/intel/aws/efs.py +0 -93
- cartography/models/aws/efs/mount_target.py +0 -52
- /cartography/models/{aws/efs → anthropic}/__init__.py +0 -0
- {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
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 AnthropicApiKeyNodeProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef("id")
|
|
17
|
+
name: PropertyRef = PropertyRef("name")
|
|
18
|
+
status: PropertyRef = PropertyRef("status")
|
|
19
|
+
created_at: PropertyRef = PropertyRef("created_at")
|
|
20
|
+
last_used_at: PropertyRef = PropertyRef("last_used_at")
|
|
21
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class AnthropicApiKeyToOrganizationRelProperties(CartographyRelProperties):
|
|
26
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
# (:AnthropicOrganization)-[:RESOURCE]->(:AnthropicApiKey)
|
|
31
|
+
class AnthropicApiKeyToOrganizationRel(CartographyRelSchema):
|
|
32
|
+
target_node_label: str = "AnthropicOrganization"
|
|
33
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
34
|
+
{"id": PropertyRef("ORG_ID", set_in_kwargs=True)},
|
|
35
|
+
)
|
|
36
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
37
|
+
rel_label: str = "RESOURCE"
|
|
38
|
+
properties: AnthropicApiKeyToOrganizationRelProperties = (
|
|
39
|
+
AnthropicApiKeyToOrganizationRelProperties()
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass(frozen=True)
|
|
44
|
+
class AnthropicApiKeyToUserRelProperties(CartographyRelProperties):
|
|
45
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
# (:AnthropicUser)-[:OWNS]->(:AnthropicApiKey)
|
|
50
|
+
class AnthropicApiKeyToUserRel(CartographyRelSchema):
|
|
51
|
+
target_node_label: str = "AnthropicUser"
|
|
52
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
53
|
+
{"id": PropertyRef("created_by.id")},
|
|
54
|
+
)
|
|
55
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
56
|
+
rel_label: str = "OWNS"
|
|
57
|
+
properties: AnthropicApiKeyToUserRelProperties = (
|
|
58
|
+
AnthropicApiKeyToUserRelProperties()
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True)
|
|
63
|
+
class AnthropicApiKeyToWorkspaceRelProperties(CartographyRelProperties):
|
|
64
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass(frozen=True)
|
|
68
|
+
# (:AnthropicWorkspace)-[:CONTAINS]->(:AnthropicApiKey)
|
|
69
|
+
class AnthropicApiKeyToWorkspaceRel(CartographyRelSchema):
|
|
70
|
+
target_node_label: str = "AnthropicWorkspace"
|
|
71
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
72
|
+
{"id": PropertyRef("workspace_id")},
|
|
73
|
+
)
|
|
74
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
75
|
+
rel_label: str = "CONTAINS"
|
|
76
|
+
properties: AnthropicApiKeyToWorkspaceRelProperties = (
|
|
77
|
+
AnthropicApiKeyToWorkspaceRelProperties()
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True)
|
|
82
|
+
class AnthropicApiKeySchema(CartographyNodeSchema):
|
|
83
|
+
label: str = "AnthropicApiKey"
|
|
84
|
+
properties: AnthropicApiKeyNodeProperties = AnthropicApiKeyNodeProperties()
|
|
85
|
+
sub_resource_relationship: AnthropicApiKeyToOrganizationRel = (
|
|
86
|
+
AnthropicApiKeyToOrganizationRel()
|
|
87
|
+
)
|
|
88
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
89
|
+
[AnthropicApiKeyToUserRel(), AnthropicApiKeyToWorkspaceRel()],
|
|
90
|
+
)
|
|
@@ -0,0 +1,19 @@
|
|
|
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 AnthropicOrganizationNodeProperties(CartographyNodeProperties):
|
|
10
|
+
id: PropertyRef = PropertyRef("id")
|
|
11
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class AnthropicOrganizationSchema(CartographyNodeSchema):
|
|
16
|
+
label: str = "AnthropicOrganization"
|
|
17
|
+
properties: AnthropicOrganizationNodeProperties = (
|
|
18
|
+
AnthropicOrganizationNodeProperties()
|
|
19
|
+
)
|
|
@@ -0,0 +1,48 @@
|
|
|
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 TargetNodeMatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class AnthropicUserNodeProperties(CartographyNodeProperties):
|
|
15
|
+
id: PropertyRef = PropertyRef("id")
|
|
16
|
+
name: PropertyRef = PropertyRef("name")
|
|
17
|
+
email: PropertyRef = PropertyRef("email", extra_index=True)
|
|
18
|
+
role: PropertyRef = PropertyRef("role")
|
|
19
|
+
added_at: PropertyRef = PropertyRef("added_at")
|
|
20
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class AnthropicUserToOrganizationRelProperties(CartographyRelProperties):
|
|
25
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
# (:AnthropicOrganization)-[:RESOURCE]->(:AnthropicUser)
|
|
30
|
+
class AnthropicUserToOrganizationRel(CartographyRelSchema):
|
|
31
|
+
target_node_label: str = "AnthropicOrganization"
|
|
32
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
33
|
+
{"id": PropertyRef("ORG_ID", set_in_kwargs=True)},
|
|
34
|
+
)
|
|
35
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
36
|
+
rel_label: str = "RESOURCE"
|
|
37
|
+
properties: AnthropicUserToOrganizationRelProperties = (
|
|
38
|
+
AnthropicUserToOrganizationRelProperties()
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(frozen=True)
|
|
43
|
+
class AnthropicUserSchema(CartographyNodeSchema):
|
|
44
|
+
label: str = "AnthropicUser"
|
|
45
|
+
properties: AnthropicUserNodeProperties = AnthropicUserNodeProperties()
|
|
46
|
+
sub_resource_relationship: AnthropicUserToOrganizationRel = (
|
|
47
|
+
AnthropicUserToOrganizationRel()
|
|
48
|
+
)
|
|
@@ -0,0 +1,90 @@
|
|
|
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 AnthropicWorkspaceNodeProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef("id")
|
|
17
|
+
name: PropertyRef = PropertyRef("name")
|
|
18
|
+
created_at: PropertyRef = PropertyRef("created_at")
|
|
19
|
+
archived_at: PropertyRef = PropertyRef("archived_at")
|
|
20
|
+
display_color: PropertyRef = PropertyRef("display_color")
|
|
21
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class AnthropicWorkspaceToOrganizationRelProperties(CartographyRelProperties):
|
|
26
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
# (:AnthropicOrganization)-[:RESOURCE]->(:AnthropicWorkspace)
|
|
31
|
+
class AnthropicWorkspaceToOrganizationRel(CartographyRelSchema):
|
|
32
|
+
target_node_label: str = "AnthropicOrganization"
|
|
33
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
34
|
+
{"id": PropertyRef("ORG_ID", set_in_kwargs=True)},
|
|
35
|
+
)
|
|
36
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
37
|
+
rel_label: str = "RESOURCE"
|
|
38
|
+
properties: AnthropicWorkspaceToOrganizationRelProperties = (
|
|
39
|
+
AnthropicWorkspaceToOrganizationRelProperties()
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass(frozen=True)
|
|
44
|
+
class AnthropicWorkspaceToUserRelProperties(CartographyRelProperties):
|
|
45
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
# (:AnthropicUser)-[:MEMBER_OF]->(:AnthropicWorkspace)
|
|
50
|
+
class AnthropicWorkspaceToUserRel(CartographyRelSchema):
|
|
51
|
+
target_node_label: str = "AnthropicUser"
|
|
52
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
53
|
+
{"id": PropertyRef("users", one_to_many=True)},
|
|
54
|
+
)
|
|
55
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
56
|
+
rel_label: str = "MEMBER_OF"
|
|
57
|
+
properties: AnthropicWorkspaceToUserRelProperties = (
|
|
58
|
+
AnthropicWorkspaceToUserRelProperties()
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True)
|
|
63
|
+
class AnthropicWorkspaceToUserAdminRelProperties(CartographyRelProperties):
|
|
64
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@dataclass(frozen=True)
|
|
68
|
+
# (:AnthropicUser)-[:ADMIN_OF]->(:AnthropicWorkspace)
|
|
69
|
+
class AnthropicWorkspaceToUserAdminRel(CartographyRelSchema):
|
|
70
|
+
target_node_label: str = "AnthropicUser"
|
|
71
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
72
|
+
{"id": PropertyRef("admins", one_to_many=True)},
|
|
73
|
+
)
|
|
74
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
75
|
+
rel_label: str = "ADMIN_OF"
|
|
76
|
+
properties: AnthropicWorkspaceToUserAdminRelProperties = (
|
|
77
|
+
AnthropicWorkspaceToUserAdminRelProperties()
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True)
|
|
82
|
+
class AnthropicWorkspaceSchema(CartographyNodeSchema):
|
|
83
|
+
label: str = "AnthropicWorkspace"
|
|
84
|
+
properties: AnthropicWorkspaceNodeProperties = AnthropicWorkspaceNodeProperties()
|
|
85
|
+
sub_resource_relationship: AnthropicWorkspaceToOrganizationRel = (
|
|
86
|
+
AnthropicWorkspaceToOrganizationRel()
|
|
87
|
+
)
|
|
88
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
89
|
+
[AnthropicWorkspaceToUserRel(), AnthropicWorkspaceToUserAdminRel()],
|
|
90
|
+
)
|
|
@@ -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
|
|
|
@@ -54,8 +55,31 @@ class CloudTrailToAWSAccountRel(CartographyRelSchema):
|
|
|
54
55
|
)
|
|
55
56
|
|
|
56
57
|
|
|
58
|
+
@dataclass(frozen=True)
|
|
59
|
+
class CloudTrailTrailToS3BucketRelProperties(CartographyRelProperties):
|
|
60
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(frozen=True)
|
|
64
|
+
class CloudTrailTrailToS3BucketRel(CartographyRelSchema):
|
|
65
|
+
target_node_label: str = "S3Bucket"
|
|
66
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
67
|
+
{"name": PropertyRef("S3BucketName")},
|
|
68
|
+
)
|
|
69
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
70
|
+
rel_label: str = "LOGS_TO"
|
|
71
|
+
properties: CloudTrailTrailToS3BucketRelProperties = (
|
|
72
|
+
CloudTrailTrailToS3BucketRelProperties()
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
57
76
|
@dataclass(frozen=True)
|
|
58
77
|
class CloudTrailTrailSchema(CartographyNodeSchema):
|
|
59
78
|
label: str = "CloudTrailTrail"
|
|
60
79
|
properties: CloudTrailTrailNodeProperties = CloudTrailTrailNodeProperties()
|
|
61
80
|
sub_resource_relationship: CloudTrailToAWSAccountRel = CloudTrailToAWSAccountRel()
|
|
81
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
82
|
+
[
|
|
83
|
+
CloudTrailTrailToS3BucketRel(),
|
|
84
|
+
]
|
|
85
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,116 @@
|
|
|
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 SecretsManagerSecretVersionNodeProperties(CartographyNodeProperties):
|
|
16
|
+
"""
|
|
17
|
+
Properties for AWS Secrets Manager Secret Version
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# Align property names with the actual keys in the data
|
|
21
|
+
id: PropertyRef = PropertyRef("ARN")
|
|
22
|
+
arn: PropertyRef = PropertyRef("ARN", extra_index=True)
|
|
23
|
+
secret_id: PropertyRef = PropertyRef("SecretId")
|
|
24
|
+
version_id: PropertyRef = PropertyRef("VersionId")
|
|
25
|
+
version_stages: PropertyRef = PropertyRef("VersionStages")
|
|
26
|
+
created_date: PropertyRef = PropertyRef("CreatedDate")
|
|
27
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
28
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
29
|
+
# Make KMS and tags properties without required=False parameter
|
|
30
|
+
kms_key_id: PropertyRef = PropertyRef("KmsKeyId")
|
|
31
|
+
tags: PropertyRef = PropertyRef("Tags")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass(frozen=True)
|
|
35
|
+
class SecretsManagerSecretVersionRelProperties(CartographyRelProperties):
|
|
36
|
+
"""
|
|
37
|
+
Properties for relationships between Secret Version and other nodes
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass(frozen=True)
|
|
44
|
+
class SecretsManagerSecretVersionToAWSAccountRel(CartographyRelSchema):
|
|
45
|
+
"""
|
|
46
|
+
Relationship between Secret Version and AWS Account
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
target_node_label: str = "AWSAccount"
|
|
50
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
51
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)},
|
|
52
|
+
)
|
|
53
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
54
|
+
rel_label: str = "RESOURCE"
|
|
55
|
+
properties: SecretsManagerSecretVersionRelProperties = (
|
|
56
|
+
SecretsManagerSecretVersionRelProperties()
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@dataclass(frozen=True)
|
|
61
|
+
class SecretsManagerSecretVersionToSecretRel(CartographyRelSchema):
|
|
62
|
+
"""
|
|
63
|
+
Relationship between Secret Version and its parent Secret
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
target_node_label: str = "SecretsManagerSecret"
|
|
67
|
+
# Use only one matcher for the id field
|
|
68
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
69
|
+
{"id": PropertyRef("SecretId")},
|
|
70
|
+
)
|
|
71
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
72
|
+
rel_label: str = "VERSION_OF"
|
|
73
|
+
properties: SecretsManagerSecretVersionRelProperties = (
|
|
74
|
+
SecretsManagerSecretVersionRelProperties()
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True)
|
|
79
|
+
class SecretsManagerSecretVersionToKMSKeyRel(CartographyRelSchema):
|
|
80
|
+
"""
|
|
81
|
+
Relationship between Secret Version and its KMS key
|
|
82
|
+
Only created when KmsKeyId is present
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
target_node_label: str = "AWSKMSKey"
|
|
86
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
87
|
+
{"id": PropertyRef("KmsKeyId")},
|
|
88
|
+
)
|
|
89
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
90
|
+
rel_label: str = "ENCRYPTED_BY"
|
|
91
|
+
properties: SecretsManagerSecretVersionRelProperties = (
|
|
92
|
+
SecretsManagerSecretVersionRelProperties()
|
|
93
|
+
)
|
|
94
|
+
# Only create this relationship if KmsKeyId exists
|
|
95
|
+
conditional_match_property: str = "KmsKeyId"
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@dataclass(frozen=True)
|
|
99
|
+
class SecretsManagerSecretVersionSchema(CartographyNodeSchema):
|
|
100
|
+
"""
|
|
101
|
+
Schema for AWS Secrets Manager Secret Version
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
label: str = "SecretsManagerSecretVersion"
|
|
105
|
+
properties: SecretsManagerSecretVersionNodeProperties = (
|
|
106
|
+
SecretsManagerSecretVersionNodeProperties()
|
|
107
|
+
)
|
|
108
|
+
sub_resource_relationship: SecretsManagerSecretVersionToAWSAccountRel = (
|
|
109
|
+
SecretsManagerSecretVersionToAWSAccountRel()
|
|
110
|
+
)
|
|
111
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
112
|
+
[
|
|
113
|
+
SecretsManagerSecretVersionToSecretRel(),
|
|
114
|
+
SecretsManagerSecretVersionToKMSKeyRel(),
|
|
115
|
+
],
|
|
116
|
+
)
|
|
@@ -0,0 +1,84 @@
|
|
|
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 SSMParameterNodeProperties(CartographyNodeProperties):
|
|
16
|
+
|
|
17
|
+
arn: PropertyRef = PropertyRef("ARN", extra_index=True)
|
|
18
|
+
id: PropertyRef = PropertyRef("ARN")
|
|
19
|
+
name: PropertyRef = PropertyRef("Name")
|
|
20
|
+
description: PropertyRef = PropertyRef("Description")
|
|
21
|
+
type: PropertyRef = PropertyRef("Type")
|
|
22
|
+
keyid: PropertyRef = PropertyRef("KeyId")
|
|
23
|
+
kms_key_id_short: PropertyRef = PropertyRef("KMSKeyIdShort")
|
|
24
|
+
version: PropertyRef = PropertyRef("Version")
|
|
25
|
+
lastmodifieddate: PropertyRef = PropertyRef("LastModifiedDate")
|
|
26
|
+
tier: PropertyRef = PropertyRef("Tier")
|
|
27
|
+
lastmodifieduser: PropertyRef = PropertyRef("LastModifiedUser")
|
|
28
|
+
datatype: PropertyRef = PropertyRef("DataType")
|
|
29
|
+
allowedpattern: PropertyRef = PropertyRef("AllowedPattern")
|
|
30
|
+
policies_json: PropertyRef = PropertyRef("PoliciesJson")
|
|
31
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
32
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass(frozen=True)
|
|
36
|
+
class SSMParameterToAWSAccountRelProperties(CartographyRelProperties):
|
|
37
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True)
|
|
41
|
+
class SSMParameterToAWSAccountRel(CartographyRelSchema):
|
|
42
|
+
target_node_label: str = "AWSAccount"
|
|
43
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
44
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)},
|
|
45
|
+
)
|
|
46
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
47
|
+
rel_label: str = "RESOURCE"
|
|
48
|
+
properties: SSMParameterToAWSAccountRelProperties = (
|
|
49
|
+
SSMParameterToAWSAccountRelProperties()
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(frozen=True)
|
|
54
|
+
class SSMParameterToKMSKeyRelProperties(CartographyRelProperties):
|
|
55
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass(frozen=True)
|
|
59
|
+
class SSMParameterToKMSKeyRel(CartographyRelSchema):
|
|
60
|
+
target_node_label: str = "KMSKey"
|
|
61
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
62
|
+
{
|
|
63
|
+
"id": PropertyRef("KMSKeyIdShort"),
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
67
|
+
rel_label: str = "ENCRYPTED_BY"
|
|
68
|
+
properties: SSMParameterToKMSKeyRelProperties = SSMParameterToKMSKeyRelProperties()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass(frozen=True)
|
|
72
|
+
class SSMParameterSchema(CartographyNodeSchema):
|
|
73
|
+
|
|
74
|
+
label: str = "SSMParameter"
|
|
75
|
+
properties: SSMParameterNodeProperties = SSMParameterNodeProperties()
|
|
76
|
+
sub_resource_relationship: SSMParameterToAWSAccountRel = (
|
|
77
|
+
SSMParameterToAWSAccountRel()
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
81
|
+
[
|
|
82
|
+
SSMParameterToKMSKeyRel(),
|
|
83
|
+
],
|
|
84
|
+
)
|
cartography/models/core/nodes.py
CHANGED
|
@@ -91,7 +91,7 @@ class CartographyNodeSchema(abc.ABC):
|
|
|
91
91
|
"""
|
|
92
92
|
Optional.
|
|
93
93
|
Allows subclasses to specify additional cartography relationships on the node.
|
|
94
|
-
:return: None if not
|
|
94
|
+
:return: None if not overridden. Else return the node's OtherRelationships.
|
|
95
95
|
"""
|
|
96
96
|
return None
|
|
97
97
|
|
|
@@ -100,6 +100,19 @@ class CartographyNodeSchema(abc.ABC):
|
|
|
100
100
|
"""
|
|
101
101
|
Optional.
|
|
102
102
|
Allows specifying extra labels on the node.
|
|
103
|
-
:return: None if not
|
|
103
|
+
:return: None if not overridden. Else return the ExtraNodeLabels specified on the node.
|
|
104
104
|
"""
|
|
105
105
|
return None
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def scoped_cleanup(self) -> bool:
|
|
109
|
+
"""
|
|
110
|
+
Optional.
|
|
111
|
+
Allows specifying whether cleanups of this node must be scoped to the sub resource relationship.
|
|
112
|
+
If True (default), when we clean up nodes of this type, we will only delete stale nodes in the current sub
|
|
113
|
+
resource. This is how our AWS sync behaves.
|
|
114
|
+
If False, when we clean up node of this type, we will delete all stale nodes. This is designed for resource
|
|
115
|
+
types that don't have a "tenant"-like entity.
|
|
116
|
+
:return: True if not overridden. Else return the boolean value specified on the node.
|
|
117
|
+
"""
|
|
118
|
+
return True
|
|
@@ -58,6 +58,25 @@ class OpenAIProjectToUserRel(CartographyRelSchema):
|
|
|
58
58
|
properties: OpenAIProjectToUserRelProperties = OpenAIProjectToUserRelProperties()
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
@dataclass(frozen=True)
|
|
62
|
+
class OpenAIProjectToUserAdminRelProperties(CartographyRelProperties):
|
|
63
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass(frozen=True)
|
|
67
|
+
# (:OpenAIUser)-[:ADMIN_OF]->(:OpenAIProject)
|
|
68
|
+
class OpenAIProjectToUserAdminRel(CartographyRelSchema):
|
|
69
|
+
target_node_label: str = "OpenAIUser"
|
|
70
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
71
|
+
{"id": PropertyRef("admins", one_to_many=True)},
|
|
72
|
+
)
|
|
73
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
74
|
+
rel_label: str = "ADMIN_OF"
|
|
75
|
+
properties: OpenAIProjectToUserAdminRelProperties = (
|
|
76
|
+
OpenAIProjectToUserAdminRelProperties()
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
61
80
|
@dataclass(frozen=True)
|
|
62
81
|
class OpenAIProjectSchema(CartographyNodeSchema):
|
|
63
82
|
label: str = "OpenAIProject"
|
|
@@ -66,5 +85,5 @@ class OpenAIProjectSchema(CartographyNodeSchema):
|
|
|
66
85
|
OpenAIProjectToOrganizationRel()
|
|
67
86
|
)
|
|
68
87
|
other_relationships: OtherRelationships = OtherRelationships(
|
|
69
|
-
[OpenAIProjectToUserRel()],
|
|
88
|
+
[OpenAIProjectToUserRel(), OpenAIProjectToUserAdminRel()],
|
|
70
89
|
)
|
cartography/sync.py
CHANGED
|
@@ -14,6 +14,7 @@ from neo4j import GraphDatabase
|
|
|
14
14
|
from statsd import StatsClient
|
|
15
15
|
|
|
16
16
|
import cartography.intel.analysis
|
|
17
|
+
import cartography.intel.anthropic
|
|
17
18
|
import cartography.intel.aws
|
|
18
19
|
import cartography.intel.azure
|
|
19
20
|
import cartography.intel.bigfix
|
|
@@ -47,6 +48,7 @@ logger = logging.getLogger(__name__)
|
|
|
47
48
|
TOP_LEVEL_MODULES = OrderedDict(
|
|
48
49
|
{ # preserve order so that the default sync always runs `analysis` at the very end
|
|
49
50
|
"create-indexes": cartography.intel.create_indexes.run,
|
|
51
|
+
"anthropic": cartography.intel.anthropic.start_anthropic_ingestion,
|
|
50
52
|
"aws": cartography.intel.aws.start_aws_ingestion,
|
|
51
53
|
"azure": cartography.intel.azure.start_azure_ingestion,
|
|
52
54
|
"entra": cartography.intel.entra.start_entra_ingestion,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cartography
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.104.0
|
|
4
4
|
Summary: Explore assets and their relationships across your technical infrastructure.
|
|
5
5
|
Maintainer: Cartography Contributors
|
|
6
6
|
License: apache2
|
|
@@ -80,8 +80,7 @@ You can learn more about the story behind Cartography in our [presentation at BS
|
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
## Supported platforms
|
|
83
|
-
|
|
84
|
-
- [Amazon Web Services](https://cartography-cncf.github.io/cartography/modules/aws/index.html) - API Gateway, CloudWatch, Config, EC2, ECS, ECR, Elasticsearch, Elastic Kubernetes Service (EKS), DynamoDB, IAM, Inspector, KMS, Lambda, RDS, Redshift, Route53, S3, Secrets Manager, Security Hub, SQS, SSM, STS, Tags
|
|
83
|
+
- [Amazon Web Services](https://cartography-cncf.github.io/cartography/modules/aws/index.html) - API Gateway, CloudWatch, Config, EC2, ECS, ECR, Elasticsearch, Elastic Kubernetes Service (EKS), DynamoDB, IAM, Inspector, KMS, Lambda, RDS, Redshift, Route53, S3, Secrets Manager(Secret Versions), Security Hub, SQS, SSM, STS, Tags
|
|
85
84
|
- [Google Cloud Platform](https://cartography-cncf.github.io/cartography/modules/gcp/index.html) - Cloud Resource Manager, Compute, DNS, Storage, Google Kubernetes Engine
|
|
86
85
|
- [Google GSuite](https://cartography-cncf.github.io/cartography/modules/gsuite/index.html) - users, groups
|
|
87
86
|
- [Oracle Cloud Infrastructure](https://cartography-cncf.github.io/cartography/modules/oci/index.html) - IAM
|
|
@@ -101,7 +100,8 @@ You can learn more about the story behind Cartography in our [presentation at BS
|
|
|
101
100
|
- [SnipeIT](https://cartography-cncf.github.io/cartography/modules/snipeit/index.html) - Users, Assets
|
|
102
101
|
- [Tailscale](https://cartography-cncf.github.io/cartography/modules/tailscale/index.html) - Tailnet, Users, Devices, Groups, Tags, PostureIntegrations
|
|
103
102
|
- [Cloudflare](https://cartography-cncf.github.io/cartography/modules/cloudflare/index.html) - Account, Role, Member, Zone, DNSRecord
|
|
104
|
-
- [OpenAI](https://cartography-cncf.github.io/cartography/modules/openai/index.html) -
|
|
103
|
+
- [OpenAI](https://cartography-cncf.github.io/cartography/modules/openai/index.html) - Organization, AdminApiKey, User, Project, ServiceAccount, ApiKey
|
|
104
|
+
- [Anthropic](https://cartography-cncf.github.io/cartography/modules/anthropic/index.html) - Organization, ApiKey, User, Workspace
|
|
105
105
|
|
|
106
106
|
|
|
107
107
|
## Philosophy
|