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.

Files changed (96) hide show
  1. cartography/_version.py +2 -2
  2. cartography/cli.py +10 -2
  3. cartography/client/core/tx.py +11 -0
  4. cartography/config.py +4 -0
  5. cartography/data/indexes.cypher +0 -27
  6. cartography/intel/aws/config.py +7 -3
  7. cartography/intel/aws/ecr.py +9 -9
  8. cartography/intel/aws/iam.py +741 -492
  9. cartography/intel/aws/identitycenter.py +240 -13
  10. cartography/intel/aws/lambda_function.py +69 -2
  11. cartography/intel/aws/organizations.py +10 -9
  12. cartography/intel/aws/permission_relationships.py +7 -17
  13. cartography/intel/aws/redshift.py +9 -4
  14. cartography/intel/aws/route53.py +53 -3
  15. cartography/intel/aws/securityhub.py +3 -1
  16. cartography/intel/azure/__init__.py +24 -0
  17. cartography/intel/azure/app_service.py +105 -0
  18. cartography/intel/azure/functions.py +124 -0
  19. cartography/intel/azure/logic_apps.py +101 -0
  20. cartography/intel/create_indexes.py +2 -1
  21. cartography/intel/dns.py +5 -2
  22. cartography/intel/entra/__init__.py +31 -0
  23. cartography/intel/entra/app_role_assignments.py +277 -0
  24. cartography/intel/entra/applications.py +4 -238
  25. cartography/intel/entra/federation/__init__.py +0 -0
  26. cartography/intel/entra/federation/aws_identity_center.py +77 -0
  27. cartography/intel/entra/service_principals.py +217 -0
  28. cartography/intel/gcp/__init__.py +136 -440
  29. cartography/intel/gcp/clients.py +65 -0
  30. cartography/intel/gcp/compute.py +18 -44
  31. cartography/intel/gcp/crm/__init__.py +0 -0
  32. cartography/intel/gcp/crm/folders.py +108 -0
  33. cartography/intel/gcp/crm/orgs.py +65 -0
  34. cartography/intel/gcp/crm/projects.py +109 -0
  35. cartography/intel/gcp/dns.py +2 -1
  36. cartography/intel/gcp/gke.py +72 -113
  37. cartography/intel/github/__init__.py +41 -0
  38. cartography/intel/github/commits.py +423 -0
  39. cartography/intel/github/repos.py +76 -45
  40. cartography/intel/gsuite/api.py +17 -4
  41. cartography/intel/okta/applications.py +9 -4
  42. cartography/intel/okta/awssaml.py +5 -2
  43. cartography/intel/okta/factors.py +3 -1
  44. cartography/intel/okta/groups.py +5 -2
  45. cartography/intel/okta/organization.py +3 -1
  46. cartography/intel/okta/origins.py +3 -1
  47. cartography/intel/okta/roles.py +5 -2
  48. cartography/intel/okta/users.py +3 -1
  49. cartography/models/aws/iam/access_key.py +103 -0
  50. cartography/models/aws/iam/account_role.py +24 -0
  51. cartography/models/aws/iam/federated_principal.py +60 -0
  52. cartography/models/aws/iam/group.py +60 -0
  53. cartography/models/aws/iam/group_membership.py +26 -0
  54. cartography/models/aws/iam/inline_policy.py +78 -0
  55. cartography/models/aws/iam/managed_policy.py +51 -0
  56. cartography/models/aws/iam/policy_statement.py +57 -0
  57. cartography/models/aws/iam/role.py +83 -0
  58. cartography/models/aws/iam/root_principal.py +52 -0
  59. cartography/models/aws/iam/service_principal.py +30 -0
  60. cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
  61. cartography/models/aws/iam/user.py +54 -0
  62. cartography/models/aws/identitycenter/awspermissionset.py +24 -1
  63. cartography/models/aws/identitycenter/awssogroup.py +70 -0
  64. cartography/models/aws/identitycenter/awsssouser.py +37 -1
  65. cartography/models/aws/lambda_function/lambda_function.py +2 -0
  66. cartography/models/azure/__init__.py +0 -0
  67. cartography/models/azure/app_service.py +59 -0
  68. cartography/models/azure/function_app.py +59 -0
  69. cartography/models/azure/logic_apps.py +56 -0
  70. cartography/models/entra/entra_user_to_aws_sso.py +41 -0
  71. cartography/models/entra/service_principal.py +104 -0
  72. cartography/models/entra/user.py +18 -0
  73. cartography/models/gcp/compute/subnet.py +74 -0
  74. cartography/models/gcp/crm/__init__.py +0 -0
  75. cartography/models/gcp/crm/folders.py +98 -0
  76. cartography/models/gcp/crm/organizations.py +21 -0
  77. cartography/models/gcp/crm/projects.py +100 -0
  78. cartography/models/gcp/gke.py +69 -0
  79. cartography/models/github/commits.py +63 -0
  80. {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/METADATA +8 -5
  81. {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/RECORD +85 -56
  82. cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
  83. cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
  84. cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
  85. cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
  86. cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
  87. cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
  88. cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
  89. cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
  90. cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
  91. cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
  92. cartography/intel/gcp/crm.py +0 -355
  93. {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/WHEEL +0 -0
  94. {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/entry_points.txt +0 -0
  95. {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/licenses/LICENSE +0 -0
  96. {cartography-0.113.0.dist-info → cartography-0.115.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,41 @@
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_source_node_matcher
8
+ from cartography.models.core.relationships import make_target_node_matcher
9
+ from cartography.models.core.relationships import SourceNodeMatcher
10
+ from cartography.models.core.relationships import TargetNodeMatcher
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class EntraUserToAWSSSOUserRelProperties(CartographyRelProperties):
15
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
16
+ _sub_resource_label: PropertyRef = PropertyRef(
17
+ "_sub_resource_label", set_in_kwargs=True
18
+ )
19
+ _sub_resource_id: PropertyRef = PropertyRef("_sub_resource_id", set_in_kwargs=True)
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class EntraUserToAWSSSOUserMatchLink(CartographyRelSchema):
24
+ target_node_label: str = "AWSSSOUser"
25
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
26
+ {
27
+ "user_name": PropertyRef("aws_user_name"),
28
+ "identity_store_id": PropertyRef("identity_store_id"),
29
+ }
30
+ )
31
+ source_node_label: str = "EntraUser"
32
+ source_node_matcher: SourceNodeMatcher = make_source_node_matcher(
33
+ {
34
+ "user_principal_name": PropertyRef("entra_user_principal_name"),
35
+ }
36
+ )
37
+ direction: LinkDirection = LinkDirection.OUTWARD
38
+ rel_label: str = "CAN_SIGN_ON_TO"
39
+ properties: EntraUserToAWSSSOUserRelProperties = (
40
+ EntraUserToAWSSSOUserRelProperties()
41
+ )
@@ -0,0 +1,104 @@
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 EntraServicePrincipalNodeProperties(CartographyNodeProperties):
16
+ id: PropertyRef = PropertyRef("id")
17
+ app_id: PropertyRef = PropertyRef("app_id")
18
+ display_name: PropertyRef = PropertyRef("display_name")
19
+ reply_urls: PropertyRef = PropertyRef("reply_urls")
20
+ aws_identity_center_instance_id: PropertyRef = PropertyRef(
21
+ "aws_identity_center_instance_id"
22
+ )
23
+ account_enabled: PropertyRef = PropertyRef("account_enabled")
24
+ service_principal_type: PropertyRef = PropertyRef("service_principal_type")
25
+ app_owner_organization_id: PropertyRef = PropertyRef("app_owner_organization_id")
26
+ login_url: PropertyRef = PropertyRef("login_url")
27
+ preferred_single_sign_on_mode: PropertyRef = PropertyRef(
28
+ "preferred_single_sign_on_mode"
29
+ )
30
+ preferred_token_signing_key_thumbprint: PropertyRef = PropertyRef(
31
+ "preferred_token_signing_key_thumbprint"
32
+ )
33
+ sign_in_audience: PropertyRef = PropertyRef("sign_in_audience")
34
+ tags: PropertyRef = PropertyRef("tags")
35
+ token_encryption_key_id: PropertyRef = PropertyRef("token_encryption_key_id")
36
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
37
+
38
+
39
+ @dataclass(frozen=True)
40
+ class EntraServicePrincipalToTenantRelProperties(CartographyRelProperties):
41
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
42
+
43
+
44
+ @dataclass(frozen=True)
45
+ class EntraServicePrincipalToTenantRel(CartographyRelSchema):
46
+ target_node_label: str = "EntraTenant"
47
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
48
+ {"id": PropertyRef("TENANT_ID", set_in_kwargs=True)},
49
+ )
50
+ direction: LinkDirection = LinkDirection.INWARD
51
+ rel_label: str = "RESOURCE"
52
+ properties: EntraServicePrincipalToTenantRelProperties = (
53
+ EntraServicePrincipalToTenantRelProperties()
54
+ )
55
+
56
+
57
+ @dataclass(frozen=True)
58
+ class ServicePrincipalToApplicationRelProperties(CartographyRelProperties):
59
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
60
+
61
+
62
+ @dataclass(frozen=True)
63
+ class ServicePrincipalToApplicationRel(CartographyRelSchema):
64
+ target_node_label: str = "EntraApplication"
65
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
66
+ {"app_id": PropertyRef("app_id")},
67
+ )
68
+ direction: LinkDirection = LinkDirection.INWARD
69
+ rel_label: str = "SERVICE_PRINCIPAL"
70
+ properties: ServicePrincipalToApplicationRelProperties = (
71
+ ServicePrincipalToApplicationRelProperties()
72
+ )
73
+
74
+
75
+ @dataclass(frozen=True)
76
+ class ServicePrincipalToAWSIdentityCenterRelProperties(CartographyRelProperties):
77
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
78
+
79
+
80
+ @dataclass(frozen=True)
81
+ class ServicePrincipalToAWSIdentityCenterRel(CartographyRelSchema):
82
+ target_node_label: str = "AWSIdentityCenter"
83
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
84
+ {"identity_store_id": PropertyRef("aws_identity_center_instance_id")},
85
+ )
86
+ direction: LinkDirection = LinkDirection.OUTWARD
87
+ rel_label: str = "FEDERATES_TO"
88
+ properties: ServicePrincipalToAWSIdentityCenterRelProperties = (
89
+ ServicePrincipalToAWSIdentityCenterRelProperties()
90
+ )
91
+
92
+
93
+ @dataclass(frozen=True)
94
+ class EntraServicePrincipalSchema(CartographyNodeSchema):
95
+ label: str = "EntraServicePrincipal"
96
+ properties: EntraServicePrincipalNodeProperties = (
97
+ EntraServicePrincipalNodeProperties()
98
+ )
99
+ sub_resource_relationship: EntraServicePrincipalToTenantRel = (
100
+ EntraServicePrincipalToTenantRel()
101
+ )
102
+ other_relationships: OtherRelationships = OtherRelationships(
103
+ [ServicePrincipalToApplicationRel(), ServicePrincipalToAWSIdentityCenterRel()]
104
+ )
@@ -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,74 @@
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 GCPSubnetNodeProperties(CartographyNodeProperties):
16
+ id: PropertyRef = PropertyRef("partial_uri", extra_index=True)
17
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
18
+ partial_uri: PropertyRef = PropertyRef("partial_uri")
19
+ self_link: PropertyRef = PropertyRef("self_link")
20
+ name: PropertyRef = PropertyRef("name", extra_index=True)
21
+ project_id: PropertyRef = PropertyRef("project_id")
22
+ region: PropertyRef = PropertyRef("region")
23
+ gateway_address: PropertyRef = PropertyRef("gateway_address")
24
+ ip_cidr_range: PropertyRef = PropertyRef("ip_cidr_range")
25
+ private_ip_google_access: PropertyRef = PropertyRef("private_ip_google_access")
26
+ vpc_partial_uri: PropertyRef = PropertyRef("vpc_partial_uri")
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class GCPSubnetToProjectRelProperties(CartographyRelProperties):
31
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
32
+
33
+
34
+ @dataclass(frozen=True)
35
+ class GCPSubnetToProjectRel(CartographyRelSchema):
36
+ target_node_label: str = "GCPProject"
37
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
38
+ {
39
+ "id": PropertyRef("PROJECT_ID", set_in_kwargs=True),
40
+ }
41
+ )
42
+ direction: LinkDirection = LinkDirection.INWARD
43
+ rel_label: str = "RESOURCE"
44
+ properties: GCPSubnetToProjectRelProperties = GCPSubnetToProjectRelProperties()
45
+
46
+
47
+ @dataclass(frozen=True)
48
+ class GCPSubnetToVpcRelProperties(CartographyRelProperties):
49
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
50
+
51
+
52
+ @dataclass(frozen=True)
53
+ class GCPSubnetToVpcRel(CartographyRelSchema):
54
+ target_node_label: str = "GCPVpc"
55
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
56
+ {
57
+ "id": PropertyRef("vpc_partial_uri"),
58
+ }
59
+ )
60
+ direction: LinkDirection = LinkDirection.INWARD
61
+ rel_label: str = "HAS"
62
+ properties: GCPSubnetToVpcRelProperties = GCPSubnetToVpcRelProperties()
63
+
64
+
65
+ @dataclass(frozen=True)
66
+ class GCPSubnetSchema(CartographyNodeSchema):
67
+ label: str = "GCPSubnet"
68
+ properties: GCPSubnetNodeProperties = GCPSubnetNodeProperties()
69
+ sub_resource_relationship: GCPSubnetToProjectRel = GCPSubnetToProjectRel()
70
+ other_relationships: OtherRelationships = OtherRelationships(
71
+ [
72
+ GCPSubnetToVpcRel(),
73
+ ]
74
+ )
File without changes
@@ -0,0 +1,98 @@
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 GCPFolderNodeProperties(CartographyNodeProperties):
16
+ id: PropertyRef = PropertyRef(
17
+ "name"
18
+ ) # Use full folder name as ID (e.g., "folders/1414")
19
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
20
+ foldername: PropertyRef = PropertyRef("name")
21
+ displayname: PropertyRef = PropertyRef("displayName")
22
+ lifecyclestate: PropertyRef = PropertyRef("lifecycleState")
23
+ parent_org: PropertyRef = PropertyRef(
24
+ "parent_org"
25
+ ) # Will be set to org ID if parent is org
26
+ parent_folder: PropertyRef = PropertyRef(
27
+ "parent_folder"
28
+ ) # Will be set to folder ID if parent is folder
29
+
30
+
31
+ @dataclass(frozen=True)
32
+ class GCPFolderToOrgParentRelProperties(CartographyRelProperties):
33
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
34
+
35
+
36
+ @dataclass(frozen=True)
37
+ class GCPFolderToOrgParentRel(CartographyRelSchema):
38
+ """Relationship when folder's parent is an organization"""
39
+
40
+ target_node_label: str = "GCPOrganization"
41
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
42
+ {"id": PropertyRef("parent_org")},
43
+ )
44
+ direction: LinkDirection = LinkDirection.OUTWARD
45
+ rel_label: str = "PARENT"
46
+ properties: GCPFolderToOrgParentRelProperties = GCPFolderToOrgParentRelProperties()
47
+
48
+
49
+ @dataclass(frozen=True)
50
+ class GCPFolderToFolderParentRelProperties(CartographyRelProperties):
51
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
52
+
53
+
54
+ @dataclass(frozen=True)
55
+ class GCPFolderToFolderParentRel(CartographyRelSchema):
56
+ """Relationship when folder's parent is another folder"""
57
+
58
+ target_node_label: str = "GCPFolder"
59
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
60
+ {"id": PropertyRef("parent_folder")},
61
+ )
62
+ direction: LinkDirection = LinkDirection.OUTWARD
63
+ rel_label: str = "PARENT"
64
+ properties: GCPFolderToFolderParentRelProperties = (
65
+ GCPFolderToFolderParentRelProperties()
66
+ )
67
+
68
+
69
+ @dataclass(frozen=True)
70
+ class GCPFolderToOrganizationRelProperties(CartographyRelProperties):
71
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
72
+
73
+
74
+ @dataclass(frozen=True)
75
+ class GCPFolderToOrganizationRel(CartographyRelSchema):
76
+ target_node_label: str = "GCPOrganization"
77
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
78
+ {"id": PropertyRef("ORG_RESOURCE_NAME", set_in_kwargs=True)},
79
+ )
80
+ direction: LinkDirection = LinkDirection.INWARD
81
+ rel_label: str = "RESOURCE"
82
+ properties: GCPFolderToOrganizationRelProperties = (
83
+ GCPFolderToOrganizationRelProperties()
84
+ )
85
+
86
+
87
+ @dataclass(frozen=True)
88
+ class GCPFolderSchema(CartographyNodeSchema):
89
+ label: str = "GCPFolder"
90
+ properties: GCPFolderNodeProperties = GCPFolderNodeProperties()
91
+ # Organization owns the folder as a resource
92
+ sub_resource_relationship: GCPFolderToOrganizationRel = GCPFolderToOrganizationRel()
93
+ other_relationships: OtherRelationships = OtherRelationships(
94
+ [
95
+ GCPFolderToOrgParentRel(),
96
+ GCPFolderToFolderParentRel(),
97
+ ]
98
+ )
@@ -0,0 +1,21 @@
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 GCPOrganizationNodeProperties(CartographyNodeProperties):
10
+ id: PropertyRef = PropertyRef("id")
11
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
12
+ orgname: PropertyRef = PropertyRef("name")
13
+ displayname: PropertyRef = PropertyRef("displayName")
14
+ lifecyclestate: PropertyRef = PropertyRef("lifecycleState")
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class GCPOrganizationSchema(CartographyNodeSchema):
19
+ label: str = "GCPOrganization"
20
+ properties: GCPOrganizationNodeProperties = GCPOrganizationNodeProperties()
21
+ # sub_resource_relationship is None by default - Organizations are top-level resources
@@ -0,0 +1,100 @@
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 GCPProjectNodeProperties(CartographyNodeProperties):
16
+ id: PropertyRef = PropertyRef("projectId")
17
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
18
+ projectnumber: PropertyRef = PropertyRef("projectNumber", extra_index=True)
19
+ displayname: PropertyRef = PropertyRef("name")
20
+ lifecyclestate: PropertyRef = PropertyRef("lifecycleState")
21
+ parent_org: PropertyRef = PropertyRef(
22
+ "parent_org"
23
+ ) # Will be set to org ID if parent is org
24
+ parent_folder: PropertyRef = PropertyRef(
25
+ "parent_folder"
26
+ ) # Will be set to folder ID if parent is folder
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class GCPProjectToOrgParentRelProperties(CartographyRelProperties):
31
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
32
+
33
+
34
+ @dataclass(frozen=True)
35
+ class GCPProjectToOrgParentRel(CartographyRelSchema):
36
+ """Relationship when project's parent is an organization"""
37
+
38
+ target_node_label: str = "GCPOrganization"
39
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
40
+ {"id": PropertyRef("parent_org")},
41
+ )
42
+ direction: LinkDirection = LinkDirection.OUTWARD
43
+ rel_label: str = "PARENT"
44
+ properties: GCPProjectToOrgParentRelProperties = (
45
+ GCPProjectToOrgParentRelProperties()
46
+ )
47
+
48
+
49
+ @dataclass(frozen=True)
50
+ class GCPProjectToFolderParentRelProperties(CartographyRelProperties):
51
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
52
+
53
+
54
+ @dataclass(frozen=True)
55
+ class GCPProjectToFolderParentRel(CartographyRelSchema):
56
+ """Relationship when project's parent is a folder"""
57
+
58
+ target_node_label: str = "GCPFolder"
59
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
60
+ {"id": PropertyRef("parent_folder")},
61
+ )
62
+ direction: LinkDirection = LinkDirection.OUTWARD
63
+ rel_label: str = "PARENT"
64
+ properties: GCPProjectToFolderParentRelProperties = (
65
+ GCPProjectToFolderParentRelProperties()
66
+ )
67
+
68
+
69
+ @dataclass(frozen=True)
70
+ class GCPProjectToOrganizationRelProperties(CartographyRelProperties):
71
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
72
+
73
+
74
+ @dataclass(frozen=True)
75
+ class GCPProjectToOrganizationRel(CartographyRelSchema):
76
+ target_node_label: str = "GCPOrganization"
77
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
78
+ {"id": PropertyRef("ORG_RESOURCE_NAME", set_in_kwargs=True)},
79
+ )
80
+ direction: LinkDirection = LinkDirection.INWARD
81
+ rel_label: str = "RESOURCE"
82
+ properties: GCPProjectToOrganizationRelProperties = (
83
+ GCPProjectToOrganizationRelProperties()
84
+ )
85
+
86
+
87
+ @dataclass(frozen=True)
88
+ class GCPProjectSchema(CartographyNodeSchema):
89
+ label: str = "GCPProject"
90
+ properties: GCPProjectNodeProperties = GCPProjectNodeProperties()
91
+ # Organization owns the project as a resource
92
+ sub_resource_relationship: GCPProjectToOrganizationRel = (
93
+ GCPProjectToOrganizationRel()
94
+ )
95
+ other_relationships: OtherRelationships = OtherRelationships(
96
+ [
97
+ GCPProjectToOrgParentRel(),
98
+ GCPProjectToFolderParentRel(),
99
+ ]
100
+ )
@@ -0,0 +1,69 @@
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 GCPGKEClusterNodeProperties(CartographyNodeProperties):
15
+ id: PropertyRef = PropertyRef("id", extra_index=True)
16
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
17
+ name: PropertyRef = PropertyRef("name")
18
+ self_link: PropertyRef = PropertyRef("self_link")
19
+ description: PropertyRef = PropertyRef("description")
20
+ logging_service: PropertyRef = PropertyRef("logging_service")
21
+ monitoring_service: PropertyRef = PropertyRef("monitoring_service")
22
+ network: PropertyRef = PropertyRef("network")
23
+ subnetwork: PropertyRef = PropertyRef("subnetwork")
24
+ cluster_ipv4cidr: PropertyRef = PropertyRef("cluster_ipv4cidr")
25
+ zone: PropertyRef = PropertyRef("zone")
26
+ location: PropertyRef = PropertyRef("location")
27
+ endpoint: PropertyRef = PropertyRef("endpoint")
28
+ initial_version: PropertyRef = PropertyRef("initial_version")
29
+ current_master_version: PropertyRef = PropertyRef("current_master_version")
30
+ status: PropertyRef = PropertyRef("status")
31
+ services_ipv4cidr: PropertyRef = PropertyRef("services_ipv4cidr")
32
+ database_encryption: PropertyRef = PropertyRef("database_encryption")
33
+ network_policy: PropertyRef = PropertyRef("network_policy")
34
+ master_authorized_networks: PropertyRef = PropertyRef("master_authorized_networks")
35
+ legacy_abac: PropertyRef = PropertyRef("legacy_abac")
36
+ shielded_nodes: PropertyRef = PropertyRef("shielded_nodes")
37
+ private_nodes: PropertyRef = PropertyRef("private_nodes")
38
+ private_endpoint_enabled: PropertyRef = PropertyRef("private_endpoint_enabled")
39
+ private_endpoint: PropertyRef = PropertyRef("private_endpoint")
40
+ public_endpoint: PropertyRef = PropertyRef("public_endpoint")
41
+ masterauth_username: PropertyRef = PropertyRef("masterauth_username")
42
+ masterauth_password: PropertyRef = PropertyRef("masterauth_password")
43
+ created_at: PropertyRef = PropertyRef("created_at")
44
+
45
+
46
+ @dataclass(frozen=True)
47
+ class GCPGKEClusterToProjectRelProperties(CartographyRelProperties):
48
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
49
+
50
+
51
+ @dataclass(frozen=True)
52
+ # (:GCPProject)-[:RESOURCE]->(:GKECluster)
53
+ class GCPGKEClusterToProjectRel(CartographyRelSchema):
54
+ target_node_label: str = "GCPProject"
55
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
56
+ {"id": PropertyRef("PROJECT_ID", set_in_kwargs=True)}
57
+ )
58
+ direction: LinkDirection = LinkDirection.INWARD
59
+ rel_label: str = "RESOURCE"
60
+ properties: GCPGKEClusterToProjectRelProperties = (
61
+ GCPGKEClusterToProjectRelProperties()
62
+ )
63
+
64
+
65
+ @dataclass(frozen=True)
66
+ class GCPGKEClusterSchema(CartographyNodeSchema):
67
+ label: str = "GKECluster"
68
+ properties: GCPGKEClusterNodeProperties = GCPGKEClusterNodeProperties()
69
+ sub_resource_relationship: GCPGKEClusterToProjectRel = GCPGKEClusterToProjectRel()
@@ -0,0 +1,63 @@
1
+ """
2
+ Data model for GitHub commit tracking, specifically for tracking which GitHubUsers have committed
3
+ to which GitHubRepositories in the last 30 days.
4
+
5
+ This uses MatchLinks to connect existing GitHubUser nodes to GitHubRepository nodes based on
6
+ commit data from a separate GitHub API call.
7
+ """
8
+
9
+ from dataclasses import dataclass
10
+
11
+ from cartography.models.core.common import PropertyRef
12
+ from cartography.models.core.relationships import CartographyRelProperties
13
+ from cartography.models.core.relationships import CartographyRelSchema
14
+ from cartography.models.core.relationships import LinkDirection
15
+ from cartography.models.core.relationships import make_source_node_matcher
16
+ from cartography.models.core.relationships import make_target_node_matcher
17
+ from cartography.models.core.relationships import SourceNodeMatcher
18
+ from cartography.models.core.relationships import TargetNodeMatcher
19
+
20
+
21
+ @dataclass(frozen=True)
22
+ class GitHubUserCommittedToRepoRelProperties(CartographyRelProperties):
23
+ """
24
+ Properties for the COMMITTED_TO relationship between GitHubUser and GitHubRepository.
25
+ """
26
+
27
+ # Required for all MatchLinks
28
+ lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
29
+ _sub_resource_label: PropertyRef = PropertyRef(
30
+ "_sub_resource_label", set_in_kwargs=True
31
+ )
32
+ _sub_resource_id: PropertyRef = PropertyRef("_sub_resource_id", set_in_kwargs=True)
33
+
34
+ # Rich relationship properties
35
+ commit_count: PropertyRef = PropertyRef("commit_count")
36
+ last_commit_date: PropertyRef = PropertyRef("last_commit_date")
37
+ first_commit_date: PropertyRef = PropertyRef("first_commit_date")
38
+
39
+
40
+ @dataclass(frozen=True)
41
+ class GitHubUserCommittedToRepoRel(CartographyRelSchema):
42
+ """
43
+ MatchLink schema for connecting GitHubUser nodes to GitHubRepository nodes
44
+ based on commits in the last 30 days.
45
+ """
46
+
47
+ target_node_label: str = "GitHubRepository"
48
+ target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
49
+ {
50
+ "id": PropertyRef("repo_url"),
51
+ }
52
+ )
53
+ source_node_label: str = "GitHubUser"
54
+ source_node_matcher: SourceNodeMatcher = make_source_node_matcher(
55
+ {
56
+ "id": PropertyRef("user_url"),
57
+ }
58
+ )
59
+ direction: LinkDirection = LinkDirection.OUTWARD
60
+ rel_label: str = "COMMITTED_TO"
61
+ properties: GitHubUserCommittedToRepoRelProperties = (
62
+ GitHubUserCommittedToRepoRelProperties()
63
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cartography
3
- Version: 0.113.0
3
+ Version: 0.115.0
4
4
  Summary: Explore assets and their relationships across your technical infrastructure.
5
5
  Maintainer: Cartography Contributors
6
6
  License-Expression: Apache-2.0
@@ -25,7 +25,7 @@ Requires-Dist: backoff>=2.1.2
25
25
  Requires-Dist: boto3>=1.15.1
26
26
  Requires-Dist: botocore>=1.18.1
27
27
  Requires-Dist: dnspython>=1.15.0
28
- Requires-Dist: neo4j>=4.4.4
28
+ Requires-Dist: neo4j>=5.28.2
29
29
  Requires-Dist: policyuniverse>=1.1.0.0
30
30
  Requires-Dist: google-api-python-client>=1.7.8
31
31
  Requires-Dist: google-auth>=2.37.0
@@ -42,6 +42,8 @@ Requires-Dist: azure-cli-core>=2.26.0
42
42
  Requires-Dist: azure-mgmt-compute>=5.0.0
43
43
  Requires-Dist: azure-mgmt-resource>=10.2.0
44
44
  Requires-Dist: azure-mgmt-cosmosdb>=6.0.0
45
+ Requires-Dist: azure-mgmt-web>=7.0.0
46
+ Requires-Dist: azure-mgmt-logic>=10.0.0
45
47
  Requires-Dist: msrestazure>=0.6.4
46
48
  Requires-Dist: azure-mgmt-storage>=16.0.0
47
49
  Requires-Dist: azure-mgmt-sql<=1.0.0
@@ -55,6 +57,7 @@ Requires-Dist: xmltodict
55
57
  Requires-Dist: duo-client
56
58
  Requires-Dist: cloudflare<5.0.0,>=4.1.0
57
59
  Requires-Dist: scaleway>=2.9.0
60
+ Requires-Dist: google-cloud-resource-manager>=1.14.2
58
61
  Dynamic: license-file
59
62
 
60
63
  ![Cartography](docs/root/images/logo-horizontal.png)
@@ -95,10 +98,10 @@ You can learn more about the story behind Cartography in our [presentation at BS
95
98
  - [Keycloak](https://cartography-cncf.github.io/cartography/modules/keycloak/index.html) - Realms, Users, Groups, Roles, Scopes, Clients, IdentityProviders, Authentication Flows, Authentication Executions, Organizations, Organization Domains
96
99
  - [Kubernetes](https://cartography-cncf.github.io/cartography/modules/kubernetes/index.html) - Cluster, Namespace, Service, Pod, Container, ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding, OIDCProvider
97
100
  - [Lastpass](https://cartography-cncf.github.io/cartography/modules/lastpass/index.html) - users
98
- - [Microsoft Azure](https://cartography-cncf.github.io/cartography/modules/azure/index.html) - CosmosDB, SQL, Storage, Virtual Machine
99
- - [Microsoft Entra ID](https://cartography-cncf.github.io/cartography/modules/entra/index.html) - Users
101
+ - [Microsoft Azure](https://cartography-cncf.github.io/cartography/modules/azure/index.html) - App Service, CosmosDB, Functions, Logic Apps, SQL, Storage, Virtual Machine
102
+ - [Microsoft Entra ID](https://cartography-cncf.github.io/cartography/modules/entra/index.html) - Users, Groups, Applications, OUs, App Roles, federation to AWS Identity Center
100
103
  - [NIST CVE](https://cartography-cncf.github.io/cartography/modules/cve/index.html) - Common Vulnerabilities and Exposures (CVE) data from NIST database
101
- - [Okta](https://cartography-cncf.github.io/cartography/modules/okta/index.html) - users, groups, organizations, roles, applications, factors, trusted origins, reply URIs
104
+ - [Okta](https://cartography-cncf.github.io/cartography/modules/okta/index.html) - users, groups, organizations, roles, applications, factors, trusted origins, reply URIs, federation to AWS roles, federation to AWS Identity Center
102
105
  - [OpenAI](https://cartography-cncf.github.io/cartography/modules/openai/index.html) - Organization, AdminApiKey, User, Project, ServiceAccount, ApiKey
103
106
  - [Oracle Cloud Infrastructure](https://cartography-cncf.github.io/cartography/modules/oci/index.html) - IAM
104
107
  - [PagerDuty](https://cartography-cncf.github.io/cartography/modules/pagerduty/index.html) - Users, teams, services, schedules, escalation policies, integrations, vendors