cartography 0.107.0rc3__py3-none-any.whl → 0.108.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 (47) hide show
  1. cartography/_version.py +2 -2
  2. cartography/cli.py +10 -0
  3. cartography/config.py +5 -0
  4. cartography/data/indexes.cypher +0 -10
  5. cartography/data/jobs/cleanup/github_repos_cleanup.json +2 -0
  6. cartography/intel/aws/__init__.py +1 -0
  7. cartography/intel/aws/cloudtrail.py +17 -4
  8. cartography/intel/aws/cloudtrail_management_events.py +560 -16
  9. cartography/intel/aws/cloudwatch.py +73 -4
  10. cartography/intel/aws/ec2/security_groups.py +140 -122
  11. cartography/intel/aws/ec2/snapshots.py +47 -84
  12. cartography/intel/aws/ec2/subnets.py +37 -63
  13. cartography/intel/aws/ecr.py +55 -80
  14. cartography/intel/aws/elasticache.py +102 -79
  15. cartography/intel/aws/guardduty.py +275 -0
  16. cartography/intel/aws/resources.py +2 -0
  17. cartography/intel/aws/secretsmanager.py +62 -44
  18. cartography/intel/github/repos.py +370 -28
  19. cartography/models/aws/cloudtrail/management_events.py +95 -6
  20. cartography/models/aws/cloudtrail/trail.py +21 -0
  21. cartography/models/aws/cloudwatch/metric_alarm.py +53 -0
  22. cartography/models/aws/ec2/security_group_rules.py +109 -0
  23. cartography/models/aws/ec2/security_groups.py +90 -0
  24. cartography/models/aws/ec2/snapshots.py +58 -0
  25. cartography/models/aws/ec2/subnets.py +65 -0
  26. cartography/models/aws/ec2/volumes.py +20 -0
  27. cartography/models/aws/ecr/__init__.py +0 -0
  28. cartography/models/aws/ecr/image.py +41 -0
  29. cartography/models/aws/ecr/repository.py +72 -0
  30. cartography/models/aws/ecr/repository_image.py +95 -0
  31. cartography/models/aws/elasticache/__init__.py +0 -0
  32. cartography/models/aws/elasticache/cluster.py +65 -0
  33. cartography/models/aws/elasticache/topic.py +67 -0
  34. cartography/models/aws/guardduty/__init__.py +1 -0
  35. cartography/models/aws/guardduty/findings.py +102 -0
  36. cartography/models/aws/secretsmanager/secret.py +106 -0
  37. cartography/models/github/dependencies.py +74 -0
  38. cartography/models/github/manifests.py +49 -0
  39. {cartography-0.107.0rc3.dist-info → cartography-0.108.0.dist-info}/METADATA +3 -3
  40. {cartography-0.107.0rc3.dist-info → cartography-0.108.0.dist-info}/RECORD +44 -29
  41. cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -24
  42. cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -8
  43. cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -30
  44. {cartography-0.107.0rc3.dist-info → cartography-0.108.0.dist-info}/WHEEL +0 -0
  45. {cartography-0.107.0rc3.dist-info → cartography-0.108.0.dist-info}/entry_points.txt +0 -0
  46. {cartography-0.107.0rc3.dist-info → cartography-0.108.0.dist-info}/licenses/LICENSE +0 -0
  47. {cartography-0.107.0rc3.dist-info → cartography-0.108.0.dist-info}/top_level.txt +0 -0
cartography/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.107.0rc3'
21
- __version_tuple__ = version_tuple = (0, 107, 0, 'rc3')
20
+ __version__ = version = '0.108.0'
21
+ __version_tuple__ = version_tuple = (0, 108, 0)
cartography/cli.py CHANGED
@@ -264,6 +264,16 @@ class CLI:
264
264
  " If not specified, cartography by default will run all AWS sync modules available."
265
265
  ),
266
266
  )
