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.

Files changed (42) hide show
  1. cartography/_version.py +2 -2
  2. cartography/cli.py +21 -3
  3. cartography/config.py +4 -0
  4. cartography/graph/cleanupbuilder.py +151 -41
  5. cartography/intel/anthropic/__init__.py +62 -0
  6. cartography/intel/anthropic/apikeys.py +72 -0
  7. cartography/intel/anthropic/users.py +75 -0
  8. cartography/intel/anthropic/util.py +51 -0
  9. cartography/intel/anthropic/workspaces.py +95 -0
  10. cartography/intel/aws/cloudtrail.py +3 -38
  11. cartography/intel/aws/cloudwatch.py +1 -1
  12. cartography/intel/aws/ec2/load_balancer_v2s.py +4 -1
  13. cartography/intel/aws/resources.py +0 -2
  14. cartography/intel/aws/secretsmanager.py +150 -3
  15. cartography/intel/aws/ssm.py +71 -0
  16. cartography/intel/entra/ou.py +21 -5
  17. cartography/intel/openai/adminapikeys.py +1 -2
  18. cartography/intel/openai/apikeys.py +1 -1
  19. cartography/intel/openai/projects.py +4 -1
  20. cartography/intel/openai/serviceaccounts.py +1 -1
  21. cartography/intel/openai/users.py +0 -3
  22. cartography/intel/openai/util.py +17 -1
  23. cartography/models/anthropic/apikey.py +90 -0
  24. cartography/models/anthropic/organization.py +19 -0
  25. cartography/models/anthropic/user.py +48 -0
  26. cartography/models/anthropic/workspace.py +90 -0
  27. cartography/models/aws/cloudtrail/trail.py +24 -0
  28. cartography/models/aws/secretsmanager/__init__.py +0 -0
  29. cartography/models/aws/secretsmanager/secret_version.py +116 -0
  30. cartography/models/aws/ssm/parameters.py +84 -0
  31. cartography/models/core/nodes.py +15 -2
  32. cartography/models/openai/project.py +20 -1
  33. cartography/sync.py +2 -0
  34. {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/METADATA +4 -4
  35. {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/RECORD +40 -30
  36. {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/WHEEL +1 -1
  37. cartography/intel/aws/efs.py +0 -93
  38. cartography/models/aws/efs/mount_target.py +0 -52
  39. /cartography/models/{aws/efs → anthropic}/__init__.py +0 -0
  40. {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/entry_points.txt +0 -0
  41. {cartography-0.103.0.dist-info → cartography-0.104.0.dist-info}/licenses/LICENSE +0 -0
  42. {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
+ )
@@ -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 overriden. Else return the node's OtherRelationships.
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 overriden. Else return the ExtraNodeLabels specified on the node.
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.103.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) - - Organization, AdminApiKey, User, Project, ProjectServiceAccount, ProjectApiKey
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