iam-policy-validator 1.8.0__py3-none-any.whl → 1.10.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.
- {iam_policy_validator-1.8.0.dist-info → iam_policy_validator-1.10.0.dist-info}/METADATA +106 -1
- iam_policy_validator-1.10.0.dist-info/RECORD +96 -0
- iam_validator/__init__.py +1 -1
- iam_validator/__version__.py +1 -1
- iam_validator/checks/action_condition_enforcement.py +504 -190
- iam_validator/checks/action_resource_matching.py +8 -15
- iam_validator/checks/action_validation.py +6 -12
- iam_validator/checks/condition_key_validation.py +6 -12
- iam_validator/checks/condition_type_mismatch.py +9 -16
- iam_validator/checks/full_wildcard.py +9 -13
- iam_validator/checks/mfa_condition_check.py +8 -17
- iam_validator/checks/policy_size.py +6 -39
- iam_validator/checks/policy_structure.py +10 -40
- iam_validator/checks/policy_type_validation.py +18 -19
- iam_validator/checks/principal_validation.py +11 -20
- iam_validator/checks/resource_validation.py +5 -12
- iam_validator/checks/sensitive_action.py +8 -15
- iam_validator/checks/service_wildcard.py +6 -12
- iam_validator/checks/set_operator_validation.py +11 -18
- iam_validator/checks/sid_uniqueness.py +8 -38
- iam_validator/checks/trust_policy_validation.py +8 -14
- iam_validator/checks/utils/wildcard_expansion.py +1 -1
- iam_validator/checks/wildcard_action.py +6 -12
- iam_validator/checks/wildcard_resource.py +6 -12
- iam_validator/commands/cache.py +4 -3
- iam_validator/commands/validate.py +26 -4
- iam_validator/core/__init__.py +1 -1
- iam_validator/core/aws_fetcher.py +24 -1030
- iam_validator/core/aws_service/__init__.py +21 -0
- iam_validator/core/aws_service/cache.py +108 -0
- iam_validator/core/aws_service/client.py +205 -0
- iam_validator/core/aws_service/fetcher.py +612 -0
- iam_validator/core/aws_service/parsers.py +149 -0
- iam_validator/core/aws_service/patterns.py +51 -0
- iam_validator/core/aws_service/storage.py +291 -0
- iam_validator/core/aws_service/validators.py +379 -0
- iam_validator/core/check_registry.py +82 -14
- iam_validator/core/config/defaults.py +10 -0
- iam_validator/core/constants.py +17 -0
- iam_validator/core/label_manager.py +197 -0
- iam_validator/core/policy_checks.py +7 -3
- iam_validator/core/pr_commenter.py +34 -7
- iam_validator/sdk/__init__.py +1 -1
- iam_validator/sdk/context.py +1 -1
- iam_validator/sdk/helpers.py +1 -1
- iam_policy_validator-1.8.0.dist-info/RECORD +0 -87
- {iam_policy_validator-1.8.0.dist-info → iam_policy_validator-1.10.0.dist-info}/WHEEL +0 -0
- {iam_policy_validator-1.8.0.dist-info → iam_policy_validator-1.10.0.dist-info}/entry_points.txt +0 -0
- {iam_policy_validator-1.8.0.dist-info → iam_policy_validator-1.10.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""Label Manager for GitHub PR Labels based on Severity Findings.
|
|
2
|
+
|
|
3
|
+
This module manages GitHub PR labels based on IAM policy validation severity findings.
|
|
4
|
+
When validation finds issues with specific severities, it applies corresponding labels.
|
|
5
|
+
When those severities are not found, it removes the labels if present.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from iam_validator.core.models import PolicyValidationResult, ValidationReport
|
|
13
|
+
from iam_validator.integrations.github_integration import GitHubIntegration
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LabelManager:
|
|
19
|
+
"""Manages GitHub PR labels based on severity findings."""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
github: "GitHubIntegration",
|
|
24
|
+
severity_labels: dict[str, str | list[str]] | None = None,
|
|
25
|
+
):
|
|
26
|
+
"""Initialize label manager.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
github: GitHubIntegration instance for API calls
|
|
30
|
+
severity_labels: Mapping of severity levels to label name(s)
|
|
31
|
+
Supports both single labels and lists of labels per severity.
|
|
32
|
+
Examples:
|
|
33
|
+
- Single label per severity:
|
|
34
|
+
{"error": "iam-validity-error", "critical": "security-critical"}
|
|
35
|
+
- Multiple labels per severity:
|
|
36
|
+
{"error": ["iam-error", "needs-fix"], "critical": ["security-critical", "needs-security-review"]}
|
|
37
|
+
- Mixed:
|
|
38
|
+
{"error": "iam-validity-error", "critical": ["security-critical", "needs-review"]}
|
|
39
|
+
"""
|
|
40
|
+
self.github = github
|
|
41
|
+
self.severity_labels = severity_labels or {}
|
|
42
|
+
|
|
43
|
+
def is_enabled(self) -> bool:
|
|
44
|
+
"""Check if label management is enabled.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
True if severity_labels is configured and GitHub is configured
|
|
48
|
+
"""
|
|
49
|
+
return bool(self.severity_labels) and self.github.is_configured()
|
|
50
|
+
|
|
51
|
+
def _get_severities_in_results(self, results: list["PolicyValidationResult"]) -> set[str]:
|
|
52
|
+
"""Extract all severity levels found in validation results.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
results: List of PolicyValidationResult objects
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Set of severity levels found (e.g., {"error", "critical", "high"})
|
|
59
|
+
"""
|
|
60
|
+
severities = set()
|
|
61
|
+
for result in results:
|
|
62
|
+
for issue in result.issues:
|
|
63
|
+
severities.add(issue.severity)
|
|
64
|
+
return severities
|
|
65
|
+
|
|
66
|
+
def _get_severities_in_report(self, report: "ValidationReport") -> set[str]:
|
|
67
|
+
"""Extract all severity levels found in validation report.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
report: ValidationReport object
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Set of severity levels found (e.g., {"error", "critical", "high"})
|
|
74
|
+
"""
|
|
75
|
+
return self._get_severities_in_results(report.results)
|
|
76
|
+
|
|
77
|
+
def _determine_labels_to_apply(self, found_severities: set[str]) -> set[str]:
|
|
78
|
+
"""Determine which labels should be applied based on found severities.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
found_severities: Set of severity levels found in validation
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Set of label names to apply
|
|
85
|
+
"""
|
|
86
|
+
labels_to_apply = set()
|
|
87
|
+
for severity, labels in self.severity_labels.items():
|
|
88
|
+
if severity in found_severities:
|
|
89
|
+
# Support both single labels and lists of labels
|
|
90
|
+
if isinstance(labels, list):
|
|
91
|
+
labels_to_apply.update(labels)
|
|
92
|
+
else:
|
|
93
|
+
labels_to_apply.add(labels)
|
|
94
|
+
return labels_to_apply
|
|
95
|
+
|
|
96
|
+
def _determine_labels_to_remove(self, found_severities: set[str]) -> set[str]:
|
|
97
|
+
"""Determine which labels should be removed based on missing severities.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
found_severities: Set of severity levels found in validation
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Set of label names to remove
|
|
104
|
+
"""
|
|
105
|
+
labels_to_remove = set()
|
|
106
|
+
for severity, labels in self.severity_labels.items():
|
|
107
|
+
if severity not in found_severities:
|
|
108
|
+
# Support both single labels and lists of labels
|
|
109
|
+
if isinstance(labels, list):
|
|
110
|
+
labels_to_remove.update(labels)
|
|
111
|
+
else:
|
|
112
|
+
labels_to_remove.add(labels)
|
|
113
|
+
return labels_to_remove
|
|
114
|
+
|
|
115
|
+
async def manage_labels_from_results(
|
|
116
|
+
self, results: list["PolicyValidationResult"]
|
|
117
|
+
) -> tuple[bool, int, int]:
|
|
118
|
+
"""Manage PR labels based on validation results.
|
|
119
|
+
|
|
120
|
+
This method will:
|
|
121
|
+
1. Determine which severity levels are present in the results
|
|
122
|
+
2. Add labels for severities that are found
|
|
123
|
+
3. Remove labels for severities that are not found
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
results: List of PolicyValidationResult objects
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
Tuple of (success, labels_added, labels_removed)
|
|
130
|
+
"""
|
|
131
|
+
if not self.is_enabled():
|
|
132
|
+
logger.debug("Label management not enabled (no severity_labels configured)")
|
|
133
|
+
return (True, 0, 0)
|
|
134
|
+
|
|
135
|
+
# Get all severities found in results
|
|
136
|
+
found_severities = self._get_severities_in_results(results)
|
|
137
|
+
logger.debug(f"Found severities in results: {found_severities}")
|
|
138
|
+
|
|
139
|
+
# Determine which labels to apply/remove
|
|
140
|
+
labels_to_apply = self._determine_labels_to_apply(found_severities)
|
|
141
|
+
labels_to_remove = self._determine_labels_to_remove(found_severities)
|
|
142
|
+
|
|
143
|
+
logger.debug(f"Labels to apply: {labels_to_apply}")
|
|
144
|
+
logger.debug(f"Labels to remove: {labels_to_remove}")
|
|
145
|
+
|
|
146
|
+
# Get current labels on PR
|
|
147
|
+
current_labels = set(await self.github.get_labels())
|
|
148
|
+
logger.debug(f"Current PR labels: {current_labels}")
|
|
149
|
+
|
|
150
|
+
# Filter: only add labels that aren't already present
|
|
151
|
+
labels_to_add = labels_to_apply - current_labels
|
|
152
|
+
|
|
153
|
+
# Filter: only remove labels that are currently present
|
|
154
|
+
labels_to_actually_remove = labels_to_remove & current_labels
|
|
155
|
+
|
|
156
|
+
success = True
|
|
157
|
+
added_count = 0
|
|
158
|
+
removed_count = 0
|
|
159
|
+
|
|
160
|
+
# Add new labels
|
|
161
|
+
if labels_to_add:
|
|
162
|
+
logger.info(f"Adding labels to PR: {labels_to_add}")
|
|
163
|
+
if await self.github.add_labels(list(labels_to_add)):
|
|
164
|
+
added_count = len(labels_to_add)
|
|
165
|
+
else:
|
|
166
|
+
logger.error("Failed to add labels to PR")
|
|
167
|
+
success = False
|
|
168
|
+
|
|
169
|
+
# Remove old labels
|
|
170
|
+
for label in labels_to_actually_remove:
|
|
171
|
+
logger.info(f"Removing label from PR: {label}")
|
|
172
|
+
if await self.github.remove_label(label):
|
|
173
|
+
removed_count += 1
|
|
174
|
+
else:
|
|
175
|
+
logger.error(f"Failed to remove label: {label}")
|
|
176
|
+
success = False
|
|
177
|
+
|
|
178
|
+
if added_count > 0 or removed_count > 0:
|
|
179
|
+
logger.info(f"Label management complete: added {added_count}, removed {removed_count}")
|
|
180
|
+
else:
|
|
181
|
+
logger.debug("No label changes needed")
|
|
182
|
+
|
|
183
|
+
return (success, added_count, removed_count)
|
|
184
|
+
|
|
185
|
+
async def manage_labels_from_report(self, report: "ValidationReport") -> tuple[bool, int, int]:
|
|
186
|
+
"""Manage PR labels based on validation report.
|
|
187
|
+
|
|
188
|
+
This is a convenience method that extracts results from the report
|
|
189
|
+
and calls manage_labels_from_results().
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
report: ValidationReport object
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
Tuple of (success, labels_added, labels_removed)
|
|
196
|
+
"""
|
|
197
|
+
return await self.manage_labels_from_results(report.results)
|
|
@@ -12,7 +12,7 @@ import logging
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
|
|
14
14
|
from iam_validator.core import constants
|
|
15
|
-
from iam_validator.core.
|
|
15
|
+
from iam_validator.core.aws_service import AWSServiceFetcher
|
|
16
16
|
from iam_validator.core.check_registry import CheckRegistry, create_default_registry
|
|
17
17
|
from iam_validator.core.config.config_loader import ConfigLoader
|
|
18
18
|
from iam_validator.core.models import (
|
|
@@ -51,6 +51,7 @@ async def validate_policies(
|
|
|
51
51
|
config_path: str | None = None,
|
|
52
52
|
custom_checks_dir: str | None = None,
|
|
53
53
|
policy_type: PolicyType = "IDENTITY_POLICY",
|
|
54
|
+
aws_services_dir: str | None = None,
|
|
54
55
|
) -> list[PolicyValidationResult]:
|
|
55
56
|
"""Validate multiple policies concurrently.
|
|
56
57
|
|
|
@@ -59,6 +60,8 @@ async def validate_policies(
|
|
|
59
60
|
config_path: Optional path to configuration file
|
|
60
61
|
custom_checks_dir: Optional path to directory containing custom checks for auto-discovery
|
|
61
62
|
policy_type: Type of policy (IDENTITY_POLICY, RESOURCE_POLICY, SERVICE_CONTROL_POLICY)
|
|
63
|
+
aws_services_dir: Optional path to directory containing pre-downloaded AWS service definitions
|
|
64
|
+
(enables offline mode, overrides config setting)
|
|
62
65
|
|
|
63
66
|
Returns:
|
|
64
67
|
List of validation results
|
|
@@ -110,7 +113,8 @@ async def validate_policies(
|
|
|
110
113
|
cache_enabled = config.get_setting("cache_enabled", True)
|
|
111
114
|
cache_ttl_hours = config.get_setting("cache_ttl_hours", constants.DEFAULT_CACHE_TTL_HOURS)
|
|
112
115
|
cache_directory = config.get_setting("cache_directory", None)
|
|
113
|
-
|
|
116
|
+
# CLI argument takes precedence over config file
|
|
117
|
+
services_dir = aws_services_dir or config.get_setting("aws_services_dir", None)
|
|
114
118
|
cache_ttl_seconds = cache_ttl_hours * constants.SECONDS_PER_HOUR
|
|
115
119
|
|
|
116
120
|
# Validate policies using registry
|
|
@@ -118,7 +122,7 @@ async def validate_policies(
|
|
|
118
122
|
enable_cache=cache_enabled,
|
|
119
123
|
cache_ttl=cache_ttl_seconds,
|
|
120
124
|
cache_dir=cache_directory,
|
|
121
|
-
aws_services_dir=
|
|
125
|
+
aws_services_dir=services_dir,
|
|
122
126
|
) as fetcher:
|
|
123
127
|
tasks = [
|
|
124
128
|
_validate_policy_with_registry(
|
|
@@ -13,7 +13,9 @@ from iam_validator.core.constants import (
|
|
|
13
13
|
REVIEW_IDENTIFIER,
|
|
14
14
|
SUMMARY_IDENTIFIER,
|
|
15
15
|
)
|
|
16
|
+
from iam_validator.core.label_manager import LabelManager
|
|
16
17
|
from iam_validator.core.models import ValidationIssue, ValidationReport
|
|
18
|
+
from iam_validator.core.report import ReportGenerator
|
|
17
19
|
from iam_validator.integrations.github_integration import GitHubIntegration, ReviewEvent
|
|
18
20
|
|
|
19
21
|
logger = logging.getLogger(__name__)
|
|
@@ -32,6 +34,7 @@ class PRCommenter:
|
|
|
32
34
|
github: GitHubIntegration | None = None,
|
|
33
35
|
cleanup_old_comments: bool = True,
|
|
34
36
|
fail_on_severities: list[str] | None = None,
|
|
37
|
+
severity_labels: dict[str, str | list[str]] | None = None,
|
|
35
38
|
):
|
|
36
39
|
"""Initialize PR commenter.
|
|
37
40
|
|
|
@@ -40,16 +43,24 @@ class PRCommenter:
|
|
|
40
43
|
cleanup_old_comments: Whether to clean up old bot comments before posting new ones
|
|
41
44
|
fail_on_severities: List of severity levels that should trigger REQUEST_CHANGES
|
|
42
45
|
(e.g., ["error", "critical", "high"])
|
|
46
|
+
severity_labels: Mapping of severity levels to label name(s) for automatic label management
|
|
47
|
+
Supports both single labels and lists of labels per severity.
|
|
48
|
+
Examples:
|
|
49
|
+
- Single: {"error": "iam-validity-error", "critical": "security-critical"}
|
|
50
|
+
- Multiple: {"error": ["iam-error", "needs-fix"], "critical": ["security-critical", "needs-review"]}
|
|
51
|
+
- Mixed: {"error": "iam-validity-error", "critical": ["security-critical", "needs-review"]}
|
|
43
52
|
"""
|
|
44
53
|
self.github = github
|
|
45
54
|
self.cleanup_old_comments = cleanup_old_comments
|
|
46
55
|
self.fail_on_severities = fail_on_severities or ["error", "critical"]
|
|
56
|
+
self.severity_labels = severity_labels or {}
|
|
47
57
|
|
|
48
58
|
async def post_findings_to_pr(
|
|
49
59
|
self,
|
|
50
60
|
report: ValidationReport,
|
|
51
61
|
create_review: bool = True,
|
|
52
62
|
add_summary_comment: bool = True,
|
|
63
|
+
manage_labels: bool = True,
|
|
53
64
|
) -> bool:
|
|
54
65
|
"""Post validation findings to a PR.
|
|
55
66
|
|
|
@@ -57,6 +68,7 @@ class PRCommenter:
|
|
|
57
68
|
report: Validation report with findings
|
|
58
69
|
create_review: Whether to create a PR review with line comments
|
|
59
70
|
add_summary_comment: Whether to add a summary comment
|
|
71
|
+
manage_labels: Whether to manage PR labels based on severity findings
|
|
60
72
|
|
|
61
73
|
Returns:
|
|
62
74
|
True if successful, False otherwise
|
|
@@ -81,8 +93,6 @@ class PRCommenter:
|
|
|
81
93
|
|
|
82
94
|
# Post summary comment (potentially as multiple parts)
|
|
83
95
|
if add_summary_comment:
|
|
84
|
-
from iam_validator.core.report import ReportGenerator
|
|
85
|
-
|
|
86
96
|
generator = ReportGenerator()
|
|
87
97
|
comment_parts = generator.generate_github_comment_parts(report)
|
|
88
98
|
|
|
@@ -104,6 +114,18 @@ class PRCommenter:
|
|
|
104
114
|
logger.error("Failed to post review comments")
|
|
105
115
|
success = False
|
|
106
116
|
|
|
117
|
+
# Manage PR labels based on severity findings
|
|
118
|
+
if manage_labels and self.severity_labels:
|
|
119
|
+
label_manager = LabelManager(self.github, self.severity_labels)
|
|
120
|
+
label_success, added, removed = await label_manager.manage_labels_from_report(report)
|
|
121
|
+
|
|
122
|
+
if not label_success:
|
|
123
|
+
logger.error("Failed to manage PR labels")
|
|
124
|
+
success = False
|
|
125
|
+
else:
|
|
126
|
+
if added > 0 or removed > 0:
|
|
127
|
+
logger.info(f"Label management: added {added}, removed {removed}")
|
|
128
|
+
|
|
107
129
|
return success
|
|
108
130
|
|
|
109
131
|
async def _post_review_comments(self, report: ValidationReport) -> bool:
|
|
@@ -288,7 +310,7 @@ class PRCommenter:
|
|
|
288
310
|
|
|
289
311
|
return mapping
|
|
290
312
|
|
|
291
|
-
except Exception as e:
|
|
313
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
292
314
|
logger.warning(f"Could not parse {policy_file} for line mapping: {e}")
|
|
293
315
|
return {}
|
|
294
316
|
|
|
@@ -369,7 +391,7 @@ class PRCommenter:
|
|
|
369
391
|
|
|
370
392
|
return None
|
|
371
393
|
|
|
372
|
-
except Exception as e:
|
|
394
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
373
395
|
logger.debug(f"Could not search {policy_file}: {e}")
|
|
374
396
|
return None
|
|
375
397
|
|
|
@@ -398,15 +420,20 @@ async def post_report_to_pr(
|
|
|
398
420
|
|
|
399
421
|
report = ValidationReport.model_validate(report_data)
|
|
400
422
|
|
|
401
|
-
# Load config to get fail_on_severity
|
|
423
|
+
# Load config to get fail_on_severity and severity_labels settings
|
|
402
424
|
from iam_validator.core.config.config_loader import ConfigLoader
|
|
403
425
|
|
|
404
426
|
config = ConfigLoader.load_config(config_path)
|
|
405
427
|
fail_on_severities = config.get_setting("fail_on_severity", ["error", "critical"])
|
|
428
|
+
severity_labels = config.get_setting("severity_labels", {})
|
|
406
429
|
|
|
407
430
|
# Post to PR
|
|
408
431
|
async with GitHubIntegration() as github:
|
|
409
|
-
commenter = PRCommenter(
|
|
432
|
+
commenter = PRCommenter(
|
|
433
|
+
github,
|
|
434
|
+
fail_on_severities=fail_on_severities,
|
|
435
|
+
severity_labels=severity_labels,
|
|
436
|
+
)
|
|
410
437
|
return await commenter.post_findings_to_pr(
|
|
411
438
|
report,
|
|
412
439
|
create_review=create_review,
|
|
@@ -419,6 +446,6 @@ async def post_report_to_pr(
|
|
|
419
446
|
except json.JSONDecodeError as e:
|
|
420
447
|
logger.error(f"Invalid JSON in report file: {e}")
|
|
421
448
|
return False
|
|
422
|
-
except Exception as e:
|
|
449
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
423
450
|
logger.error(f"Failed to post report to PR: {e}")
|
|
424
451
|
return False
|
iam_validator/sdk/__init__.py
CHANGED
|
@@ -37,7 +37,7 @@ Quick Start:
|
|
|
37
37
|
|
|
38
38
|
# === High-level validation functions (shortcuts) ===
|
|
39
39
|
# === AWS utilities ===
|
|
40
|
-
from iam_validator.core.
|
|
40
|
+
from iam_validator.core.aws_service import AWSServiceFetcher
|
|
41
41
|
|
|
42
42
|
# === Core validation components (for advanced usage) ===
|
|
43
43
|
from iam_validator.core.check_registry import CheckRegistry, PolicyCheck
|
iam_validator/sdk/context.py
CHANGED
|
@@ -8,7 +8,7 @@ and make the validation API more convenient to use.
|
|
|
8
8
|
from contextlib import asynccontextmanager
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
|
|
11
|
-
from iam_validator.core.
|
|
11
|
+
from iam_validator.core.aws_service import AWSServiceFetcher
|
|
12
12
|
from iam_validator.core.models import PolicyValidationResult
|
|
13
13
|
from iam_validator.core.policy_checks import validate_policies
|
|
14
14
|
from iam_validator.core.policy_loader import PolicyLoader
|
iam_validator/sdk/helpers.py
CHANGED
|
@@ -6,7 +6,7 @@ easy to develop custom IAM policy checks.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from iam_validator.checks.utils.wildcard_expansion import expand_wildcard_actions
|
|
9
|
-
from iam_validator.core.
|
|
9
|
+
from iam_validator.core.aws_service import AWSServiceFetcher
|
|
10
10
|
from iam_validator.core.models import ValidationIssue
|
|
11
11
|
from iam_validator.sdk.arn_matching import arn_matches, arn_strictly_valid
|
|
12
12
|
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
iam_validator/__init__.py,sha256=APnMR3Fu4fHhxfsHBvUM2dJIwazgvLKQbfOsSgFPidg,693
|
|
2
|
-
iam_validator/__main__.py,sha256=to_nz3n_IerJpVVZZ6WSFlFR5s_06J0csfPOTfQZG8g,197
|
|
3
|
-
iam_validator/__version__.py,sha256=3gyLuIf6oV1A2rFZSmXco3rdq2hmgGAYEB2we_Su_TU,361
|
|
4
|
-
iam_validator/checks/__init__.py,sha256=OTkPnmlelu4YjMO8krjhu2wXiTV72RzopA5u1SfPQA0,1990
|
|
5
|
-
iam_validator/checks/action_condition_enforcement.py,sha256=XztLhckc3Xc5RwxlMM2U2M81TNyt9M5xgBwn5fqHK1M,39141
|
|
6
|
-
iam_validator/checks/action_resource_matching.py,sha256=BTrweeD1SNy9hcsfIDEN4L1E7oLNiVLyg-yerlZ5eC0,19356
|
|
7
|
-
iam_validator/checks/action_validation.py,sha256=t8JPbvLiQb0Lx7SF_gruxehVgy0WU5uWppDJhhsSnI0,2580
|
|
8
|
-
iam_validator/checks/condition_key_validation.py,sha256=VaOo1CLrMVRi23oUE1nMlKAgzNY9_jrnnEfGbdfF53g,3982
|
|
9
|
-
iam_validator/checks/condition_type_mismatch.py,sha256=VK7KxkdeX2FmKWJUaZwJXSFQUxqtnqGj5sigOuhGCWo,10707
|
|
10
|
-
iam_validator/checks/full_wildcard.py,sha256=ywD762BOV8WxFuTTARkaGMJn27f3ZZVuZUjKo8URnTc,2281
|
|
11
|
-
iam_validator/checks/mfa_condition_check.py,sha256=YCBX3tFTQRmVTAed_W-Tu1b6WqD2LBYyom53P7lBjh4,4935
|
|
12
|
-
iam_validator/checks/policy_size.py,sha256=ibgmrErpkz6OfUAN6bFuHe1KHzpzzra9gHwNtVAkPWc,5729
|
|
13
|
-
iam_validator/checks/policy_structure.py,sha256=CQh1FsqVOFENAQe7mbyRzlIntjMs0gAwv6wUUqsdXqc,22636
|
|
14
|
-
iam_validator/checks/policy_type_validation.py,sha256=8wnaCmvFb_q4ToqPR8B1exwFdwwqXYEf-Dw8YUgnj0s,15873
|
|
15
|
-
iam_validator/checks/principal_validation.py,sha256=HYxcUtTWDvWh9AZbqtUSWrZOJrNGALRu1jrDydNF3xk,27895
|
|
16
|
-
iam_validator/checks/resource_validation.py,sha256=8FAVPxAsralAPlao5GeJNSutqKC7DLWYZaI7CHhLs_E,6052
|
|
17
|
-
iam_validator/checks/sensitive_action.py,sha256=1-Bumsk_fPHTCW0iRmIHaqMaQY-1uYI5vH2uO3YGvf0,9765
|
|
18
|
-
iam_validator/checks/service_wildcard.py,sha256=brdm4cm7bOgpHB8jyAzGEGPQzoytaFIy5CgfUVgamv8,4012
|
|
19
|
-
iam_validator/checks/set_operator_validation.py,sha256=AnOC7Ywd3tk7zdqNkQXAAdtsiCxKwVQ6pGsbpsopZfY,7465
|
|
20
|
-
iam_validator/checks/sid_uniqueness.py,sha256=ZScVKa1RROhrY2uSOUSeeIK4xXNVzfnp9hn5Jr-TVHk,6984
|
|
21
|
-
iam_validator/checks/trust_policy_validation.py,sha256=q3YFqMk3MYa4pEr1CPCCPvMcbv8-6rzT74EfsgZ6k0k,17880
|
|
22
|
-
iam_validator/checks/wildcard_action.py,sha256=-yS4o2SgDRMEp_SA_kcwmmf6do0gWppkP1rpg7IP9Zg,2023
|
|
23
|
-
iam_validator/checks/wildcard_resource.py,sha256=zsz7nfvvqnOYLMUfM1w7E46267Y4SrBF4x1Nvgg-B7U,5467
|
|
24
|
-
iam_validator/checks/utils/__init__.py,sha256=j0X4ibUB6RGx2a-kNoJnlVZwHfoEvzZsIeTmJIAoFzA,45
|
|
25
|
-
iam_validator/checks/utils/policy_level_checks.py,sha256=2V60C0zhKfsFPjQ-NMlD3EemtwA9S6-4no8nETgXdQE,5274
|
|
26
|
-
iam_validator/checks/utils/sensitive_action_matcher.py,sha256=qDXcJa_2sCJu9pBbjDlI7x5lPtLRc6jQCpKPMheCOJQ,11215
|
|
27
|
-
iam_validator/checks/utils/wildcard_expansion.py,sha256=JK8iYcYpOzi5RN4IvIMBCbzkCEhVRJxZDKLZIKgD8nY,3131
|
|
28
|
-
iam_validator/commands/__init__.py,sha256=M-5bo8w0TCWydK0cXgJyPD2fmk8bpQs-3b26YbgLzlc,565
|
|
29
|
-
iam_validator/commands/analyze.py,sha256=rvLBJ5_A3HB530xtixhaIsC19QON68olEQnn8TievgI,20784
|
|
30
|
-
iam_validator/commands/base.py,sha256=5baCCMwxz7pdQ6XMpWfXFNz7i1l5dB8Qv9dKKR04Gzs,1074
|
|
31
|
-
iam_validator/commands/cache.py,sha256=p4ucRVuh42sbK3Lk0b610L3ofAR5TnUreF00fpO6VFg,14219
|
|
32
|
-
iam_validator/commands/download_services.py,sha256=KKz3ybMLT8DQUf9aFZ0tilJ-o1b6PE8Pf1pC4K6cT8I,9175
|
|
33
|
-
iam_validator/commands/post_to_pr.py,sha256=CvUXs2xvO-UhluxdfNM6F0TCWD8hDBEOiYw60fm1Dms,2363
|
|
34
|
-
iam_validator/commands/validate.py,sha256=hau8oPCNGya8gAUrvbhQxAlR4fhaGKzl7MQSryBgQfQ,23381
|
|
35
|
-
iam_validator/core/__init__.py,sha256=JyeUUjuVsXFPkxLjsZ9omLPAFudWR-lQ_8oBX9jTY70,376
|
|
36
|
-
iam_validator/core/access_analyzer.py,sha256=mtMaY-FnKjKEVITky_9ywZe1FaCAm61ElRv5Z_ZeC7E,24562
|
|
37
|
-
iam_validator/core/access_analyzer_report.py,sha256=UMm2RNGj2rAKav1zsCw_htQZZRwRC0jjayd2zvKma1A,24896
|
|
38
|
-
iam_validator/core/aws_fetcher.py,sha256=U9aE1kJ6HqJYYFpT8bq90dAAKGvmy8wKV6v_1aQCno4,41741
|
|
39
|
-
iam_validator/core/check_registry.py,sha256=5hmhKiF45cenLYviGMAEhb08_Fqvu9PFxXzBmLEQuqk,22639
|
|
40
|
-
iam_validator/core/cli.py,sha256=PkXiZjlgrQ21QustBbspefYsdbxst4gxoClyG2_HQR8,3843
|
|
41
|
-
iam_validator/core/condition_validators.py,sha256=7zBjlcf2xGFKGbcFrXSLvWT5tFhWxoqwzhsJqS2E8uY,21524
|
|
42
|
-
iam_validator/core/constants.py,sha256=H3eH0yddn5Dk-xZxJWtuvluRIpuXKYGiiteBSHPpJoI,5560
|
|
43
|
-
iam_validator/core/ignore_patterns.py,sha256=pZqDJBtkbck-85QK5eFPM5ZOPEKs3McRh3avqiCT5z0,10398
|
|
44
|
-
iam_validator/core/models.py,sha256=f5d9ovtO1xMSwhyBrKIgc2psEq0eugnd3S3ioqurqEE,13242
|
|
45
|
-
iam_validator/core/policy_checks.py,sha256=le1ovFm3qcgq3JG-L336h4nCSfol0PzL65RC3Beslwk,8520
|
|
46
|
-
iam_validator/core/policy_loader.py,sha256=2KJnXzGg3g9pDXWZHk3DO0xpZnZZ-wXWFEOdQ_naJ8s,17862
|
|
47
|
-
iam_validator/core/pr_commenter.py,sha256=MU-t7SfdHUpSc6BDbh8_dNAbxDiG-bZBCry-jUXivAc,15066
|
|
48
|
-
iam_validator/core/report.py,sha256=kzSeWnT1LqWZVA5pqKKz-maVowXVj0djdoShfRhhpz4,35899
|
|
49
|
-
iam_validator/core/config/__init__.py,sha256=CWSyIA7kEyzrskEenjYbs9Iih10BXRpiY9H2dHg61rU,2671
|
|
50
|
-
iam_validator/core/config/aws_api.py,sha256=HLIzOItQ0A37wxHcgWck6ZFO0wmNY8JNTiWMMK6JKYU,1248
|
|
51
|
-
iam_validator/core/config/aws_global_conditions.py,sha256=gdmMxXGBy95B3uYUG-J7rnM6Ixgc6L7Y9Pcd2XAMb60,7170
|
|
52
|
-
iam_validator/core/config/category_suggestions.py,sha256=QlrYi4BTkxDSTlL7NZGE9BWN-atWetZ6XjkI9F_7YzI,4370
|
|
53
|
-
iam_validator/core/config/condition_requirements.py,sha256=qauIP73HFnOw1dchUeFpg1x7Y7QWkILo3GfxV_dxdQo,7696
|
|
54
|
-
iam_validator/core/config/config_loader.py,sha256=qKD8aR8YAswaFf68pnYJLFNwKznvcc6lNxSQWU3i6SY,17713
|
|
55
|
-
iam_validator/core/config/defaults.py,sha256=rWzDrlw0AAudtm_If6zjNFvruLg71jpLJEdRgKYSKMQ,27917
|
|
56
|
-
iam_validator/core/config/principal_requirements.py,sha256=VCX7fBDgeDTJQyoz7_x7GI7Kf9O1Eu-sbihoHOrKv6o,15105
|
|
57
|
-
iam_validator/core/config/sensitive_actions.py,sha256=uATDIp_TD3OQQlsYTZp79qd1mSK2Bf9hJ0JwcqLBr84,25344
|
|
58
|
-
iam_validator/core/config/service_principals.py,sha256=8pys5H_yycVJ9KTyimAKFYBg83Aol2Iri53wiHjtnEM,3959
|
|
59
|
-
iam_validator/core/config/wildcards.py,sha256=H_v6hb-rZ0UUz4cul9lxkVI39e6knaK4Y-MbWz2Ebpw,3228
|
|
60
|
-
iam_validator/core/formatters/__init__.py,sha256=fnCKAEBXItnOf2m4rhVs7zwMaTxbG6ESh3CF8V5j5ec,868
|
|
61
|
-
iam_validator/core/formatters/base.py,sha256=SShDeDiy5mYQnS6BpA8xYg91N-KX1EObkOtlrVHqx1Q,4451
|
|
62
|
-
iam_validator/core/formatters/console.py,sha256=FdTp7AzeILCWrUynSvSew8QJKGOMJaAA9_YiQJd-uco,2196
|
|
63
|
-
iam_validator/core/formatters/csv.py,sha256=pPqgvGh4KtD5Qm36xnMaDAavXYR6MlQhs4zbcrxT550,5941
|
|
64
|
-
iam_validator/core/formatters/enhanced.py,sha256=TVtkcTIow8NGoLhG45-5ms-_PTxyxMcAHxf_uPMyKAc,18155
|
|
65
|
-
iam_validator/core/formatters/html.py,sha256=j4sQi-wXiD9kCHldW5JCzbJe0frhiP5uQI9KlH3Sj_g,22994
|
|
66
|
-
iam_validator/core/formatters/json.py,sha256=A7gZ8P32GEdbDvrSn6v56yQ4fOP_kyMaoFVXG2bgnew,939
|
|
67
|
-
iam_validator/core/formatters/markdown.py,sha256=dk4STeY-tOEZsVrlmolIEqZvWYP9JhRtygxxNA49DEE,2293
|
|
68
|
-
iam_validator/core/formatters/sarif.py,sha256=O3pn7whqFq5xxk-tuoqSb2k4Fk5ai_A2SKX_ph8GLV4,10469
|
|
69
|
-
iam_validator/integrations/__init__.py,sha256=7Hlor_X9j0NZaEjFuSvoXAAuSKQ-zgY19Rk-Dz3JpKo,616
|
|
70
|
-
iam_validator/integrations/github_integration.py,sha256=EnrolMq3uZbKWPxUMhYnqcKAfic6Fb8qJzieDruKqsc,26485
|
|
71
|
-
iam_validator/integrations/ms_teams.py,sha256=t2PlWuTDb6GGH-eDU1jnOKd8D1w4FCB68bahGA7MJcE,14475
|
|
72
|
-
iam_validator/sdk/__init__.py,sha256=fRDSXAclGmCU3KDft4StL8JUcpAsdzwIRf8mVj461q0,5306
|
|
73
|
-
iam_validator/sdk/arn_matching.py,sha256=HSDpLltOYISq-SoPebAlM89mKOaUaghq_04urchEFDA,12778
|
|
74
|
-
iam_validator/sdk/context.py,sha256=SBFeedu8rhCzFA-zC2cH4wLZxEJT6XOW30hIZAyXPVU,6826
|
|
75
|
-
iam_validator/sdk/exceptions.py,sha256=tm91TxIwU157U_UHN7w5qICf_OhU11agj6pV5W_YP-4,1023
|
|
76
|
-
iam_validator/sdk/helpers.py,sha256=OVBg4xrW95LT74wXCg1LQkba9kw5RfFqeCLuTqhgL-A,5697
|
|
77
|
-
iam_validator/sdk/policy_utils.py,sha256=CZS1OGSdiWsd2lsCwg0BDcUNWa61tUwgvn-P5rKqeN8,12987
|
|
78
|
-
iam_validator/sdk/shortcuts.py,sha256=EVNSYV7rv4TFH03ulsZ3mS1UVmTSp2jKpc2AXs4j1q4,8531
|
|
79
|
-
iam_validator/utils/__init__.py,sha256=NveA2F3G1E6-ANZzFr7J6Q6u5mogvMp862iFokmYuCs,1021
|
|
80
|
-
iam_validator/utils/cache.py,sha256=wOQKOBeoG6QqC5f0oXcHz63Cjtu_-SsSS-0pTSwyAiM,3254
|
|
81
|
-
iam_validator/utils/regex.py,sha256=xHoMECttb7qaMhts-c9b0GIxdhHNZTt-UBr7wNhWfzg,6219
|
|
82
|
-
iam_validator/utils/terminal.py,sha256=FsRaRMH_JAyDgXWBCOgOEhbS89cs17HCmKYoughq5io,724
|
|
83
|
-
iam_policy_validator-1.8.0.dist-info/METADATA,sha256=vccDFxkghziff8eO-K7hIVreQjE5gkLsWrIS5b61EwY,16174
|
|
84
|
-
iam_policy_validator-1.8.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
85
|
-
iam_policy_validator-1.8.0.dist-info/entry_points.txt,sha256=8HtWd8O7mvPiPdZR5YbzY8or_qcqLM4-pKaFdhtFT8M,62
|
|
86
|
-
iam_policy_validator-1.8.0.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
|
|
87
|
-
iam_policy_validator-1.8.0.dist-info/RECORD,,
|
|
File without changes
|
{iam_policy_validator-1.8.0.dist-info → iam_policy_validator-1.10.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{iam_policy_validator-1.8.0.dist-info → iam_policy_validator-1.10.0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|