267
+ parser.add_argument(
268
+ "--aws-guardduty-severity-threshold",
269
+ type=str,
270
+ default=None,
271
+ help=(
272
+ "GuardDuty severity threshold filter. Only findings at or above this severity level will be synced. "
273
+ "Valid values: LOW, MEDIUM, HIGH, CRITICAL. If not specified, all findings (except archived) will be synced. "
274
+ "Example: 'HIGH' will sync only HIGH and CRITICAL findings, filtering out LOW and MEDIUM severity findings."
275
+ ),
276
+ )
267
277
  parser.add_argument(
268
278
  "--analysis-job-directory",
269
279
  type=str,
cartography/config.py CHANGED
@@ -53,6 +53,9 @@ class Config:
53
53
  :param entra_client_secret: Client Secret for connecting in a Service Principal Authentication approach. Optional.
54
54
  :type aws_requested_syncs: str
55
55
  :param aws_requested_syncs: Comma-separated list of AWS resources to sync. Optional.
56
+ :type aws_guardduty_severity_threshold: str
57
+ :param aws_guardduty_severity_threshold: GuardDuty severity threshold filter. Only findings at or above this
58
+ severity level will be synced. Valid values: LOW, MEDIUM, HIGH, CRITICAL. Optional.
56
59
  :type analysis_job_directory: str
57
60
  :param analysis_job_directory: Path to a directory tree containing analysis jobs to run. Optional.
58
61
  :type oci_sync_all_profiles: bool
@@ -185,6 +188,7 @@ class Config:
185
188
  entra_client_id=None,
186
189
  entra_client_secret=None,
187
190
  aws_requested_syncs=None,
191
+ aws_guardduty_severity_threshold=None,
188
192
  analysis_job_directory=None,
189
193
  oci_sync_all_profiles=None,
190
194
  okta_org_id=None,
@@ -268,6 +272,7 @@ class Config:
268
272
  self.entra_client_id = entra_client_id
269
273
  self.entra_client_secret = entra_client_secret
270
274
  self.aws_requested_syncs = aws_requested_syncs
275
+ self.aws_guardduty_severity_threshold = aws_guardduty_severity_threshold
271
276
  self.analysis_job_directory = analysis_job_directory
272
277
  self.oci_sync_all_profiles = oci_sync_all_profiles
273
278
  self.okta_org_id = okta_org_id
@@ -81,8 +81,6 @@ CREATE INDEX IF NOT EXISTS FOR (n:DODroplet) ON (n.id);
81
81
  CREATE INDEX IF NOT EXISTS FOR (n:DODroplet) ON (n.lastupdated);
82
82
  CREATE INDEX IF NOT EXISTS FOR (n:DOProject) ON (n.id);
83
83
  CREATE INDEX IF NOT EXISTS FOR (n:DOProject) ON (n.lastupdated);
84
- CREATE INDEX IF NOT EXISTS FOR (n:EBSSnapshot) ON (n.id);
85
- CREATE INDEX IF NOT EXISTS FOR (n:EBSSnapshot) ON (n.lastupdated);
86
84
  CREATE INDEX IF NOT EXISTS FOR (n:EC2KeyPair) ON (n.keyfingerprint);
87
85
  CREATE INDEX IF NOT EXISTS FOR (n:EC2ReservedInstance) ON (n.id);
88
86
  CREATE INDEX IF NOT EXISTS FOR (n:EC2ReservedInstance) ON (n.lastupdated);
@@ -156,14 +154,8 @@ CREATE INDEX IF NOT EXISTS FOR (n:GSuiteUser) ON (n.lastupdated);
156
154
  CREATE INDEX IF NOT EXISTS FOR (n:Ip) ON (n.id);
157
155
  CREATE INDEX IF NOT EXISTS FOR (n:Ip) ON (n.ip);
158
156
  CREATE INDEX IF NOT EXISTS FOR (n:Ip) ON (n.lastupdated);
159
- CREATE INDEX IF NOT EXISTS FOR (n:IpPermissionInbound) ON (n.ruleid);
160
- CREATE INDEX IF NOT EXISTS FOR (n:IpPermissionInbound) ON (n.lastupdated);
161
- CREATE INDEX IF NOT EXISTS FOR (n:IpPermissionsEgress) ON (n.ruleid);
162
- CREATE INDEX IF NOT EXISTS FOR (n:IpPermissionsEgress) ON (n.lastupdated);
163
157
  CREATE INDEX IF NOT EXISTS FOR (n:IpRange) ON (n.id);
164
158
  CREATE INDEX IF NOT EXISTS FOR (n:IpRange) ON (n.lastupdated);
165
- CREATE INDEX IF NOT EXISTS FOR (n:IpRule) ON (n.ruleid);
166
- CREATE INDEX IF NOT EXISTS FOR (n:IpRule) ON (n.lastupdated);
167
159
  CREATE INDEX IF NOT EXISTS FOR (n:JamfComputerGroup) ON (n.id);
168
160
  CREATE INDEX IF NOT EXISTS FOR (n:JamfComputerGroup) ON (n.lastupdated);
169
161
  CREATE INDEX IF NOT EXISTS FOR (n:KMSKey) ON (n.id);
@@ -267,8 +259,6 @@ CREATE INDEX IF NOT EXISTS FOR (n:S3Bucket) ON (n.id);
267
259
  CREATE INDEX IF NOT EXISTS FOR (n:S3Bucket) ON (n.name);
268
260
  CREATE INDEX IF NOT EXISTS FOR (n:S3Bucket) ON (n.arn);
269
261
  CREATE INDEX IF NOT EXISTS FOR (n:S3Bucket) ON (n.lastupdated);
270
- CREATE INDEX IF NOT EXISTS FOR (n:SecretsManagerSecret) ON (n.id);
271
- CREATE INDEX IF NOT EXISTS FOR (n:SecretsManagerSecret) ON (n.lastupdated);
272
262
  CREATE INDEX IF NOT EXISTS FOR (n:SecurityHub) ON (n.id);
273
263
  CREATE INDEX IF NOT EXISTS FOR (n:SecurityHub) ON (n.lastupdated);
274
264
  CREATE INDEX IF NOT EXISTS FOR (n:SpotlightVulnerability) ON (n.id);
@@ -19,6 +19,7 @@
19
19
  "iterative": true,
20
20
  "iterationsize": 100
21
21
  },
