iam-policy-validator 1.0.4__py3-none-any.whl → 1.1.1__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 iam-policy-validator might be problematic. Click here for more details.

Files changed (34) hide show
  1. {iam_policy_validator-1.0.4.dist-info → iam_policy_validator-1.1.1.dist-info}/METADATA +88 -10
  2. iam_policy_validator-1.1.1.dist-info/RECORD +53 -0
  3. iam_validator/__version__.py +1 -1
  4. iam_validator/checks/__init__.py +2 -0
  5. iam_validator/checks/action_condition_enforcement.py +112 -28
  6. iam_validator/checks/action_resource_constraint.py +151 -0
  7. iam_validator/checks/action_validation.py +18 -138
  8. iam_validator/checks/security_best_practices.py +241 -400
  9. iam_validator/checks/utils/__init__.py +1 -0
  10. iam_validator/checks/utils/policy_level_checks.py +143 -0
  11. iam_validator/checks/utils/sensitive_action_matcher.py +252 -0
  12. iam_validator/checks/utils/wildcard_expansion.py +89 -0
  13. iam_validator/commands/__init__.py +3 -1
  14. iam_validator/commands/cache.py +402 -0
  15. iam_validator/commands/validate.py +7 -5
  16. iam_validator/core/access_analyzer_report.py +2 -1
  17. iam_validator/core/aws_fetcher.py +79 -19
  18. iam_validator/core/check_registry.py +3 -0
  19. iam_validator/core/cli.py +1 -1
  20. iam_validator/core/config_loader.py +40 -3
  21. iam_validator/core/defaults.py +334 -0
  22. iam_validator/core/formatters/__init__.py +2 -0
  23. iam_validator/core/formatters/console.py +44 -7
  24. iam_validator/core/formatters/csv.py +7 -2
  25. iam_validator/core/formatters/enhanced.py +433 -0
  26. iam_validator/core/formatters/html.py +127 -37
  27. iam_validator/core/formatters/markdown.py +10 -2
  28. iam_validator/core/models.py +30 -6
  29. iam_validator/core/policy_checks.py +21 -2
  30. iam_validator/core/report.py +112 -26
  31. iam_policy_validator-1.0.4.dist-info/RECORD +0 -45
  32. {iam_policy_validator-1.0.4.dist-info → iam_policy_validator-1.1.1.dist-info}/WHEEL +0 -0
  33. {iam_policy_validator-1.0.4.dist-info → iam_policy_validator-1.1.1.dist-info}/entry_points.txt +0 -0
  34. {iam_policy_validator-1.0.4.dist-info → iam_policy_validator-1.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,73 +1,22 @@
1
- """Action validation check - validates IAM actions against AWS service definitions."""
1
+ """Action validation check - validates IAM actions against AWS service definitions.
2
2
 
3
- import re
4
- from functools import lru_cache
5
- from re import Pattern
3
+ This check ensures that all actions specified in IAM policies are valid actions
4
+ defined by AWS services. It helps identify typos or deprecated actions that may
5
+ lead to unintended access permissions.
6
+
7
+ This check is not necessary when using Access Analyzer, as it performs similar
8
+ validations. However, it can be useful in environments where Access Analyzer is
9
+ not available or for pre-deployment policy validation to catch errors early.
10
+ """
6
11
 
7
12
  from iam_validator.core.aws_fetcher import AWSServiceFetcher
8
13
  from iam_validator.core.check_registry import CheckConfig, PolicyCheck
9
14
  from iam_validator.core.models import Statement, ValidationIssue
10
15
 
11
16
 
12
- # Global cache for compiled wildcard patterns
13
- @lru_cache(maxsize=512)
14
- def _compile_wildcard_pattern(pattern: str) -> Pattern[str]:
15
- """Compile and cache wildcard patterns for O(1) reuse.
16
-
17
- Args:
18
- pattern: Wildcard pattern (e.g., "s3:Get*")
19
-
20
- Returns:
21
- Compiled regex pattern
22
-
23
- Performance:
24
- 20-30x speedup by avoiding repeated pattern compilation
25
- """
26
- regex_pattern = "^" + re.escape(pattern).replace(r"\*", ".*") + "$"
27
- return re.compile(regex_pattern, re.IGNORECASE)
28
-
29
-
30
17
  class ActionValidationCheck(PolicyCheck):
31
18
  """Validates that IAM actions exist in AWS services."""
32
19
 
33
- # Default allowlist for safe wildcard patterns (read-only operations)
34
- # Note: s3:Get* is intentionally excluded as reading S3 data can be sensitive
35
- # Using frozenset for O(1) lookup performance
36
- DEFAULT_ALLOWED_WILDCARDS = frozenset(
37
- {
38
- "s3:List*",
39
- "s3:Describe*",
40
- "ec2:Describe*",
41
- "iam:Get*",
42
- "iam:List*",
43
- "rds:Describe*",
44
- "lambda:Get*",
45
- "lambda:List*",
46
- "dynamodb:Describe*",
47
- "cloudwatch:Describe*",
48
- "cloudwatch:Get*",
49
- "cloudwatch:List*",
50
- "logs:Describe*",
51
- "logs:Get*",
52
- "logs:Filter*",
53
- "kms:Describe*",
54
- "kms:Get*",
55
- "kms:List*",
56
- "sns:Get*",
57
- "sns:List*",
58
- "sqs:Get*",
59
- "sqs:List*",
60
- "elasticloadbalancing:Describe*",
61
- "autoscaling:Describe*",
62
- "cloudformation:Describe*",
63
- "cloudformation:Get*",
64
- "cloudformation:List*",
65
- "route53:Get*",
66
- "route53:List*",
67
- "apigateway:GET",
68
- }
69
- )
70
-
71
20
  @property
72
21
  def check_id(self) -> str:
73
22
  return "action_validation"
@@ -80,41 +29,6 @@ class ActionValidationCheck(PolicyCheck):
80
29
  def default_severity(self) -> str:
81
30
  return "error"
82
31
 
83
- def _is_allowed_wildcard(
84
- self, action: str, allowed_wildcards: frozenset[str] | list[str] | set[str]
85
- ) -> bool:
86
- """Check if a wildcard action matches the allowlist.
87
-
88
- Args:
89
- action: The action to check (e.g., "s3:Get*")
90
- allowed_wildcards: Set or list of allowed wildcard patterns
91
-
92
- Returns:
93
- True if the action matches any pattern in the allowlist
94
-
95
- Note:
96
- Exact matches use O(1) set lookup for performance.
97
- Pattern matches (wildcards in allowlist) require O(n) iteration.
98
- """
99
- # Fast O(1) exact match using set membership
100
- if action in allowed_wildcards:
101
- return True
102
-
103
- # Pattern match - check if action matches any pattern in allowlist
104
- # This is needed when allowlist contains wildcards like "s3:*"
105
- # Uses cached compiled patterns for 20-30x speedup
106
- for pattern in allowed_wildcards:
107
- # Skip exact matches (already checked above)
108
- if "*" not in pattern:
109
- continue
110
-
111
- # Use cached compiled pattern
112
- compiled = _compile_wildcard_pattern(pattern)
113
- if compiled.match(action):
114
- return True
115
-
116
- return False
117
-
118
32
  async def execute(
119
33
  self,
120
34
  statement: Statement,
@@ -122,7 +36,11 @@ class ActionValidationCheck(PolicyCheck):
122
36
  fetcher: AWSServiceFetcher,
123
37
  config: CheckConfig,
124
38
  ) -> list[ValidationIssue]:
125
- """Execute action validation on a statement."""
39
+ """Execute action validation on a statement.
40
+
41
+ This check ONLY validates that actions exist in AWS service definitions.
42
+ Wildcard security checks are handled by security_best_practices_check.
43
+ """
126
44
  issues = []
127
45
 
128
46
  # Get actions from statement
@@ -130,28 +48,13 @@ class ActionValidationCheck(PolicyCheck):
130
48
  statement_sid = statement.sid
131
49
  line_number = statement.line_number
132
50
 
133
- # Get allowed wildcards from config, or use defaults
134
- allowed_wildcards_raw = config.config.get(
135
- "allowed_wildcards", self.DEFAULT_ALLOWED_WILDCARDS
136
- )
137
-
138
- # Convert list to frozenset for O(1) lookups (if from config)
139
- # DEFAULT_ALLOWED_WILDCARDS is already a frozenset
140
- if isinstance(allowed_wildcards_raw, list):
141
- allowed_wildcards = frozenset(allowed_wildcards_raw)
142
- else:
143
- allowed_wildcards = allowed_wildcards_raw
144
-
145
- # Check if wildcard warnings are disabled entirely
146
- disable_wildcard_warnings = config.config.get("disable_wildcard_warnings", False)
147
-
148
51
  for action in actions:
149
- # Wildcard-only actions are handled by security checks
150
- if action == "*":
52
+ # Skip wildcard actions - they're handled by security_best_practices_check
53
+ if action == "*" or "*" in action:
151
54
  continue
152
55
 
153
- # Validate the action
154
- is_valid, error_msg, is_wildcard = await fetcher.validate_action(action)
56
+ # Validate the action exists in AWS
57
+ is_valid, error_msg, _is_wildcard = await fetcher.validate_action(action)
155
58
 
156
59
  if not is_valid:
157
60
  issues.append(
@@ -165,28 +68,5 @@ class ActionValidationCheck(PolicyCheck):
165
68
  line_number=line_number,
166
69
  )
167
70
  )
168
- elif is_wildcard:
169
- # Check if this wildcard is in the allowlist
170
- if self._is_allowed_wildcard(action, allowed_wildcards):
171
- # Wildcard is allowed, skip warning
172
- continue
173
-
174
- # Wildcard actions are security concerns (unless disabled)
175
- # Note: This uses "info" severity by default because the security_best_practices
176
- # check provides more comprehensive wildcard analysis with proper security severities.
177
- # This is mainly informational - the action IS valid, just uses a wildcard.
178
- if not disable_wildcard_warnings:
179
- issues.append(
180
- ValidationIssue(
181
- severity="info", # Changed from "warning" - this is just informational
182
- statement_sid=statement_sid,
183
- statement_index=statement_idx,
184
- issue_type="wildcard_action",
185
- message=f"Action uses wildcard: {action}",
186
- action=action,
187
- suggestion="Consider using specific actions instead of wildcards for better security",
188
- line_number=line_number,
189
- )
190
- )
191
71
 
192
72
  return issues