iam-policy-validator 1.10.2__py3-none-any.whl → 1.10.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iam-policy-validator
3
- Version: 1.10.2
3
+ Version: 1.10.3
4
4
  Summary: Validate AWS IAM policies for correctness and security using AWS Service Reference API
5
5
  Project-URL: Homepage, https://github.com/boogy/iam-policy-validator
6
6
  Project-URL: Documentation, https://github.com/boogy/iam-policy-validator/tree/main/docs
@@ -1,6 +1,6 @@
1
1
  iam_validator/__init__.py,sha256=xHdUASOxFHwEXfT_GSr_KrkLlnxZ-pAAr1wW1PwAGko,693
2
2
  iam_validator/__main__.py,sha256=to_nz3n_IerJpVVZZ6WSFlFR5s_06J0csfPOTfQZG8g,197
3
- iam_validator/__version__.py,sha256=Fz08JonmD1dXoibF83ZYkSo1e0IWJO9aJ4iIAfq64mI,374
3
+ iam_validator/__version__.py,sha256=UMITyOhvLRTs5TZWk4U4b0IKHWjVN05qKIVWOKq-Gx8,374
4
4
  iam_validator/checks/__init__.py,sha256=OTkPnmlelu4YjMO8krjhu2wXiTV72RzopA5u1SfPQA0,1990
5
5
  iam_validator/checks/action_condition_enforcement.py,sha256=0dCH_xX-Xc0uLxtNeRjrpNjWYbdWQRzO1XNcLTSn6sI,51698
6
6
  iam_validator/checks/action_resource_matching.py,sha256=WiGJmCIJfx5yituMjZxpKmk-99N6nK20ueN02ddy9oM,19296
@@ -20,7 +20,7 @@ iam_validator/checks/set_operator_validation.py,sha256=FyxZ7qWlp9-ABzZaRRkxRP_Hw
20
20
  iam_validator/checks/sid_uniqueness.py,sha256=vfpk88b9G9OApxtrotABI2mPXvGd_C_X4gJKeqIURlk,5968
21
21
  iam_validator/checks/trust_policy_validation.py,sha256=a8Sm2xu3gFOHLd7rXDl-ibqiLEmg5c-dyWv1lK2i6HA,17816
22
22
  iam_validator/checks/wildcard_action.py,sha256=CyURgURDt2fQT2468LK813RupQ3WWvpmvLVLjUZf9QQ,1960
23
- iam_validator/checks/wildcard_resource.py,sha256=AidyyKMQL3PxLI6Zd-iFiiI6BnvSle4ATLwDXUmV3jQ,5404
23
+ iam_validator/checks/wildcard_resource.py,sha256=lRNZN7f3ZQrvnbGdVDCefUQF8lESIMoXVfhIgpln3mM,6679
24
24
  iam_validator/checks/utils/__init__.py,sha256=j0X4ibUB6RGx2a-kNoJnlVZwHfoEvzZsIeTmJIAoFzA,45
25
25
  iam_validator/checks/utils/policy_level_checks.py,sha256=2V60C0zhKfsFPjQ-NMlD3EemtwA9S6-4no8nETgXdQE,5274
26
26
  iam_validator/checks/utils/sensitive_action_matcher.py,sha256=qDXcJa_2sCJu9pBbjDlI7x5lPtLRc6jQCpKPMheCOJQ,11215
@@ -61,7 +61,7 @@ iam_validator/core/config/aws_global_conditions.py,sha256=gdmMxXGBy95B3uYUG-J7rn
61
61
  iam_validator/core/config/category_suggestions.py,sha256=QlrYi4BTkxDSTlL7NZGE9BWN-atWetZ6XjkI9F_7YzI,4370
62
62
  iam_validator/core/config/condition_requirements.py,sha256=qauIP73HFnOw1dchUeFpg1x7Y7QWkILo3GfxV_dxdQo,7696
63
63
  iam_validator/core/config/config_loader.py,sha256=qKD8aR8YAswaFf68pnYJLFNwKznvcc6lNxSQWU3i6SY,17713
