cartography 0.112.0__py3-none-any.whl → 0.114.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 +8 -0
- cartography/config.py +4 -0
- cartography/data/indexes.cypher +0 -31
- cartography/intel/aws/apigatewayv2.py +116 -0
- cartography/intel/aws/iam.py +741 -492
- cartography/intel/aws/organizations.py +7 -8
- cartography/intel/aws/permission_relationships.py +4 -16
- cartography/intel/aws/resources.py +2 -0
- cartography/intel/azure/__init__.py +16 -0
- cartography/intel/azure/app_service.py +105 -0
- cartography/intel/azure/functions.py +124 -0
- cartography/intel/entra/__init__.py +31 -0
- cartography/intel/entra/app_role_assignments.py +277 -0
- cartography/intel/entra/applications.py +4 -238
- cartography/intel/entra/federation/__init__.py +0 -0
- cartography/intel/entra/federation/aws_identity_center.py +77 -0
- cartography/intel/entra/service_principals.py +217 -0
- cartography/intel/gcp/__init__.py +136 -436
- cartography/intel/gcp/clients.py +65 -0
- cartography/intel/gcp/compute.py +18 -44
- cartography/intel/gcp/crm/__init__.py +0 -0
- cartography/intel/gcp/crm/folders.py +108 -0
- cartography/intel/gcp/crm/orgs.py +65 -0
- cartography/intel/gcp/crm/projects.py +109 -0
- cartography/intel/gcp/dns.py +82 -169
- cartography/intel/gcp/gke.py +72 -113
- cartography/intel/gcp/iam.py +66 -54
- cartography/intel/gcp/storage.py +75 -159
- cartography/intel/github/__init__.py +41 -0
- cartography/intel/github/commits.py +423 -0
- cartography/intel/github/repos.py +73 -39
- cartography/models/aws/apigatewayv2/__init__.py +0 -0
- cartography/models/aws/apigatewayv2/apigatewayv2.py +53 -0
- cartography/models/aws/iam/access_key.py +103 -0
- cartography/models/aws/iam/account_role.py +24 -0
- cartography/models/aws/iam/federated_principal.py +60 -0
- cartography/models/aws/iam/group.py +60 -0
- cartography/models/aws/iam/group_membership.py +26 -0
- cartography/models/aws/iam/inline_policy.py +78 -0
- cartography/models/aws/iam/managed_policy.py +51 -0
- cartography/models/aws/iam/policy_statement.py +57 -0
- cartography/models/aws/iam/role.py +83 -0
- cartography/models/aws/iam/root_principal.py +52 -0
- cartography/models/aws/iam/service_principal.py +30 -0
- cartography/models/aws/iam/sts_assumerole_allow.py +38 -0
- cartography/models/aws/iam/user.py +54 -0
- cartography/models/azure/__init__.py +0 -0
- cartography/models/azure/app_service.py +59 -0
- cartography/models/azure/function_app.py +59 -0
- cartography/models/entra/entra_user_to_aws_sso.py +41 -0
- cartography/models/entra/service_principal.py +104 -0
- cartography/models/gcp/compute/subnet.py +74 -0
- cartography/models/gcp/crm/__init__.py +0 -0
- cartography/models/gcp/crm/folders.py +98 -0
- cartography/models/gcp/crm/organizations.py +21 -0
- cartography/models/gcp/crm/projects.py +100 -0
- cartography/models/gcp/dns.py +109 -0
- cartography/models/gcp/gke.py +69 -0
- cartography/models/gcp/iam.py +3 -0
- cartography/models/gcp/storage/__init__.py +0 -0
- cartography/models/gcp/storage/bucket.py +119 -0
- cartography/models/github/commits.py +63 -0
- {cartography-0.112.0.dist-info → cartography-0.114.0.dist-info}/METADATA +7 -5
- {cartography-0.112.0.dist-info → cartography-0.114.0.dist-info}/RECORD +69 -39
- cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -17
- cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -30
- cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -13
- cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -8
- cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -35
- cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -17
- cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -23
- cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -29
- cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -17
- cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -29
- cartography/intel/gcp/crm.py +0 -355
- {cartography-0.112.0.dist-info → cartography-0.114.0.dist-info}/WHEEL +0 -0
- {cartography-0.112.0.dist-info → cartography-0.114.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.112.0.dist-info → cartography-0.114.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.112.0.dist-info → cartography-0.114.0.dist-info}/top_level.txt +0 -0
cartography/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0,
|
|
31
|
+
__version__ = version = '0.114.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 114, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
cartography/cli.py
CHANGED
|
@@ -328,6 +328,14 @@ class CLI:
|
|
|
328
328
|
"Required if you are using the GitHub intel module. Ignored otherwise."
|
|
329
329
|
),
|
|
330
330
|
)
|
|
331
|
+
parser.add_argument(
|
|
332
|
+
"--github-commit-lookback-days",
|
|
333
|
+
type=int,
|
|
334
|
+
default=30,
|
|
335
|
+
help=(
|
|
336
|
+
"Number of days to look back for tracking GitHub users committing to repositories. Defaults to 30 days."
|
|
337
|
+
),
|
|
338
|
+
)
|
|
331
339
|
parser.add_argument(
|
|
332
340
|
"--digitalocean-token-env-var",
|
|
333
341
|
type=str,
|
cartography/config.py
CHANGED
|
@@ -70,6 +70,8 @@ class Config:
|
|
|
70
70
|
:param okta_saml_role_regex: The regex used to map okta groups to AWS roles. Optional.
|
|
71
71
|
:type github_config: str
|
|
72
72
|
:param github_config: Base64 encoded config object for GitHub ingestion. Optional.
|
|
73
|
+
:type github_commit_lookback_days: int
|
|
74
|
+
:param github_commit_lookback_days: Number of days to look back for GitHub commit tracking. Optional.
|
|
73
75
|
:type digitalocean_token: str
|
|
74
76
|
:param digitalocean_token: DigitalOcean access token. Optional.
|
|
75
77
|
:type permission_relationships_file: str
|
|
@@ -210,6 +212,7 @@ class Config:
|
|
|
210
212
|
okta_api_key=None,
|
|
211
213
|
okta_saml_role_regex=None,
|
|
212
214
|
github_config=None,
|
|
215
|
+
github_commit_lookback_days=30,
|
|
213
216
|
digitalocean_token=None,
|
|
214
217
|
permission_relationships_file=None,
|
|
215
218
|
jamf_base_uri=None,
|
|
@@ -301,6 +304,7 @@ class Config:
|
|
|
301
304
|
self.okta_api_key = okta_api_key
|
|
302
305
|
self.okta_saml_role_regex = okta_saml_role_regex
|
|
303
306
|
self.github_config = github_config
|
|
307
|
+
self.github_commit_lookback_days = github_commit_lookback_days
|
|
304
308
|
self.digitalocean_token = digitalocean_token
|
|
305
309
|
self.permission_relationships_file = permission_relationships_file
|
|
306
310
|
self.jamf_base_uri = jamf_base_uri
|
cartography/data/indexes.cypher
CHANGED
|
@@ -21,23 +21,12 @@ CREATE INDEX IF NOT EXISTS FOR (n:AWSDNSRecord) ON (n.lastupdated);
|
|
|
21
21
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSDNSZone) ON (n.name);
|
|
22
22
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSDNSZone) ON (n.zoneid);
|
|
23
23
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSDNSZone) ON (n.lastupdated);
|
|
24
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSGroup) ON (n.arn);
|
|
25
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSGroup) ON (n.lastupdated);
|
|
26
24
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSInternetGateway) ON (n.id);
|
|
27
25
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSInternetGateway) ON (n.lastupdated);
|
|
28
26
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSIpv4CidrBlock) ON (n.id);
|
|
29
27
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSIpv4CidrBlock) ON (n.lastupdated);
|
|
30
28
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSIpv6CidrBlock) ON (n.id);
|
|
31
29
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSIpv6CidrBlock) ON (n.lastupdated);
|
|
32
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSPolicy) ON (n.id);
|
|
33
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSPolicy) ON (n.name);
|
|
34
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSPolicy) ON (n.lastupdated);
|
|
35
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSPolicyStatement) ON (n.id);
|
|
36
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSPolicyStatement) ON (n.lastupdated);
|
|
37
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSPrincipal) ON (n.arn);
|
|
38
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSPrincipal) ON (n.lastupdated);
|
|
39
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSRole) ON (n.arn);
|
|
40
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSRole) ON (n.lastupdated);
|
|
41
30
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSTag) ON (n.id);
|
|
42
31
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSTag) ON (n.key);
|
|
43
32
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSTag) ON (n.lastupdated);
|
|
@@ -46,11 +35,6 @@ CREATE INDEX IF NOT EXISTS FOR (n:AWSTransitGateway) ON (n.id);
|
|
|
46
35
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSTransitGateway) ON (n.lastupdated);
|
|
47
36
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSTransitGatewayAttachment) ON (n.id);
|
|
48
37
|
CREATE INDEX IF NOT EXISTS FOR (n:AWSTransitGatewayAttachment) ON (n.lastupdated);
|
|
49
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSUser) ON (n.arn);
|
|
50
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSUser) ON (n.name);
|
|
51
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AWSUser) ON (n.lastupdated);
|
|
52
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AccountAccessKey) ON (n.accesskeyid);
|
|
53
|
-
CREATE INDEX IF NOT EXISTS FOR (n:AccountAccessKey) ON (n.lastupdated);
|
|
54
38
|
CREATE INDEX IF NOT EXISTS FOR (n:AutoScalingGroup) ON (n.arn);
|
|
55
39
|
CREATE INDEX IF NOT EXISTS FOR (n:AutoScalingGroup) ON (n.lastupdated);
|
|
56
40
|
CREATE INDEX IF NOT EXISTS FOR (n:CVE) ON (n.id);
|
|
@@ -100,12 +84,6 @@ CREATE INDEX IF NOT EXISTS FOR (n:ESDomain) ON (n.arn);
|
|
|
100
84
|
CREATE INDEX IF NOT EXISTS FOR (n:ESDomain) ON (n.id);
|
|
101
85
|
CREATE INDEX IF NOT EXISTS FOR (n:ESDomain) ON (n.name);
|
|
102
86
|
CREATE INDEX IF NOT EXISTS FOR (n:ESDomain) ON (n.lastupdated);
|
|
103
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPDNSZone) ON (n.id);
|
|
104
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPDNSZone) ON (n.lastupdated);
|
|
105
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPRecordSet) ON (n.id);
|
|
106
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPRecordSet) ON (n.lastupdated);
|
|
107
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPFolder) ON (n.id);
|
|
108
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPFolder) ON (n.lastupdated);
|
|
109
87
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPForwardingRule) ON (n.id);
|
|
110
88
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPForwardingRule) ON (n.lastupdated);
|
|
111
89
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPInstance) ON (n.id);
|
|
@@ -116,23 +94,14 @@ CREATE INDEX IF NOT EXISTS FOR (n:GCPNetworkTag) ON (n.id);
|
|
|
116
94
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPNetworkTag) ON (n.lastupdated);
|
|
117
95
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPNicAccessConfig) ON (n.id);
|
|
118
96
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPNicAccessConfig) ON (n.lastupdated);
|
|
119
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPOrganization) ON (n.id);
|
|
120
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPOrganization) ON (n.lastupdated);
|
|
121
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPProject) ON (n.id);
|
|
122
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPProject) ON (n.projectnumber);
|
|
123
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPProject) ON (n.lastupdated);
|
|
124
97
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPBucket) ON (n.id);
|
|
125
98
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPBucket) ON (n.lastupdated);
|
|
126
99
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPBucketLabel) ON (n.key);
|
|
127
100
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPBucketLabel) ON (n.lastupdated);
|
|
128
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPSubnet) ON (n.id);
|
|
129
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GCPSubnet) ON (n.lastupdated);
|
|
130
101
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPVpc) ON (n.id);
|
|
131
102
|
CREATE INDEX IF NOT EXISTS FOR (n:GCPVpc) ON (n.lastupdated);
|
|
132
103
|
CREATE INDEX IF NOT EXISTS FOR (n:GitHubRepository) ON (n.id);
|
|
133
104
|
CREATE INDEX IF NOT EXISTS FOR (n:GitHubRepository) ON (n.lastupdated);
|
|
134
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GKECluster) ON (n.id);
|
|
135
|
-
CREATE INDEX IF NOT EXISTS FOR (n:GKECluster) ON (n.lastupdated);
|
|
136
105
|
CREATE INDEX IF NOT EXISTS FOR (n:GSuiteGroup) ON (n.email);
|
|
137
106
|
CREATE INDEX IF NOT EXISTS FOR (n:GSuiteGroup) ON (n.id);
|
|
138
107
|
CREATE INDEX IF NOT EXISTS FOR (n:GSuiteGroup) ON (n.lastupdated);
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import boto3
|
|
5
|
+
import neo4j
|
|
6
|
+
|
|
7
|
+
from cartography.client.core.tx import load
|
|
8
|
+
from cartography.graph.job import GraphJob
|
|
9
|
+
from cartography.models.aws.apigatewayv2.apigatewayv2 import APIGatewayV2APISchema
|
|
10
|
+
from cartography.util import aws_handle_regions
|
|
11
|
+
from cartography.util import timeit
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@timeit
|
|
17
|
+
@aws_handle_regions
|
|
18
|
+
def get_apigatewayv2_apis(
|
|
19
|
+
boto3_session: boto3.session.Session,
|
|
20
|
+
region: str,
|
|
21
|
+
) -> list[dict[str, Any]]:
|
|
22
|
+
client = boto3_session.client("apigatewayv2", region_name=region)
|
|
23
|
+
paginator = client.get_paginator("get_apis")
|
|
24
|
+
apis: list[dict[str, Any]] = []
|
|
25
|
+
for page in paginator.paginate():
|
|
26
|
+
apis.extend(page.get("Items", []))
|
|
27
|
+
return apis
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def transform_apigatewayv2_apis(apis: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
31
|
+
transformed: list[dict[str, Any]] = []
|
|
32
|
+
for api in apis:
|
|
33
|
+
transformed.append(
|
|
34
|
+
{
|
|
35
|
+
"id": api.get("ApiId"),
|
|
36
|
+
"name": api.get("Name"),
|
|
37
|
+
"protocoltype": api.get("ProtocolType"),
|
|
38
|
+
"routeselectionexpression": api.get("RouteSelectionExpression"),
|
|
39
|
+
"apikeyselectionexpression": api.get("ApiKeySelectionExpression"),
|
|
40
|
+
"apiendpoint": api.get("ApiEndpoint"),
|
|
41
|
+
"version": api.get("Version"),
|
|
42
|
+
"createddate": api.get("CreatedDate"),
|
|
43
|
+
"description": api.get("Description"),
|
|
44
|
+
},
|
|
45
|
+
)
|
|
46
|
+
return transformed
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@timeit
|
|
50
|
+
def load_apigatewayv2_apis(
|
|
51
|
+
neo4j_session: neo4j.Session,
|
|
52
|
+
data: list[dict[str, Any]],
|
|
53
|
+
region: str,
|
|
54
|
+
current_aws_account_id: str,
|
|
55
|
+
update_tag: int,
|
|
56
|
+
) -> None:
|
|
57
|
+
load(
|
|
58
|
+
neo4j_session,
|
|
59
|
+
APIGatewayV2APISchema(),
|
|
60
|
+
data,
|
|
61
|
+
lastupdated=update_tag,
|
|
62
|
+
AWS_ID=current_aws_account_id,
|
|
63
|
+
region=region,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@timeit
|
|
68
|
+
def cleanup(
|
|
69
|
+
neo4j_session: neo4j.Session, common_job_parameters: dict[str, Any]
|
|
70
|
+
) -> None:
|
|
71
|
+
GraphJob.from_node_schema(
|
|
72
|
+
APIGatewayV2APISchema(),
|
|
73
|
+
common_job_parameters,
|
|
74
|
+
).run(neo4j_session)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@timeit
|
|
78
|
+
def sync_apigatewayv2_apis(
|
|
79
|
+
neo4j_session: neo4j.Session,
|
|
80
|
+
boto3_session: boto3.session.Session,
|
|
81
|
+
region: str,
|
|
82
|
+
current_aws_account_id: str,
|
|
83
|
+
aws_update_tag: int,
|
|
84
|
+
) -> None:
|
|
85
|
+
apis = get_apigatewayv2_apis(boto3_session, region)
|
|
86
|
+
transformed = transform_apigatewayv2_apis(apis)
|
|
87
|
+
load_apigatewayv2_apis(
|
|
88
|
+
neo4j_session,
|
|
89
|
+
transformed,
|
|
90
|
+
region,
|
|
91
|
+
current_aws_account_id,
|
|
92
|
+
aws_update_tag,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@timeit
|
|
97
|
+
def sync(
|
|
98
|
+
neo4j_session: neo4j.Session,
|
|
99
|
+
boto3_session: boto3.session.Session,
|
|
100
|
+
regions: list[str],
|
|
101
|
+
current_aws_account_id: str,
|
|
102
|
+
update_tag: int,
|
|
103
|
+
common_job_parameters: dict[str, Any],
|
|
104
|
+
) -> None:
|
|
105
|
+
for region in regions:
|
|
106
|
+
logger.info(
|
|
107
|
+
f"Syncing AWS APIGatewayV2 APIs for region '{region}' in account '{current_aws_account_id}'.",
|
|
108
|
+
)
|
|
109
|
+
sync_apigatewayv2_apis(
|
|
110
|
+
neo4j_session,
|
|
111
|
+
boto3_session,
|
|
112
|
+
region,
|
|
113
|
+
current_aws_account_id,
|
|
114
|
+
update_tag,
|
|
115
|
+
)
|
|
116
|
+
cleanup(neo4j_session, common_job_parameters)
|