cartography 0.109.0rc1__py3-none-any.whl → 0.110.0rc1__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 +22 -0
- cartography/config.py +13 -0
- cartography/data/indexes.cypher +0 -15
- cartography/intel/aws/cloudtrail_management_events.py +21 -0
- cartography/intel/aws/eventbridge.py +91 -0
- cartography/intel/aws/glue.py +117 -0
- cartography/intel/aws/identitycenter.py +71 -23
- cartography/intel/aws/kms.py +160 -200
- cartography/intel/aws/lambda_function.py +206 -190
- cartography/intel/aws/rds.py +243 -458
- cartography/intel/aws/resources.py +4 -0
- cartography/intel/aws/route53.py +334 -332
- cartography/intel/entra/__init__.py +43 -41
- cartography/intel/entra/applications.py +1 -2
- cartography/intel/entra/ou.py +1 -1
- cartography/intel/entra/resources.py +20 -0
- cartography/intel/trivy/__init__.py +73 -13
- cartography/intel/trivy/scanner.py +115 -92
- cartography/models/aws/eventbridge/__init__.py +0 -0
- cartography/models/aws/eventbridge/rule.py +77 -0
- cartography/models/aws/glue/__init__.py +0 -0
- cartography/models/aws/glue/connection.py +51 -0
- cartography/models/aws/identitycenter/awspermissionset.py +44 -0
- cartography/models/aws/kms/__init__.py +0 -0
- cartography/models/aws/kms/aliases.py +86 -0
- cartography/models/aws/kms/grants.py +65 -0
- cartography/models/aws/kms/keys.py +88 -0
- cartography/models/aws/lambda_function/__init__.py +0 -0
- cartography/models/aws/lambda_function/alias.py +74 -0
- cartography/models/aws/lambda_function/event_source_mapping.py +88 -0
- cartography/models/aws/lambda_function/lambda_function.py +89 -0
- cartography/models/aws/lambda_function/layer.py +72 -0
- cartography/models/aws/rds/__init__.py +0 -0
- cartography/models/aws/rds/cluster.py +89 -0
- cartography/models/aws/rds/instance.py +154 -0
- cartography/models/aws/rds/snapshot.py +108 -0
- cartography/models/aws/rds/subnet_group.py +101 -0
- cartography/models/aws/route53/__init__.py +0 -0
- cartography/models/aws/route53/dnsrecord.py +214 -0
- cartography/models/aws/route53/nameserver.py +63 -0
- cartography/models/aws/route53/subzone.py +40 -0
- cartography/models/aws/route53/zone.py +47 -0
- cartography/models/snipeit/asset.py +1 -0
- cartography/util.py +8 -1
- {cartography-0.109.0rc1.dist-info → cartography-0.110.0rc1.dist-info}/METADATA +2 -2
- {cartography-0.109.0rc1.dist-info → cartography-0.110.0rc1.dist-info}/RECORD +51 -32
- cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -65
- cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +0 -16
- cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -50
- cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -47
- cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -23
- cartography/data/jobs/cleanup/aws_kms_details.json +0 -10
- {cartography-0.109.0rc1.dist-info → cartography-0.110.0rc1.dist-info}/WHEEL +0 -0
- {cartography-0.109.0rc1.dist-info → cartography-0.110.0rc1.dist-info}/entry_points.txt +0 -0
- {cartography-0.109.0rc1.dist-info → cartography-0.110.0rc1.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.109.0rc1.dist-info → cartography-0.110.0rc1.dist-info}/top_level.txt +0 -0
cartography/intel/aws/kms.py
CHANGED
|
@@ -4,8 +4,6 @@ from typing import Any
|
|
|
4
4
|
from typing import Dict
|
|
5
5
|
from typing import Generator
|
|
6
6
|
from typing import List
|
|
7
|
-
from typing import Optional
|
|
8
|
-
from typing import Tuple
|
|
9
7
|
|
|
10
8
|
import boto3
|
|
11
9
|
import botocore
|
|
@@ -13,8 +11,13 @@ import neo4j
|
|
|
13
11
|
from botocore.exceptions import ClientError
|
|
14
12
|
from policyuniverse.policy import Policy
|
|
15
13
|
|
|
14
|
+
from cartography.client.core.tx import load
|
|
15
|
+
from cartography.graph.job import GraphJob
|
|
16
|
+
from cartography.models.aws.kms.aliases import KMSAliasSchema
|
|
17
|
+
from cartography.models.aws.kms.grants import KMSGrantSchema
|
|
18
|
+
from cartography.models.aws.kms.keys import KMSKeySchema
|
|
16
19
|
from cartography.util import aws_handle_regions
|
|
17
|
-
from cartography.util import
|
|
20
|
+
from cartography.util import dict_date_to_epoch
|
|
18
21
|
from cartography.util import timeit
|
|
19
22
|
|
|
20
23
|
logger = logging.getLogger(__name__)
|
|
@@ -51,7 +54,7 @@ def get_kms_key_list(boto3_session: boto3.session.Session, region: str) -> List[
|
|
|
51
54
|
@aws_handle_regions
|
|
52
55
|
def get_kms_key_details(
|
|
53
56
|
boto3_session: boto3.session.Session,
|
|
54
|
-
kms_key_data: Dict,
|
|
57
|
+
kms_key_data: List[Dict],
|
|
55
58
|
region: str,
|
|
56
59
|
) -> Generator[Any, Any, Any]:
|
|
57
60
|
"""
|
|
@@ -120,249 +123,176 @@ def get_grants(key: Dict, client: botocore.client.BaseClient) -> List[Any]:
|
|
|
120
123
|
|
|
121
124
|
|
|
122
125
|
@timeit
|
|
123
|
-
def
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
) -> None:
|
|
126
|
+
def transform_kms_aliases(aliases: List[Dict]) -> List[Dict]:
|
|
127
|
+
"""
|
|
128
|
+
Transform AWS KMS Aliases to match the data model.
|
|
129
|
+
Converts datetime fields to epoch timestamps for consistency.
|
|
128
130
|
"""
|
|
129
|
-
|
|
131
|
+
transformed_data = []
|
|
132
|
+
for alias in aliases:
|
|
133
|
+
transformed = dict(alias)
|
|
134
|
+
|
|
135
|
+
# Convert datetime fields to epoch timestamps
|
|
136
|
+
transformed["CreationDate"] = dict_date_to_epoch(alias, "CreationDate")
|
|
137
|
+
transformed["LastUpdatedDate"] = dict_date_to_epoch(alias, "LastUpdatedDate")
|
|
138
|
+
|
|
139
|
+
transformed_data.append(transformed)
|
|
140
|
+
return transformed_data
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def transform_kms_keys(keys: List[Dict], policy_data: Dict[str, Dict]) -> List[Dict]:
|
|
130
144
|
"""
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
ON CREATE SET a.firstseen = timestamp(), a.targetkeyid = alias.TargetKeyId
|
|
135
|
-
SET a.aliasname = alias.AliasName, a.lastupdated = $UpdateTag
|
|
136
|
-
WITH a, alias
|
|
137
|
-
MATCH (kmskey:KMSKey{id: alias.TargetKeyId})
|
|
138
|
-
MERGE (a)-[r:KNOWN_AS]->(kmskey)
|
|
139
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
140
|
-
SET r.lastupdated = $UpdateTag
|
|
145
|
+
Transform AWS KMS Keys to match the data model.
|
|
146
|
+
Converts datetime fields to epoch timestamps for consistency.
|
|
147
|
+
Includes policy analysis properties.
|
|
141
148
|
"""
|
|
149
|
+
transformed_data = []
|
|
150
|
+
for key in keys:
|
|
151
|
+
transformed = dict(key)
|
|
142
152
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
)
|
|
153
|
+
# Convert datetime fields to epoch timestamps
|
|
154
|
+
transformed["CreationDate"] = dict_date_to_epoch(key, "CreationDate")
|
|
155
|
+
transformed["DeletionDate"] = dict_date_to_epoch(key, "DeletionDate")
|
|
156
|
+
transformed["ValidTo"] = dict_date_to_epoch(key, "ValidTo")
|
|
148
157
|
|
|
158
|
+
# Add policy analysis
|
|
159
|
+
transformed.update(policy_data[key["KeyId"]])
|
|
149
160
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
) -> None:
|
|
161
|
+
transformed_data.append(transformed)
|
|
162
|
+
return transformed_data
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def transform_kms_grants(grants: List[Dict]) -> List[Dict]:
|
|
156
166
|
"""
|
|
157
|
-
|
|
167
|
+
Transform AWS KMS Grants to match the data model.
|
|
168
|
+
Converts datetime fields to epoch timestamps for consistency.
|
|
169
|
+
"""
|
|
170
|
+
transformed_data = []
|
|
171
|
+
for grant in grants:
|
|
172
|
+
transformed = dict(grant)
|
|
173
|
+
|
|
174
|
+
# Convert datetime fields to epoch timestamps
|
|
175
|
+
transformed["CreationDate"] = dict_date_to_epoch(grant, "CreationDate")
|
|
176
|
+
|
|
177
|
+
transformed_data.append(transformed)
|
|
178
|
+
return transformed_data
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def transform_kms_key_policies(
|
|
182
|
+
policy_alias_grants_data: list[tuple],
|
|
183
|
+
) -> dict[str, dict[str, Any]]:
|
|
158
184
|
"""
|
|
159
|
-
|
|
160
|
-
UNWIND $grants AS grant
|
|
161
|
-
MERGE (g:KMSGrant{id: grant.GrantId})
|
|
162
|
-
ON CREATE SET g.firstseen = timestamp(), g.granteeprincipal = grant.GranteePrincipal,
|
|
163
|
-
g.creationdate = grant.CreationDate
|
|
164
|
-
SET g.name = grant.GrantName, g.lastupdated = $UpdateTag
|
|
165
|
-
WITH g, grant
|
|
166
|
-
MATCH (kmskey:KMSKey{id: grant.KeyId})
|
|
167
|
-
MERGE (g)-[r:APPLIED_ON]->(kmskey)
|
|
168
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
169
|
-
SET r.lastupdated = $UpdateTag
|
|
185
|
+
Transform KMS key policy data for inclusion in key records.
|
|
170
186
|
"""
|
|
187
|
+
policy_data = {}
|
|
171
188
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
grant["CreationDate"] = str(grant["CreationDate"])
|
|
189
|
+
for key_id, policy, *_ in policy_alias_grants_data:
|
|
190
|
+
parsed_policy = parse_policy(key_id, policy)
|
|
191
|
+
policy_data[key_id] = parsed_policy
|
|
176
192
|
|
|
177
|
-
|
|
178
|
-
ingest_grants,
|
|
179
|
-
grants=grants_list,
|
|
180
|
-
UpdateTag=update_tag,
|
|
181
|
-
)
|
|
193
|
+
return policy_data
|
|
182
194
|
|
|
183
195
|
|
|
184
196
|
@timeit
|
|
185
|
-
def
|
|
197
|
+
def load_kms_aliases(
|
|
186
198
|
neo4j_session: neo4j.Session,
|
|
187
|
-
|
|
199
|
+
aliases: List[Dict],
|
|
200
|
+
region: str,
|
|
201
|
+
aws_account_id: str,
|
|
188
202
|
update_tag: int,
|
|
189
203
|
) -> None:
|
|
190
204
|
"""
|
|
191
|
-
|
|
192
|
-
"""
|
|
193
|
-
# NOTE we use the coalesce function so appending works when the value is null initially
|
|
194
|
-
ingest_policies = """
|
|
195
|
-
UNWIND $policies AS policy
|
|
196
|
-
MATCH (k:KMSKey) where k.name = policy.kms_key
|
|
197
|
-
SET k.anonymous_access = (coalesce(k.anonymous_access, false) OR policy.internet_accessible),
|
|
198
|
-
k.anonymous_actions = coalesce(k.anonymous_actions, []) + policy.accessible_actions,
|
|
199
|
-
k.lastupdated = $UpdateTag
|
|
200
|
-
"""
|
|
201
|
-
|
|
202
|
-
neo4j_session.run(
|
|
203
|
-
ingest_policies,
|
|
204
|
-
policies=policies,
|
|
205
|
-
UpdateTag=update_tag,
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
def _set_default_values(neo4j_session: neo4j.Session, aws_account_id: str) -> None:
|
|
210
|
-
set_defaults = """
|
|
211
|
-
MATCH (:AWSAccount{id: $AWS_ID})-[:RESOURCE]->(kmskey:KMSKey) where kmskey.anonymous_actions IS NULL
|
|
212
|
-
SET kmskey.anonymous_access = false, kmskey.anonymous_actions = []
|
|
205
|
+
Load KMS Aliases into Neo4j using the data model.
|
|
213
206
|
"""
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
207
|
+
logger.info(f"Loading {len(aliases)} KMS aliases for region {region} into graph.")
|
|
208
|
+
load(
|
|
209
|
+
neo4j_session,
|
|
210
|
+
KMSAliasSchema(),
|
|
211
|
+
aliases,
|
|
212
|
+
lastupdated=update_tag,
|
|
213
|
+
Region=region,
|
|
217
214
|
AWS_ID=aws_account_id,
|
|
218
215
|
)
|
|
219
216
|
|
|
220
217
|
|
|
221
218
|
@timeit
|
|
222
|
-
def
|
|
219
|
+
def load_kms_grants(
|
|
223
220
|
neo4j_session: neo4j.Session,
|
|
224
|
-
|
|
225
|
-
region: str,
|
|
221
|
+
grants: List[Dict],
|
|
226
222
|
aws_account_id: str,
|
|
227
223
|
update_tag: int,
|
|
228
224
|
) -> None:
|
|
229
225
|
"""
|
|
230
|
-
|
|
226
|
+
Load KMS Grants into Neo4j using the data model.
|
|
231
227
|
"""
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
grants: List[str] = []
|
|
235
|
-
for key, policy, alias, grant in policy_alias_grants_data:
|
|
236
|
-
parsed_policy = parse_policy(key, policy)
|
|
237
|
-
if parsed_policy is not None:
|
|
238
|
-
policies.append(parsed_policy)
|
|
239
|
-
if len(alias) > 0:
|
|
240
|
-
aliases.extend(alias)
|
|
241
|
-
if len(grants) > 0:
|
|
242
|
-
grants.extend(grant)
|
|
243
|
-
|
|
244
|
-
# cleanup existing policy properties
|
|
245
|
-
run_cleanup_job(
|
|
246
|
-
"aws_kms_details.json",
|
|
228
|
+
logger.info(f"Loading {len(grants)} KMS grants into graph.")
|
|
229
|
+
load(
|
|
247
230
|
neo4j_session,
|
|
248
|
-
|
|
231
|
+
KMSGrantSchema(),
|
|
232
|
+
grants,
|
|
233
|
+
lastupdated=update_tag,
|
|
234
|
+
AWS_ID=aws_account_id,
|
|
249
235
|
)
|
|
250
236
|
|
|
251
|
-
_load_kms_key_policies(neo4j_session, policies, update_tag)
|
|
252
|
-
_load_kms_key_aliases(neo4j_session, aliases, update_tag)
|
|
253
|
-
_load_kms_key_grants(neo4j_session, grants, update_tag)
|
|
254
|
-
_set_default_values(neo4j_session, aws_account_id)
|
|
255
|
-
|
|
256
237
|
|
|
257
238
|
@timeit
|
|
258
|
-
def parse_policy(key: str, policy: Policy) ->
|
|
239
|
+
def parse_policy(key: str, policy: Policy) -> dict[str, Any]:
|
|
259
240
|
"""
|
|
260
|
-
Uses PolicyUniverse to parse KMS key policies and returns the internet accessibility results
|
|
241
|
+
Uses PolicyUniverse to parse KMS key policies and returns the internet accessibility results.
|
|
242
|
+
Expects policy to never be None
|
|
261
243
|
"""
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
# "Statement": [
|
|
271
|
-
# {
|
|
272
|
-
# "Sid": "Enable IAM User Permissions",
|
|
273
|
-
# "Effect": "Allow",
|
|
274
|
-
# "Principal": {
|
|
275
|
-
# "AWS": "arn:aws:iam::123456789012:root"
|
|
276
|
-
# },
|
|
277
|
-
# "Action": "kms:*",
|
|
278
|
-
# "Resource": "*"
|
|
279
|
-
# },
|
|
280
|
-
# {
|
|
281
|
-
# "Sid": "Allow access for Key Administrators",
|
|
282
|
-
# "Effect": "Allow",
|
|
283
|
-
# "Principal": {
|
|
284
|
-
# "AWS": "arn:aws:iam::123456789012:role/ec2-manager"
|
|
285
|
-
# },
|
|
286
|
-
# "Action": [
|
|
287
|
-
# "kms:Create*",
|
|
288
|
-
# "kms:Describe*",
|
|
289
|
-
# "kms:Enable*",
|
|
290
|
-
# "kms:List*",
|
|
291
|
-
# "kms:Put*",
|
|
292
|
-
# "kms:Update*",
|
|
293
|
-
# "kms:Revoke*",
|
|
294
|
-
# "kms:Disable*",
|
|
295
|
-
# "kms:Get*",
|
|
296
|
-
# "kms:Delete*",
|
|
297
|
-
# "kms:ScheduleKeyDeletion",
|
|
298
|
-
# "kms:CancelKeyDeletion"
|
|
299
|
-
# ],
|
|
300
|
-
# "Resource": "*"
|
|
301
|
-
# }
|
|
302
|
-
# ]
|
|
303
|
-
# }
|
|
304
|
-
if policy is not None:
|
|
305
|
-
# get just the policy element and convert to JSON because boto3 returns this as string
|
|
306
|
-
policy = Policy(json.loads(policy["Policy"]))
|
|
307
|
-
if policy.is_internet_accessible():
|
|
308
|
-
return {
|
|
309
|
-
"kms_key": key,
|
|
310
|
-
"internet_accessible": True,
|
|
311
|
-
"accessible_actions": list(policy.internet_accessible_actions()),
|
|
312
|
-
}
|
|
313
|
-
else:
|
|
314
|
-
return None
|
|
315
|
-
else:
|
|
316
|
-
return None
|
|
244
|
+
policy = Policy(json.loads(policy["Policy"]))
|
|
245
|
+
inet_actions = policy.internet_accessible_actions()
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
"kms_key": key,
|
|
249
|
+
"anonymous_access": policy.is_internet_accessible(),
|
|
250
|
+
"anonymous_actions": list(inet_actions) if inet_actions else [],
|
|
251
|
+
}
|
|
317
252
|
|
|
318
253
|
|
|
319
254
|
@timeit
|
|
320
255
|
def load_kms_keys(
|
|
321
256
|
neo4j_session: neo4j.Session,
|
|
322
|
-
|
|
257
|
+
keys: List[Dict],
|
|
323
258
|
region: str,
|
|
324
|
-
|
|
325
|
-
|
|
259
|
+
aws_account_id: str,
|
|
260
|
+
update_tag: int,
|
|
326
261
|
) -> None:
|
|
327
|
-
ingest_keys = """
|
|
328
|
-
UNWIND $key_list AS k
|
|
329
|
-
MERGE (kmskey:KMSKey{id:k.KeyId})
|
|
330
|
-
ON CREATE SET kmskey.firstseen = timestamp(),
|
|
331
|
-
kmskey.arn = k.Arn, kmskey.creationdate = k.CreationDate
|
|
332
|
-
SET kmskey.deletiondate = k.DeletionDate,
|
|
333
|
-
kmskey.validto = k.ValidTo,
|
|
334
|
-
kmskey.enabled = k.Enabled,
|
|
335
|
-
kmskey.keystate = k.KeyState,
|
|
336
|
-
kmskey.customkeystoreid = k.CustomKeyStoreId,
|
|
337
|
-
kmskey.cloudhsmclusterid = k.CloudHsmClusterId,
|
|
338
|
-
kmskey.lastupdated = $aws_update_tag,
|
|
339
|
-
kmskey.region = $Region
|
|
340
|
-
WITH kmskey
|
|
341
|
-
MATCH (aa:AWSAccount{id: $AWS_ACCOUNT_ID})
|
|
342
|
-
MERGE (aa)-[r:RESOURCE]->(kmskey)
|
|
343
|
-
ON CREATE SET r.firstseen = timestamp()
|
|
344
|
-
SET r.lastupdated = $aws_update_tag
|
|
345
262
|
"""
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
for
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
ingest_keys,
|
|
356
|
-
key_list=data,
|
|
263
|
+
Load KMS Keys into Neo4j using the data model.
|
|
264
|
+
Expects data to already be transformed by transform_kms_keys().
|
|
265
|
+
"""
|
|
266
|
+
logger.info(f"Loading {len(keys)} KMS keys for region {region} into graph.")
|
|
267
|
+
load(
|
|
268
|
+
neo4j_session,
|
|
269
|
+
KMSKeySchema(),
|
|
270
|
+
keys,
|
|
271
|
+
lastupdated=update_tag,
|
|
357
272
|
Region=region,
|
|
358
|
-
|
|
359
|
-
aws_update_tag=aws_update_tag,
|
|
273
|
+
AWS_ID=aws_account_id,
|
|
360
274
|
)
|
|
361
275
|
|
|
362
276
|
|
|
363
277
|
@timeit
|
|
364
278
|
def cleanup_kms(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
|
|
365
|
-
|
|
279
|
+
"""
|
|
280
|
+
Run KMS cleanup using schema-based GraphJobs for all node types.
|
|
281
|
+
"""
|
|
282
|
+
logger.debug("Running KMS cleanup using GraphJob for all node types")
|
|
283
|
+
|
|
284
|
+
# Clean up grants first (they depend on keys)
|
|
285
|
+
GraphJob.from_node_schema(KMSGrantSchema(), common_job_parameters).run(
|
|
286
|
+
neo4j_session
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
# Clean up aliases
|
|
290
|
+
GraphJob.from_node_schema(KMSAliasSchema(), common_job_parameters).run(
|
|
291
|
+
neo4j_session
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
# Clean up keys
|
|
295
|
+
GraphJob.from_node_schema(KMSKeySchema(), common_job_parameters).run(neo4j_session)
|
|
366
296
|
|
|
367
297
|
|
|
368
298
|
@timeit
|
|
@@ -373,24 +303,54 @@ def sync_kms_keys(
|
|
|
373
303
|
current_aws_account_id: str,
|
|
374
304
|
aws_update_tag: int,
|
|
375
305
|
) -> None:
|
|
306
|
+
# Get basic key metadata
|
|
376
307
|
kms_keys = get_kms_key_list(boto3_session, region)
|
|
377
308
|
|
|
309
|
+
# Get detailed data (policies, aliases, grants)
|
|
310
|
+
policy_alias_grants_data = list(
|
|
311
|
+
get_kms_key_details(boto3_session, kms_keys, region)
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
# Transform policy data for inclusion in keys
|
|
315
|
+
policy_data = transform_kms_key_policies(policy_alias_grants_data)
|
|
316
|
+
|
|
317
|
+
# Transform keys WITH policy data included
|
|
318
|
+
transformed_keys = transform_kms_keys(kms_keys, policy_data)
|
|
319
|
+
|
|
320
|
+
# Load complete keys (now includes policy properties via data model)
|
|
378
321
|
load_kms_keys(
|
|
379
322
|
neo4j_session,
|
|
380
|
-
|
|
323
|
+
transformed_keys,
|
|
381
324
|
region,
|
|
382
325
|
current_aws_account_id,
|
|
383
326
|
aws_update_tag,
|
|
384
327
|
)
|
|
385
328
|
|
|
386
|
-
|
|
387
|
-
|
|
329
|
+
# Extract and transform aliases and grants
|
|
330
|
+
aliases: List[Dict] = []
|
|
331
|
+
grants: List[Dict] = []
|
|
332
|
+
|
|
333
|
+
for key, policy, alias, grant in policy_alias_grants_data:
|
|
334
|
+
if len(alias) > 0:
|
|
335
|
+
aliases.extend(alias)
|
|
336
|
+
if len(grant) > 0:
|
|
337
|
+
grants.extend(grant)
|
|
338
|
+
|
|
339
|
+
# Transform aliases and grants following standard pattern
|
|
340
|
+
transformed_aliases = transform_kms_aliases(aliases)
|
|
341
|
+
transformed_grants = transform_kms_grants(grants)
|
|
342
|
+
|
|
343
|
+
# Load aliases and grants directly - standard Cartography pattern
|
|
344
|
+
load_kms_aliases(
|
|
388
345
|
neo4j_session,
|
|
389
|
-
|
|
346
|
+
transformed_aliases,
|
|
390
347
|
region,
|
|
391
348
|
current_aws_account_id,
|
|
392
349
|
aws_update_tag,
|
|
393
350
|
)
|
|
351
|
+
load_kms_grants(
|
|
352
|
+
neo4j_session, transformed_grants, current_aws_account_id, aws_update_tag
|
|
353
|
+
)
|
|
394
354
|
|
|
395
355
|
|
|
396
356
|
@timeit
|