64
- iam_validator/core/config/defaults.py,sha256=qpFP534dgCQ-vjCdhkK7ZslDoTm9Ftgy20qmYZsSYUI,28637
64
+ iam_validator/core/config/defaults.py,sha256=bI0MC3x7q6TVDxJxFs0MeyVRMmANGyfOOdvOWQQAuKc,30103
65
65
  iam_validator/core/config/principal_requirements.py,sha256=VCX7fBDgeDTJQyoz7_x7GI7Kf9O1Eu-sbihoHOrKv6o,15105
66
66
  iam_validator/core/config/sensitive_actions.py,sha256=uATDIp_TD3OQQlsYTZp79qd1mSK2Bf9hJ0JwcqLBr84,25344
67
67
  iam_validator/core/config/service_principals.py,sha256=8pys5H_yycVJ9KTyimAKFYBg83Aol2Iri53wiHjtnEM,3959
@@ -89,8 +89,8 @@ iam_validator/utils/__init__.py,sha256=NveA2F3G1E6-ANZzFr7J6Q6u5mogvMp862iFokmYu
89
89
  iam_validator/utils/cache.py,sha256=wOQKOBeoG6QqC5f0oXcHz63Cjtu_-SsSS-0pTSwyAiM,3254
90
90
  iam_validator/utils/regex.py,sha256=xHoMECttb7qaMhts-c9b0GIxdhHNZTt-UBr7wNhWfzg,6219
91
91
  iam_validator/utils/terminal.py,sha256=FsRaRMH_JAyDgXWBCOgOEhbS89cs17HCmKYoughq5io,724
92
- iam_policy_validator-1.10.2.dist-info/METADATA,sha256=t5vzMawKVACC8uFWNJznjMBvw4xX9T7z1EduP8HbAQA,19070
93
- iam_policy_validator-1.10.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
- iam_policy_validator-1.10.2.dist-info/entry_points.txt,sha256=8HtWd8O7mvPiPdZR5YbzY8or_qcqLM4-pKaFdhtFT8M,62
95
- iam_policy_validator-1.10.2.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
96
- iam_policy_validator-1.10.2.dist-info/RECORD,,
92
+ iam_policy_validator-1.10.3.dist-info/METADATA,sha256=TNwd0AdEvphwtPx0E8AoHsNNyYzTcl6QUDT6dRqqyEE,19070
93
+ iam_policy_validator-1.10.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
+ iam_policy_validator-1.10.3.dist-info/entry_points.txt,sha256=8HtWd8O7mvPiPdZR5YbzY8or_qcqLM4-pKaFdhtFT8M,62
95
+ iam_policy_validator-1.10.3.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
96
+ iam_policy_validator-1.10.3.dist-info/RECORD,,
@@ -3,7 +3,7 @@
3
3
  This file is the single source of truth for the package version.
