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
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.113.0'
32
- __version_tuple__ = version_tuple = (0, 113, 0)
31
+ __version__ = version = '0.115.0'
32
+ __version_tuple__ = version_tuple = (0, 115, 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,
@@ -959,8 +967,8 @@ class CLI:
959
967
  logger.warning("A Kandji base URI was provided but a token was not.")
960
968
  config.kandji_token = None
961
969
  else:
962
- logger.warning("A Kandji base URI was not provided.")
963
970
  config.kandji_base_uri = None
971
+ config.kandji_token = None
964
972
 
965
973
  if config.statsd_enabled:
966
974
  logger.debug(
@@ -1088,8 +1096,8 @@ class CLI:
1088
1096
  logger.warning("A SnipeIT base URI was provided but a token was not.")
1089
1097
  config.snipeit_token = None
1090
1098
  else:
1091
- logger.warning("A SnipeIT base URI was not provided.")
1092
1099
  config.snipeit_base_uri = None
1100
+ config.snipeit_token = None
1093
1101
 
1094
1102
  # Tailscale config
1095
1103
  if config.tailscale_token_env_var:
@@ -19,6 +19,17 @@ from cartography.util import batch
19
19
  logger = logging.getLogger(__name__)
20
20
 
21
21
 
22
+ def run_write_query(
23
+ neo4j_session: neo4j.Session, query: str, **parameters: Any
24
+ ) -> None:
25
+ """Execute a write query inside a managed transaction."""
26
+
27
+ def _run_query_tx(tx: neo4j.Transaction) -> None:
28
+ tx.run(query, **parameters).consume()
29
+
30
+ neo4j_session.execute_write(_run_query_tx)
31
+
32
+
22
33
  def read_list_of_values_tx(
23
34
  tx: neo4j.Transaction,
24
35
  query: 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
@@ -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,8 +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:GCPFolder) ON (n.id);
104
- CREATE INDEX IF NOT EXISTS FOR (n:GCPFolder) ON (n.lastupdated);
105
87
  CREATE INDEX IF NOT EXISTS FOR (n:GCPForwardingRule) ON (n.id);
106
88
  CREATE INDEX IF NOT EXISTS FOR (n:GCPForwardingRule) ON (n.lastupdated);
107
89
  CREATE INDEX IF NOT EXISTS FOR (n:GCPInstance) ON (n.id);
@@ -112,23 +94,14 @@ CREATE INDEX IF NOT EXISTS FOR (n:GCPNetworkTag) ON (n.id);
112
94
  CREATE INDEX IF NOT EXISTS FOR (n:GCPNetworkTag) ON (n.lastupdated);
113
95
  CREATE INDEX IF NOT EXISTS FOR (n:GCPNicAccessConfig) ON (n.id);
114
96
  CREATE INDEX IF NOT EXISTS FOR (n:GCPNicAccessConfig) ON (n.lastupdated);
115
- CREATE INDEX IF NOT EXISTS FOR (n:GCPOrganization) ON (n.id);
116
- CREATE INDEX IF NOT EXISTS FOR (n:GCPOrganization) ON (n.lastupdated);
117
- CREATE INDEX IF NOT EXISTS FOR (n:GCPProject) ON (n.id);
118
- CREATE INDEX IF NOT EXISTS FOR (n:GCPProject) ON (n.projectnumber);
119
- CREATE INDEX IF NOT EXISTS FOR (n:GCPProject) ON (n.lastupdated);
120
97
  CREATE INDEX IF NOT EXISTS FOR (n:GCPBucket) ON (n.id);
121
98
  CREATE INDEX IF NOT EXISTS FOR (n:GCPBucket) ON (n.lastupdated);
122
99
  CREATE INDEX IF NOT EXISTS FOR (n:GCPBucketLabel) ON (n.key);
123
100
  CREATE INDEX IF NOT EXISTS FOR (n:GCPBucketLabel) ON (n.lastupdated);
124
- CREATE INDEX IF NOT EXISTS FOR (n:GCPSubnet) ON (n.id);
125
- CREATE INDEX IF NOT EXISTS FOR (n:GCPSubnet) ON (n.lastupdated);
126
101
  CREATE INDEX IF NOT EXISTS FOR (n:GCPVpc) ON (n.id);
127
102
  CREATE INDEX IF NOT EXISTS FOR (n:GCPVpc) ON (n.lastupdated);
128
103
  CREATE INDEX IF NOT EXISTS FOR (n:GitHubRepository) ON (n.id);
129
104
  CREATE INDEX IF NOT EXISTS FOR (n:GitHubRepository) ON (n.lastupdated);
130
- CREATE INDEX IF NOT EXISTS FOR (n:GKECluster) ON (n.id);
131
- CREATE INDEX IF NOT EXISTS FOR (n:GKECluster) ON (n.lastupdated);
132
105
  CREATE INDEX IF NOT EXISTS FOR (n:GSuiteGroup) ON (n.email);
133
106
  CREATE INDEX IF NOT EXISTS FOR (n:GSuiteGroup) ON (n.id);
134
107
  CREATE INDEX IF NOT EXISTS FOR (n:GSuiteGroup) ON (n.lastupdated);
@@ -5,6 +5,7 @@ from typing import List
5
5
  import boto3
6
6
  import neo4j
7
7
 
8
+ from cartography.client.core.tx import run_write_query
8
9
  from cartography.util import aws_handle_regions
9
10
  from cartography.util import run_cleanup_job
10
11
  from cartography.util import timeit
@@ -80,7 +81,8 @@ def load_configuration_recorders(
80
81
  for recorder in data:
81
82
  recorder["_id"] = f'{recorder["name"]}:{current_aws_account_id}:{region}'
82
83
 
83
- neo4j_session.run(
84
+ run_write_query(
85
+ neo4j_session,
84
86
  ingest_configuration_recorders,
85
87
  Recorders=data,
86
88
  Region=region,
@@ -120,7 +122,8 @@ def load_delivery_channels(
120
122
  for channel in data:
121
123
  channel["_id"] = f'{channel["name"]}:{current_aws_account_id}:{region}'
122
124
 
123
- neo4j_session.run(
125
+ run_write_query(
126
+ neo4j_session,
124
127
  ingest_delivery_channels,
125
128
  Channels=data,
126
129
  Region=region,
@@ -167,7 +170,8 @@ def load_config_rules(
167
170
  for detail in rule["Source"]["SourceDetails"]:
168
171
  details.append(f"{detail}")
169
172
  rule["_source_details"] = details
170
- neo4j_session.run(
173
+ run_write_query(
174
+ neo4j_session,
171
175
  ingest_config_rules,
172
176
  Rules=data,
173
177
  Region=region,
@@ -57,15 +57,15 @@ def get_ecr_repository_images(
57
57
  )
58
58
  for response in describe_response:
59
59
  image_details = response["imageDetails"]
60
- image_details = [
61
- (
62
- {**detail, "imageTag": detail["imageTags"][0]}
63
- if detail.get("imageTags")
64
- else detail
65
- )
66
- for detail in image_details
67
- ]
68
- ecr_repository_images.extend(image_details)
60
+ for detail in image_details:
61
+ tags = detail.get("imageTags") or []
62
+ if tags:
63
+ for tag in tags:
64
+ image_detail = {**detail, "imageTag": tag}
65
+ image_detail.pop("imageTags", None)
66
+ ecr_repository_images.append(image_detail)
67
+ else:
68
+ ecr_repository_images.append({**detail})
69
69
  return ecr_repository_images
70
70
 
71
71