iam-policy-validator 1.15.0__py3-none-any.whl → 1.15.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iam-policy-validator
3
- Version: 1.15.0
3
+ Version: 1.15.1
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://boogy.github.io/iam-policy-validator
@@ -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=nBQw8c9_j3cm0AjlGzltWfPi7BYKIJlC0VQImhHNMGQ,374
3
+ iam_validator/__version__.py,sha256=3sYnVKt3REhH-Klaa8pLaSXpDxcV1dV0Se9CjHHE4Nc,374
4
4
  iam_validator/checks/__init__.py,sha256=wFU5Lz-ZIQBcn2y1u0Kl88B--vEO3btOOaTGPPSjJ74,2106
5
5
  iam_validator/checks/action_condition_enforcement.py,sha256=2-XUMbof9tQ7SHZNmAHMkR1DgbOIzY2eFWlp9S9dwLk,60625
6
6
  iam_validator/checks/action_resource_matching.py,sha256=qND0hfDgNoxFEdLWwrxOPVDfdj3k50nzedT2qF7nK7o,19428
@@ -64,10 +64,10 @@ iam_validator/core/aws_service/fetcher.py,sha256=TqaCp6yKOEXCJdcQIFVBB5RW0pxLMOm
64
64
  iam_validator/core/aws_service/parsers.py,sha256=gJzR7HCD8ItCWCCbguTQIZpPEdj2rdMwC7LPhu7ve14,5174
65
65
  iam_validator/core/aws_service/patterns.py,sha256=gGc55Tn-EJ3cmcWtmYAZROUajKYz7DaMchYWGEhHpC0,1726
66
66
  iam_validator/core/aws_service/storage.py,sha256=A98ui_THAyZ86ik-t6HWB22vOqwmbFklG10uhdf26p4,10881
67
- iam_validator/core/aws_service/validators.py,sha256=qWMB4iQi9Oc0SGXOJVrlyjnsMwmPlqhUaywyRL4d-hM,19385
67
+ iam_validator/core/aws_service/validators.py,sha256=d2nGuy4NifbBiKbLIFHxP-wZctYDtK4qniSdq3l8-T0,21574
68
68
  iam_validator/core/config/__init__.py,sha256=CWSyIA7kEyzrskEenjYbs9Iih10BXRpiY9H2dHg61rU,2671
69
69
  iam_validator/core/config/aws_api.py,sha256=HLIzOItQ0A37wxHcgWck6ZFO0wmNY8JNTiWMMK6JKYU,1248
70
- iam_validator/core/config/aws_global_conditions.py,sha256=Ny20rnwp0OGxW8NdrHw8d3Lv3wh8YbL5vCIFQw7ZQh4,8006
70
+ iam_validator/core/config/aws_global_conditions.py,sha256=WQjR8z1Mhc8H874CnzwEMvKOz9rCifBNUltvo0oFYbM,7894
71
71
  iam_validator/core/config/category_suggestions.py,sha256=fopaZ9kXDrsLgi_r0pERrLwgdPPJl5VIiKvXtQK9tj0,8583
72
72
  iam_validator/core/config/check_documentation.py,sha256=-wK6-wfU7SEHX3h2Jj5pOFqgxD9ULW-NvEkSVp_66WA,18718
73
73
  iam_validator/core/config/condition_requirements.py,sha256=1CeQJfWV-Y2ImW0Mq9YdrgvH-hj9IXe0gVOm3B36Rc8,10655
@@ -112,8 +112,8 @@ iam_validator/utils/__init__.py,sha256=NveA2F3G1E6-ANZzFr7J6Q6u5mogvMp862iFokmYu
112
112
  iam_validator/utils/cache.py,sha256=wOQKOBeoG6QqC5f0oXcHz63Cjtu_-SsSS-0pTSwyAiM,3254
113
113
  iam_validator/utils/regex.py,sha256=xHoMECttb7qaMhts-c9b0GIxdhHNZTt-UBr7wNhWfzg,6219
114
114
  iam_validator/utils/terminal.py,sha256=FsRaRMH_JAyDgXWBCOgOEhbS89cs17HCmKYoughq5io,724
115
- iam_policy_validator-1.15.0.dist-info/METADATA,sha256=CkJmAGo-FcnQ0qpEb0_EDjNcbKRzTErYiIic3gUyHD8,34808
116
- iam_policy_validator-1.15.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
117
- iam_policy_validator-1.15.0.dist-info/entry_points.txt,sha256=VXAcx1evo9fuxX0Gtj3J2HnzWcBHSXugiZwBtQ1BXE0,162
118
- iam_policy_validator-1.15.0.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
119
- iam_policy_validator-1.15.0.dist-info/RECORD,,
115
+ iam_policy_validator-1.15.1.dist-info/METADATA,sha256=5U2vmBBtv-GXPRTflISPL-sOmq_kT9aWlDdOBsfbMnI,34808
116
+ iam_policy_validator-1.15.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
117
+ iam_policy_validator-1.15.1.dist-info/entry_points.txt,sha256=VXAcx1evo9fuxX0Gtj3J2HnzWcBHSXugiZwBtQ1BXE0,162
118
+ iam_policy_validator-1.15.1.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
119
+ iam_policy_validator-1.15.1.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.15.0"
6
+ __version__ = "1.15.1"
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("."))
@@ -243,22 +243,30 @@ class ServiceValidator:
243
243
  _, action_name = self._parser.parse_action(action)