4
4
  """
5
5
 
6
- __version__ = "1.10.2"
6
+ __version__ = "1.10.3"
7
7
  # Parse version, handling pre-release suffixes like -rc, -alpha, -beta
8
8
  _version_base = __version__.split("-", maxsplit=1)[0] # Remove pre-release suffix if present
9
9
  __version_info__ = tuple(int(part) for part in _version_base.split("."))
@@ -39,22 +39,44 @@ class WildcardResourceCheck(PolicyCheck):
39
39
  # to all matching AWS actions using the AWS API, then checking if the policy's
40
40
  # actions are in that expanded list. This ensures only validated AWS actions
41
41
  # are allowed with Resource: "*".
42
+ allowed_wildcards_config = config.config.get("allowed_wildcards", [])
42
43
  allowed_wildcards_expanded = await self._get_expanded_allowed_wildcards(config, fetcher)
43
44
 
44
45
  # Check if ALL actions (excluding full wildcard "*") are in the expanded list
45
46
  non_wildcard_actions = [a for a in actions if a != "*"]
46
47
 
47
- if allowed_wildcards_expanded and non_wildcard_actions:
48
- # Check if all actions are in the expanded allowed list (exact match)
49
- all_actions_allowed = all(
50
- action in allowed_wildcards_expanded for action in non_wildcard_actions
48
+ if (allowed_wildcards_config or allowed_wildcards_expanded) and non_wildcard_actions:
49
+ # Strategy 1: Check literal pattern match (fast path)
50
+ # If policy action matches config pattern literally, allow it
51
+ # Example: Policy has "iam:Get*", config has "iam:Get*" -> match
52
+ all_actions_allowed_literal = all(
53
+ action in allowed_wildcards_config for action in non_wildcard_actions
51
54
  )
52
55
 
53
- # If all actions are in the expanded list, skip the wildcard resource warning
54
- if all_actions_allowed:
55
- # All actions are safe, Resource: "*" is acceptable
56
+ if all_actions_allowed_literal:
57
+ # All actions match literally, Resource: "*" is acceptable
56
58
  return issues
57
59
 
60
+ # Strategy 2: Check expanded pattern match (comprehensive path)
61
+ # Expand both policy actions and config patterns, then compare
62
+ # Example: Policy has "iam:Get*" -> ["iam:GetUser", ...],
63
+ # config has "iam:Get*" -> ["iam:GetUser", ...] -> all match
64
+ if allowed_wildcards_expanded:
65
+ expanded_statement_actions = await expand_wildcard_actions(
66
+ non_wildcard_actions, fetcher
67
+ )
68
+
69
+ # Check if all expanded actions are in the expanded allowed list (exact match)
70
+ all_actions_allowed_expanded = all(
71
+ action in allowed_wildcards_expanded
72
+ for action in expanded_statement_actions
73
+ )
74
+
75
+ # If all actions are in the expanded list, skip the wildcard resource warning
76
+ if all_actions_allowed_expanded:
77
+ # All actions are safe, Resource: "*" is acceptable
78
+ return issues
79
+
58
80
  # Flag the issue if actions are not all allowed or no allowed_wildcards configured
59
81
  message = config.config.get(
60
82
  "message", 'Statement applies to all resources `"*"` (wildcard resource).'
@@ -344,13 +344,41 @@ DEFAULT_CONFIG = {
344
344
  # Check for wildcard resources (Resource: "*")
345
345
  # Flags statements that apply to all resources
346
346
  # Exception: Allowed if ALL actions are in allowed_wildcards list
347
+ #
348
+ # DUAL MATCHING STRATEGY:
349
+ # The check uses two complementary matching strategies for maximum flexibility:
350
+ #
351
+ # 1. LITERAL MATCH (Fast Path - no AWS API calls):
352
+ # Policy actions match config patterns exactly as strings
353
+ # Example: Policy "iam:Get*" matches config "iam:Get*" → PASS
354
+ #
355
+ # 2. EXPANDED MATCH (Comprehensive Path - uses AWS API):
356
+ # Both policy actions and config patterns expand to actual AWS actions
357
+ # Example: Policy "iam:GetUser" matches config "iam:Get*" (expanded) → PASS
358
+ #
359
+ # SUPPORTED SCENARIOS:
360
+ # Policy Action Config Pattern Match Type Result
361
+ # iam:Get* iam:Get* Literal ✅ Pass
362
+ # iam:GetUser iam:Get* Expanded ✅ Pass
363
+ # iam:Get*, iam:List* iam:Get*, iam:List* Literal ✅ Pass
364
+ # iam:Get*, iam:GetUser iam:Get* Literal ✅ Pass
365
+ # iam:Delete* iam:Get* None ❌ Fail
366
+ #
367
+ # PERFORMANCE TIP: Literal matching is faster (no AWS API expansion)
347
368
  "wildcard_resource": {
348
369
  "enabled": True,
349
370
  "severity": "medium", # Security issue
350
371
  "description": "Checks for wildcard resources (*)",
351
372
  # Allowed wildcard patterns for actions that can be used with Resource: "*"
373
+ # Supports BOTH literal matching and pattern expansion via AWS API
374
+ #
352
375
  # Default: 25 read-only patterns (Describe*, List*, Get*)
353
376
  # See: iam_validator/core/config/wildcards.py
377
+ #
378
+ # Examples:
379
+ # ["ec2:Describe*"] # Matches: ec2:Describe* (literal) OR ec2:DescribeInstances (expanded)
380
+ # ["iam:GetUser"] # Matches: iam:GetUser only
381
+ # ["s3:List*"] # Matches: s3:List* (literal) OR s3:ListBucket (expanded)
354
382
  "allowed_wildcards": list(DEFAULT_ALLOWED_WILDCARDS),
355
383
  "message": "Statement applies to all resources (*)",
356
384
  "suggestion": "Replace wildcard with specific resource ARNs",