22
+
22
23
  {
23
24
  "query": "MATCH (:GitHubBranch)-[r:BRANCH]->(:GitHubRepository) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r)",
24
25
  "iterative": true,
@@ -39,6 +40,7 @@
39
40
  "iterative": true,
40
41
  "iterationsize": 100
41
42
  },
43
+
42
44
  {
43
45
  "query": "MATCH (:GitHubUser)-[r:OUTSIDE_COLLAB_ADMIN]->(:GitHubRepository) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r)",
44
46
  "iterative": true,
@@ -310,6 +310,7 @@ def start_aws_ingestion(neo4j_session: neo4j.Session, config: Config) -> None:
310
310
  common_job_parameters = {
311
311
  "UPDATE_TAG": config.update_tag,
312
312
  "permission_relationships_file": config.permission_relationships_file,
313
+ "aws_guardduty_severity_threshold": config.aws_guardduty_severity_threshold,
313
314
  "aws_cloudtrail_management_events_lookback_hours": config.aws_cloudtrail_management_events_lookback_hours,
314
315
  }
315
316
  try:
@@ -26,13 +26,25 @@ def get_cloudtrail_trails(
26
26
  )
27
27
 
28
28
  trails = client.describe_trails()["trailList"]
29
-
30
- # CloudTrail multi-region trails are shown in list_trails,
31
- # but the get_trail call only works in the home region
32
29
  trails_filtered = [trail for trail in trails if trail.get("HomeRegion") == region]
30
+
33
31
  return trails_filtered
34
32
 
35
33
 
34
+ def transform_cloudtrail_trails(
35
+ trails: List[Dict[str, Any]], region: str
36
+ ) -> List[Dict[str, Any]]:
37
+ """
38
+ Transform CloudTrail trail data for ingestion
39
+ """
40
+ for trail in trails:
41
+ arn = trail.get("CloudWatchLogsLogGroupArn")
42
+ if arn:
43
+ trail["CloudWatchLogsLogGroupArn"] = arn.split(":*")[0]
44
+
45
+ return trails
46
+
47
+
36
48
  @timeit
37
49
  def load_cloudtrail_trails(
38
50
  neo4j_session: neo4j.Session,
@@ -79,7 +91,8 @@ def sync(
79
91
  logger.info(
80
92
  f"Syncing CloudTrail for region '{region}' in account '{current_aws_account_id}'.",
81
93
  )
82
- trails = get_cloudtrail_trails(boto3_session, region)
94
+ trails_filtered = get_cloudtrail_trails(boto3_session, region)
95
+ trails = transform_cloudtrail_trails(trails_filtered, region)
83
96
 
84
97
  load_cloudtrail_trails(
85
98
  neo4j_session,