244
244
 
245
245
  # Check if it's a global condition key
246
+ # Note: Some aws: prefixed keys like aws:RequestTag/* and aws:ResourceTag/* are NOT
247
+ # global keys - they're action-specific or resource-specific. We'll check those later.
246
248
  is_global_key = False
247
249
  if condition_key.startswith("aws:"):
248
250
  global_conditions = get_global_conditions()
249
251
  if global_conditions.is_valid_global_key(condition_key):
250
252
  is_global_key = True
251
- else:
252
- return ConditionKeyValidationResult(
253
- is_valid=False,
254
- error_message=f"Invalid AWS global condition key: `{condition_key}`.",
255
- )
253
+ # If not a global key, continue to check action/resource-specific keys
254
+ # Don't return an error yet - aws:RequestTag, aws:ResourceTag are action-specific
256
255
 
257
256
  # Check service-specific condition keys (with pattern matching for tag keys)
258
- if service_detail.condition_keys and condition_key_in_list(
259
- condition_key, list(service_detail.condition_keys.keys())
260
- ):
261
- return ConditionKeyValidationResult(is_valid=True)
257
+ # IMPORTANT: aws:RequestTag and aws:ResourceTag patterns in service-level keys
258
+ # are NOT universally valid for all actions. Skip them here - they'll be checked
259
+ # at action/resource level.
260
+ if service_detail.condition_keys:
261
+ # Check if it matches service-level keys, but exclude RequestTag/ResourceTag
262
+ if condition_key_in_list(condition_key, list(service_detail.condition_keys.keys())):
263
+ # If it's RequestTag or ResourceTag, don't return valid here - check action/resource level
264
+ if not (
265
+ condition_key.startswith("aws:RequestTag/")
266
+ or condition_key.startswith("aws:ResourceTag/")
267
+ ):
268
+ return ConditionKeyValidationResult(is_valid=True)
269
+ # For RequestTag/ResourceTag, continue to check action/resource level
262
270
 
263
271
  # Check action-specific condition keys
264
272
  if action_name in service_detail.actions:
@@ -298,8 +306,26 @@ class ServiceValidator:
298
306
  if is_global_key:
299
307
  return ConditionKeyValidationResult(is_valid=True)
300
308
 
301
- # Short error message
302
- error_msg = f"Condition key `{condition_key}` is not valid for action `{action}`"
309
+ # If we reach here, the condition key was not found in any valid location
310
+ # Check if it's an aws: prefixed key that's not global - provide specific error
311
+ if condition_key.startswith("aws:"):
312
+ # Special handling for aws:RequestTag and aws:ResourceTag patterns
313
+ if condition_key.startswith("aws:RequestTag/"):
314
+ error_msg = (
315
+ f"Condition key `{condition_key}` is not supported by action `{action}`. "
316
+ f"The `aws:RequestTag/${{TagKey}}` condition is only supported by actions that "
317
+ f"create or modify resources with tags. This action does not support tag operations."
318
+ )
319
+ elif condition_key.startswith("aws:ResourceTag/"):
320
+ error_msg = (
321
+ f"Condition key `{condition_key}` is not supported by the resources used by action `{action}`. "
322
+ f"The `aws:ResourceTag/${{TagKey}}` condition is only supported by resources that have tags."
323
+ )
324
+ else:
325
+ error_msg = f"Invalid AWS condition key: `{condition_key}`. This key is not a valid global condition key and is not supported by action `{action}`."
326
+ else:
327
+ # Short error message for non-aws: keys
328
+ error_msg = f"Condition key `{condition_key}` is not valid for action `{action}`"
303
329
 
304
330
  # Collect valid condition keys for this action
305
331
  valid_keys: set[str] = set()
@@ -85,17 +85,13 @@ GLOBAL_RESOURCE_SCOPING_CONDITION_KEYS = frozenset(
85
85
  )
86
86
 
87
87
  # Patterns that should be recognized (wildcards and tag-based keys)
88
- # These allow things like aws:RequestTag/Department or aws:PrincipalTag/Environment
88
+ # IMPORTANT: aws:RequestTag and aws:ResourceTag are NOT global condition keys!
89
+ # They are action-specific or resource-specific and must be explicitly listed in
90
+ # the action's ActionConditionKeys or the resource's ConditionKeys.
91
+ # Only aws:PrincipalTag is a true global condition key.
92
+ #
89
93
  # Uses centralized tag key character class from constants
90
94
  AWS_CONDITION_KEY_PATTERNS = [
91
- {
92
- "pattern": rf"^aws:RequestTag/[{AWS_TAG_KEY_ALLOWED_CHARS}]+$",
93
- "description": "Tag keys in the request (for tag-based access control)",
94
- },
95
- {
96
- "pattern": rf"^aws:ResourceTag/[{AWS_TAG_KEY_ALLOWED_CHARS}]+$",
97
- "description": "Tags on the resource being accessed",
98
- },
99
95
  {
100
96
  "pattern": rf"^aws:PrincipalTag/[{AWS_TAG_KEY_ALLOWED_CHARS}]+$",
101
97
  "description": "Tags attached to the principal making the request",