iam-policy-validator 1.14.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.
Files changed (106) hide show
  1. iam_policy_validator-1.14.0.dist-info/METADATA +782 -0
  2. iam_policy_validator-1.14.0.dist-info/RECORD +106 -0
  3. iam_policy_validator-1.14.0.dist-info/WHEEL +4 -0
  4. iam_policy_validator-1.14.0.dist-info/entry_points.txt +2 -0
  5. iam_policy_validator-1.14.0.dist-info/licenses/LICENSE +21 -0
  6. iam_validator/__init__.py +27 -0
  7. iam_validator/__main__.py +11 -0
  8. iam_validator/__version__.py +9 -0
  9. iam_validator/checks/__init__.py +45 -0
  10. iam_validator/checks/action_condition_enforcement.py +1442 -0
  11. iam_validator/checks/action_resource_matching.py +472 -0
  12. iam_validator/checks/action_validation.py +67 -0
  13. iam_validator/checks/condition_key_validation.py +88 -0
  14. iam_validator/checks/condition_type_mismatch.py +257 -0
  15. iam_validator/checks/full_wildcard.py +62 -0
  16. iam_validator/checks/mfa_condition_check.py +105 -0
  17. iam_validator/checks/policy_size.py +114 -0
  18. iam_validator/checks/policy_structure.py +556 -0
  19. iam_validator/checks/policy_type_validation.py +331 -0
  20. iam_validator/checks/principal_validation.py +708 -0
  21. iam_validator/checks/resource_validation.py +135 -0
  22. iam_validator/checks/sensitive_action.py +438 -0
  23. iam_validator/checks/service_wildcard.py +98 -0
  24. iam_validator/checks/set_operator_validation.py +153 -0
  25. iam_validator/checks/sid_uniqueness.py +146 -0
  26. iam_validator/checks/trust_policy_validation.py +509 -0
  27. iam_validator/checks/utils/__init__.py +17 -0
  28. iam_validator/checks/utils/action_parser.py +149 -0
  29. iam_validator/checks/utils/policy_level_checks.py +190 -0
  30. iam_validator/checks/utils/sensitive_action_matcher.py +293 -0
  31. iam_validator/checks/utils/wildcard_expansion.py +86 -0
  32. iam_validator/checks/wildcard_action.py +58 -0
  33. iam_validator/checks/wildcard_resource.py +374 -0
  34. iam_validator/commands/__init__.py +31 -0
  35. iam_validator/commands/analyze.py +549 -0
  36. iam_validator/commands/base.py +48 -0
  37. iam_validator/commands/cache.py +393 -0
  38. iam_validator/commands/completion.py +471 -0
  39. iam_validator/commands/download_services.py +255 -0
  40. iam_validator/commands/post_to_pr.py +86 -0
  41. iam_validator/commands/query.py +485 -0
  42. iam_validator/commands/validate.py +830 -0
  43. iam_validator/core/__init__.py +13 -0
  44. iam_validator/core/access_analyzer.py +671 -0
  45. iam_validator/core/access_analyzer_report.py +640 -0
  46. iam_validator/core/aws_fetcher.py +29 -0
  47. iam_validator/core/aws_service/__init__.py +21 -0
  48. iam_validator/core/aws_service/cache.py +108 -0
  49. iam_validator/core/aws_service/client.py +205 -0
  50. iam_validator/core/aws_service/fetcher.py +641 -0
  51. iam_validator/core/aws_service/parsers.py +149 -0
  52. iam_validator/core/aws_service/patterns.py +51 -0
  53. iam_validator/core/aws_service/storage.py +291 -0
  54. iam_validator/core/aws_service/validators.py +380 -0
  55. iam_validator/core/check_registry.py +679 -0
  56. iam_validator/core/cli.py +134 -0
  57. iam_validator/core/codeowners.py +245 -0
  58. iam_validator/core/condition_validators.py +626 -0
  59. iam_validator/core/config/__init__.py +81 -0
  60. iam_validator/core/config/aws_api.py +35 -0
  61. iam_validator/core/config/aws_global_conditions.py +160 -0
  62. iam_validator/core/config/category_suggestions.py +181 -0
  63. iam_validator/core/config/check_documentation.py +390 -0
  64. iam_validator/core/config/condition_requirements.py +258 -0
  65. iam_validator/core/config/config_loader.py +670 -0
  66. iam_validator/core/config/defaults.py +739 -0
  67. iam_validator/core/config/principal_requirements.py +421 -0
  68. iam_validator/core/config/sensitive_actions.py +672 -0
  69. iam_validator/core/config/service_principals.py +132 -0
  70. iam_validator/core/config/wildcards.py +127 -0
  71. iam_validator/core/constants.py +149 -0
  72. iam_validator/core/diff_parser.py +325 -0
  73. iam_validator/core/finding_fingerprint.py +131 -0
  74. iam_validator/core/formatters/__init__.py +27 -0
  75. iam_validator/core/formatters/base.py +147 -0
  76. iam_validator/core/formatters/console.py +68 -0
  77. iam_validator/core/formatters/csv.py +171 -0
  78. iam_validator/core/formatters/enhanced.py +481 -0
  79. iam_validator/core/formatters/html.py +672 -0
  80. iam_validator/core/formatters/json.py +33 -0
  81. iam_validator/core/formatters/markdown.py +64 -0
  82. iam_validator/core/formatters/sarif.py +251 -0
  83. iam_validator/core/ignore_patterns.py +297 -0
  84. iam_validator/core/ignore_processor.py +309 -0
  85. iam_validator/core/ignored_findings.py +400 -0
  86. iam_validator/core/label_manager.py +197 -0
  87. iam_validator/core/models.py +404 -0
  88. iam_validator/core/policy_checks.py +220 -0
  89. iam_validator/core/policy_loader.py +785 -0
  90. iam_validator/core/pr_commenter.py +780 -0
  91. iam_validator/core/report.py +942 -0
  92. iam_validator/integrations/__init__.py +28 -0
  93. iam_validator/integrations/github_integration.py +1821 -0
  94. iam_validator/integrations/ms_teams.py +442 -0
  95. iam_validator/sdk/__init__.py +220 -0
  96. iam_validator/sdk/arn_matching.py +382 -0
  97. iam_validator/sdk/context.py +222 -0
  98. iam_validator/sdk/exceptions.py +48 -0
  99. iam_validator/sdk/helpers.py +177 -0
  100. iam_validator/sdk/policy_utils.py +451 -0
  101. iam_validator/sdk/query_utils.py +454 -0
  102. iam_validator/sdk/shortcuts.py +283 -0
  103. iam_validator/utils/__init__.py +35 -0
  104. iam_validator/utils/cache.py +105 -0
  105. iam_validator/utils/regex.py +205 -0
  106. iam_validator/utils/terminal.py +22 -0
@@ -0,0 +1,739 @@
1
+ """
2
+ Default configuration for IAM Policy Validator.
3
+
4
+ This module contains the default configuration that is used when no user
5
+ configuration file is provided. User configuration files will override
6
+ these defaults.
7
+
8
+ This configuration uses Python-native data structures (imported from
9
+ iam_validator.core.config) for optimal performance and PyPI packaging.
10
+
11
+ Benefits of code-first approach:
12
+ - Zero parsing overhead (no YAML/JSON parsing)
13
+ - Compiled to .pyc for faster imports
14
+ - Better IDE support and type hints
15
+ - No data files to manage in PyPI package
16
+ - 5-10x faster than YAML parsing
17
+ """
18
+
19
+ from iam_validator.core import constants
20
+ from iam_validator.core.config.category_suggestions import get_category_suggestions
21
+ from iam_validator.core.config.condition_requirements import CONDITION_REQUIREMENTS
22
+ from iam_validator.core.config.principal_requirements import (
23
+ get_default_principal_requirements,
24
+ )
25
+ from iam_validator.core.config.wildcards import (
26
+ DEFAULT_ALLOWED_WILDCARDS,
27
+ DEFAULT_SERVICE_WILDCARDS,
28
+ )
29
+
30
+ # ============================================================================
31
+ # SEVERITY LEVELS
32
+ # ============================================================================
33
+ # The validator uses two types of severity levels:
34
+ #
35
+ # 1. IAM VALIDITY SEVERITIES (for AWS IAM policy correctness):
36
+ # - error: Policy violates AWS IAM rules (invalid actions, ARNs, etc.)
37
+ # - warning: Policy may have IAM-related issues but is technically valid
38
+ # - info: Informational messages about the policy structure
39
+ #
40
+ # 2. SECURITY SEVERITIES (for security best practices):
41
+ # - critical: Critical security risk (e.g., wildcard action + resource)
42
+ # - high: High security risk (e.g., missing required conditions)
43
+ # - medium: Medium security risk (e.g., overly permissive wildcards)
44
+ # - low: Low security risk (e.g., minor best practice violations)
45
+ #
46
+ # Use 'error' for policy validity issues, and 'critical/high/medium/low' for
47
+ # security best practices. This distinction helps separate "broken policies"
48
+ # from "insecure but valid policies".
49
+ # ============================================================================
50
+
51
+ # ============================================================================
52
+ # DEFAULT CONFIGURATION
53
+ # ============================================================================
54
+ DEFAULT_CONFIG = {
55
+ # ========================================================================
56
+ # Global Settings
57
+ # ========================================================================
58
+ "settings": {
59
+ # Stop validation on first error
60
+ "fail_fast": False,
61
+ # Maximum number of concurrent policy validations
62
+ "max_concurrent": 10,
63
+ # Enable/disable ALL built-in checks (set to False when using AWS Access Analyzer)
64
+ "enable_builtin_checks": True,
65
+ # Enable parallel execution of checks for better performance
66
+ "parallel_execution": True,
67
+ # Path to directory containing pre-downloaded AWS service definitions
68
+ # Set to a directory path to use offline validation, or None to use AWS API
69
+ "aws_services_dir": None,
70
+ # Cache AWS service definitions locally (persists between runs)
71
+ "cache_enabled": True,
72
+ # Cache TTL in hours (default: 168 = 7 days)
73
+ "cache_ttl_hours": constants.DEFAULT_CACHE_TTL_HOURS,
74
+ # Severity levels that cause validation to fail
75
+ # IAM Validity: error, warning, info
76
+ # Security: critical, high, medium, low
77
+ "fail_on_severity": list(constants.HIGH_SEVERITY_LEVELS),
78
+ # GitHub PR label mapping based on severity findings
79
+ # When issues with these severities are found, apply the corresponding labels
80
+ # If no issues with these severities exist, remove the labels if present
81
+ # Supports both single labels and lists of labels per severity
82
+ # Examples:
83
+ # Single label per severity: {"error": "iam-validity-error", "critical": "security-critical"}
84
+ # Multiple labels per severity: {"error": ["iam-error", "needs-fix"], "critical": ["security-critical", "needs-review"]}
85
+ # Mixed: {"error": "iam-validity-error", "critical": ["security-critical", "needs-review"]}
86
+ # Default: {} (disabled)
87
+ "severity_labels": {},
88
+ # CODEOWNERS-based finding ignore settings
89
+ # Allows CODEOWNERS to ignore validation findings by replying "ignore" to PR comments
90
+ # Ignored findings won't cause the action to fail and won't be posted as comments
91
+ "ignore_settings": {
92
+ # Enable/disable the CODEOWNERS ignore feature
93
+ "enabled": True,
94
+ # Fallback list of users who can ignore findings when no CODEOWNERS file exists
95
+ # If empty and no CODEOWNERS, all ignore requests are denied (fail secure)
96
+ # Example: ["security-team-lead", "platform-admin"]
97
+ "allowed_users": [],
98
+ # Whether to post visible replies when ignore requests are denied
99
+ # When False (default), denials are only logged
100
+ # When True, a reply is posted explaining why the ignore was denied
101
+ "post_denial_feedback": False,
102
+ },
103
+ # Organization-specific documentation URL configuration
104
+ # Allows overriding default AWS documentation links with org-specific runbooks
105
+ "documentation": {
106
+ # Base URL for org-specific runbooks (null = use AWS docs)
107
+ # Example: "https://wiki.mycompany.com/security/iam-checks"
108
+ # When set, check documentation URLs will be: {base_url}/{check_id}
109
+ "base_url": None,
110
+ # Include AWS documentation links alongside org docs
111
+ "include_aws_docs": True,
112
+ },
113
+ },
114
+ # ========================================================================
115
+ # AWS IAM Validation Checks (17 checks total)
116
+ # These validate that policies conform to AWS IAM requirements
117
+ # ========================================================================
118
+ # ========================================================================
119
+ # 1. SID UNIQUENESS
120
+ # ========================================================================
121
+ # Validate Statement ID (Sid) uniqueness as per AWS IAM requirements
122
+ # AWS requires:
123
+ # - Sids must be unique within the policy (duplicate_sid error)
124
+ # - Sids must contain only alphanumeric characters, hyphens, and underscores
125
+ # - No spaces or special characters allowed
126
+ "sid_uniqueness": {
127
+ "enabled": True,
128
+ "severity": "error", # IAM validity error
129
+ "description": "Validates that Statement IDs (Sids) are unique and follow AWS naming requirements",
130
+ },
131
+ # ========================================================================
132
+ # 2. POLICY SIZE
133
+ # ========================================================================
134
+ # Validate policy size against AWS limits
135
+ # Policy type determines which AWS limit to enforce:
136
+ # - managed: 6144 characters (excluding whitespace)
137
+ # - inline_user: 2048 characters
138
+ # - inline_group: 5120 characters
139
+ # - inline_role: 10240 characters
140
+ "policy_size": {
141
+ "enabled": True,
142
+ "severity": "error", # IAM validity error
143
+ "description": "Validates that IAM policies don't exceed AWS size limits",
144
+ "policy_type": "managed", # Change based on your policy type
145
+ },
146
+ # ========================================================================
147
+ # 3. ACTION VALIDATION
148
+ # ========================================================================
149
+ # Validate IAM actions against AWS service definitions
150
+ # Uses AWS Service Authorization Reference to validate action names
151
+ # Catches typos like "s3:GetObjekt" or non-existent actions
152
+ "action_validation": {
153
+ "enabled": True,
154
+ "severity": "error", # IAM validity error
155
+ "description": "Validates that actions exist in AWS services",
156
+ },
157
+ # ========================================================================
158
+ # 4. CONDITION KEY VALIDATION
159
+ # ========================================================================
160
+ # Validate condition keys for actions against AWS service definitions
161
+ # Ensures condition keys are valid for the specified actions
162
+ # Examples:
163
+ # ✅ s3:GetObject with s3:prefix condition
164
+ # ❌ s3:GetObject with ec2:InstanceType condition (invalid)
165
+ "condition_key_validation": {
166
+ "enabled": True,
167
+ "severity": "error", # IAM validity error
168
+ "description": "Validates condition keys against AWS service definitions for specified actions",
169
+ # Validate aws:* global condition keys against known list
170
+ "validate_aws_global_keys": True,
171
+ # Warn when global condition keys (aws:*) are used with actions that have action-specific keys
172
+ # While global condition keys can be used across all AWS services, they may not be available
173
+ # in every request context. This warning helps ensure proper validation.
174
+ # Set to False to disable warnings for global condition keys
175
+ "warn_on_global_condition_keys": False,
176
+ },
177
+ # ========================================================================
178
+ # 5. CONDITION TYPE MISMATCH
179
+ # ========================================================================
180
+ # Validate condition type matching
181
+ # Ensures condition operators match the expected types for condition keys
182
+ # Examples:
183
+ # ✅ StringEquals with string condition key
184
+ # ❌ NumericEquals with string condition key (type mismatch)
185
+ # ✅ DateGreaterThan with date condition key
186
+ # ❌ StringLike with date condition key (type mismatch)
187
+ "condition_type_mismatch": {
188
+ "enabled": True,
189
+ "severity": "error", # IAM validity error
190
+ "description": "Validates that condition operators match the expected types for condition keys",
191
+ },
192
+ # ========================================================================
193
+ # 6. SET OPERATOR VALIDATION
194
+ # ========================================================================
195
+ # Validate set operator usage (ForAllValues/ForAnyValue)
196
+ # Ensures set operators are only used with multi-value condition keys
197
+ # Using them with single-value keys can cause unexpected behavior
198
+ "set_operator_validation": {
199
+ "enabled": True,
200
+ "severity": "error", # IAM validity error
201
+ "description": "Validates that set operators are used with multi-value condition keys",
202
+ },
203
+ # ========================================================================
204
+ # 7. MFA CONDITION ANTIPATTERN
205
+ # ========================================================================
206
+ # Detect MFA condition anti-patterns
207
+ # Identifies dangerous MFA-related patterns that may not enforce MFA as intended:
208
+ # 1. Bool with aws:MultiFactorAuthPresent = false (key may not exist)
209
+ # 2. Null with aws:MultiFactorAuthPresent = false (only checks existence)
210
+ "mfa_condition_antipattern": {
211
+ "enabled": True,
212
+ "severity": "warning", # Security concern, not an IAM validity error
213
+ "description": "Detects dangerous MFA-related condition patterns",
214
+ },
215
+ # ========================================================================
216
+ # 8. RESOURCE VALIDATION
217
+ # ========================================================================
218
+ # Validate resource ARN formats
219
+ # Ensures ARNs follow the correct format:
220
+ # arn:partition:service:region:account-id:resource-type/resource-id
221
+ # Pattern allows wildcards (*) in region and account fields
222
+ "resource_validation": {
223
+ "enabled": True,
224
+ "severity": "error", # IAM validity error
225
+ "description": "Validates ARN format for resources",
226
+ "arn_pattern": constants.DEFAULT_ARN_VALIDATION_PATTERN,
227
+ },
228
+ # ========================================================================
229
+ # 9. PRINCIPAL VALIDATION
230
+ # ========================================================================
231
+ # Validates Principal elements in resource-based policies
232
+ # Applies to: S3 buckets, SNS topics, SQS queues, Lambda functions, etc.
233
+ # Only runs when: --policy-type RESOURCE_POLICY
234
+ #
235
+ # Three control mechanisms:
236
+ # 1. blocked_principals - Block specific principals (deny list)
237
+ # 2. allowed_principals - Allow only specific principals (whitelist mode)
238
+ # 3. principal_condition_requirements - Require conditions for principals
239
+ # 4. allowed_service_principals - Always allow AWS service principals
240
+ "principal_validation": {
241
+ "enabled": True,
242
+ "severity": "high", # Security issue, not IAM validity error
243
+ "description": "Validates Principal elements in resource policies for security best practices",
244
+ # blocked_principals: Deny list - these principals are never allowed
245
+ # Default: ["*"] blocks public access
246
+ "blocked_principals": ["*"],
247
+ # allowed_principals: Whitelist mode - when set, ONLY these are allowed
248
+ # Default: [] allows all (except blocked)
249
+ "allowed_principals": [],
250
+ # principal_condition_requirements: Require conditions for specific principals
251
+ # Supports all_of/any_of/none_of logic like action_condition_enforcement
252
+ # Default: 2 enabled (public_access, prevent_insecure_transport)
253
+ # See: iam_validator/core/config/principal_requirements.py
254
+ "principal_condition_requirements": get_default_principal_requirements(),
255
+ # allowed_service_principals: AWS service principals (*.amazonaws.com)
256
+ # Default: ["aws:*"] allows ALL AWS service principals
257
+ # Note: "aws:*" is different from "*" (public access)
258
+ "allowed_service_principals": ["aws:*"],
259
+ },
260
+ # ========================================================================
261
+ # 10. TRUST POLICY VALIDATION
262
+ # ========================================================================
263
+ # Validate trust policies (role assumption policies) for security best practices
264
+ # Ensures assume role actions have appropriate principals and conditions
265
+ #
266
+ # Key validations:
267
+ # - Action-Principal type matching (e.g., AssumeRoleWithSAML needs Federated)
268
+ # - Provider ARN format validation (SAML vs OIDC provider patterns)
269
+ # - Required conditions per assume method
270
+ #
271
+ # Complements principal_validation check (which validates principal allowlists/blocklists)
272
+ # This check focuses on action-principal coupling specific to trust policies
273
+ #
274
+ # Auto-detection: Only runs on statements with assume role actions
275
+ "trust_policy_validation": {
276
+ "enabled": True, # Enabled by default (auto-detects trust policies)
277
+ "severity": "high", # Security issue
278
+ "description": "Validates trust policies for role assumption security and action-principal coupling",
279
+ # validation_rules: Custom rules override defaults
280
+ # Default rules validate:
281
+ # - sts:AssumeRole → AWS or Service principals
282
+ # - sts:AssumeRoleWithSAML → Federated (SAML provider) with SAML:aud
283
+ # - sts:AssumeRoleWithWebIdentity → Federated (OIDC provider)
284
+ # Example custom rules:
285
+ # "validation_rules": {
286
+ # "sts:AssumeRole": {
287
+ # "allowed_principal_types": ["AWS"], # Only AWS, not Service
288
+ # "required_conditions": ["sts:ExternalId"], # Always require ExternalId
289
+ # }
290
+ # }
291
+ },
292
+ # ========================================================================
293
+ # 11. POLICY TYPE VALIDATION
294
+ # ========================================================================
295
+ # Validate policy type requirements (new in v1.3.0)
296
+ # Ensures policies conform to the declared type (IDENTITY vs RESOURCE_POLICY)
297
+ # Also enforces RCP (Resource Control Policy) specific requirements
298
+ # RCP validation includes:
299
+ # - Must have Effect: Deny (RCPs are deny-only)
300
+ # - Must target specific resource types (no wildcards)
301
+ # - Principal must be "*" (applies to all)
302
+ "policy_type_validation": {
303
+ "enabled": True,
304
+ "severity": "error", # IAM validity error
305
+ "description": "Validates policies match declared type and enforces RCP requirements",
306
+ },
307
+ # ========================================================================
308
+ # 12. ACTION-RESOURCE MATCHING
309
+ # ========================================================================
310
+ # Validate action-resource matching
311
+ # Ensures resources match the required resource types for actions
312
+ # Handles both:
313
+ # 1. Account-level actions that require Resource: "*" (e.g., iam:ListUsers)
314
+ # 2. Resource-specific actions with correct ARN types (e.g., s3:GetObject)
315
+ # Inspired by Parliament's RESOURCE_MISMATCH check
316
+ # Examples:
317
+ # ✅ iam:ListUsers with Resource: "*"
318
+ # ❌ iam:ListUsers with arn:aws:iam::123:user/foo (account-level action)
319
+ # ✅ s3:GetObject with arn:aws:s3:::bucket/*
320
+ # ❌ s3:GetObject with arn:aws:s3:::bucket (missing /*)
321
+ # ✅ s3:ListBucket with arn:aws:s3:::bucket
322
+ # ❌ s3:ListBucket with arn:aws:s3:::bucket/* (should be bucket, not object)
323
+ "action_resource_matching": {
324
+ "enabled": True,
325
+ "severity": "error", # IAM validity error
326
+ "description": "Validates that resource ARNs match the required resource types for actions (including account-level actions)",
327
+ },
328
+ # ========================================================================
329
+ # Security Best Practices Checks (6 checks)
330
+ # ========================================================================
331
+ # Individual checks for security anti-patterns
332
+ #
333
+ # Configuration Fields Reference:
334
+ # - description: Technical description of what the check does (internal/docs)
335
+ # - message: Error/warning shown to users when issue is detected
336
+ # - suggestion: Guidance on how to fix or mitigate the issue
337
+ # - example: Concrete code example showing before/after or proper usage
338
+ #
339
+ # Field Progression: detect (description) → alert (message) → advise (suggestion) → demonstrate (example)
340
+ #
341
+ # For detailed explanation of these fields and how to customize them,
342
+ # see: docs/configuration.md#customizing-messages
343
+ #
344
+ # See: iam_validator/core/config/wildcards.py for allowed wildcards
345
+ # See: iam_validator/core/config/sensitive_actions.py for sensitive actions
346
+ # ========================================================================
347
+ # ========================================================================
348
+ # 13. WILDCARD ACTION
349
+ # ========================================================================
350
+ # Check for wildcard actions (Action: "*")
351
+ # Flags statements that allow all actions
352
+ "wildcard_action": {
353
+ "enabled": True,
354
+ "severity": "medium", # Security issue
355
+ "description": "Checks for wildcard actions (*)",
356
+ "message": "Statement allows all actions (*)",
357
+ "suggestion": "Replace wildcard with specific actions needed for your use case",
358
+ "example": (
359
+ "Replace:\n"
360
+ ' "Action": ["*"]\n'
361
+ "\n"
362
+ "With specific actions:\n"
363
+ ' "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"]\n'
364
+ ),
365
+ },
366
+ # ========================================================================
367
+ # 14. WILDCARD RESOURCE
368
+ # ========================================================================
369
+ # Check for wildcard resources (Resource: "*")
370
+ # Flags statements that apply to all resources
371
+ # Exception: Allowed if ALL actions are in allowed_wildcards list
372
+ #
373
+ # DUAL MATCHING STRATEGY:
374
+ # The check uses two complementary matching strategies for maximum flexibility:
375
+ #
376
+ # 1. LITERAL MATCH (Fast Path - no AWS API calls):
377
+ # Policy actions match config patterns exactly as strings
378
+ # Example: Policy "iam:Get*" matches config "iam:Get*" → PASS
379
+ #
380
+ # 2. EXPANDED MATCH (Comprehensive Path - uses AWS API):
381
+ # Both policy actions and config patterns expand to actual AWS actions
382
+ # Example: Policy "iam:GetUser" matches config "iam:Get*" (expanded) → PASS
383
+ #
384
+ # SUPPORTED SCENARIOS:
385
+ # Policy Action Config Pattern Match Type Result
386
+ # iam:Get* iam:Get* Literal ✅ Pass
387
+ # iam:GetUser iam:Get* Expanded ✅ Pass
388
+ # iam:Get*, iam:List* iam:Get*, iam:List* Literal ✅ Pass
389
+ # iam:Get*, iam:GetUser iam:Get* Literal ✅ Pass
390
+ # iam:Delete* iam:Get* None ❌ Fail
391
+ #
392
+ # PERFORMANCE TIP: Literal matching is faster (no AWS API expansion)
393
+ "wildcard_resource": {
394
+ "enabled": True,
395
+ "severity": "medium", # Security issue
396
+ "description": "Checks for wildcard resources (*)",
397
+ # Allowed wildcard patterns for actions that can be used with Resource: "*"
398
+ # Supports BOTH literal matching and pattern expansion via AWS API
399
+ #
400
+ # Default: 25 read-only patterns (Describe*, List*, Get*)
401
+ # See: iam_validator/core/config/wildcards.py
402
+ #
403
+ # Examples:
404
+ # ["ec2:Describe*"] # Matches: ec2:Describe* (literal) OR ec2:DescribeInstances (expanded)
405
+ # ["iam:GetUser"] # Matches: iam:GetUser only
406
+ # ["s3:List*"] # Matches: s3:List* (literal) OR s3:ListBucket (expanded)
407
+ "allowed_wildcards": list(DEFAULT_ALLOWED_WILDCARDS),
408
+ "message": "Statement applies to all resources (*)",
409
+ "suggestion": "Replace wildcard with specific resource ARNs",
410
+ "example": (
411
+ "Replace:\n"
412
+ ' "Resource": "*"\n'
413
+ "\n"
414
+ "With specific ARNs:\n"
415
+ ' "Resource": [\n'
416
+ ' "arn:aws:service:region:account-id:resource-type/resource-id",\n'
417
+ ' "arn:aws:service:region:account-id:resource-type/*"\n'
418
+ " ]\n"
419
+ ),
420
+ },
421
+ # ========================================================================
422
+ # 15. FULL WILDCARD (CRITICAL)
423
+ # ========================================================================
424
+ # Check for BOTH Action: "*" AND Resource: "*" (CRITICAL)
425
+ # This grants full administrative access (AdministratorAccess equivalent)
426
+ "full_wildcard": {
427
+ "enabled": True,
428
+ "severity": "critical", # CRITICAL security risk
429
+ "description": "Checks for both action and resource wildcards together (critical risk)",
430
+ "message": "Statement allows all actions on all resources - CRITICAL SECURITY RISK",
431
+ "suggestion": (
432
+ "This grants full administrative access. Replace both wildcards with specific actions "
433
+ "and resources to follow least-privilege principle"
434
+ ),
435
+ "example": (
436
+ "Replace:\n"
437
+ ' "Action": "*",\n'
438
+ ' "Resource": "*"\n'
439
+ "\n"
440
+ "With specific values:\n"
441
+ ' "Action": ["s3:GetObject", "s3:PutObject"],\n'
442
+ ' "Resource": ["arn:aws:s3:::my-bucket/*"]\n'
443
+ ),
444
+ },
445
+ # ========================================================================
446
+ # 16. SERVICE WILDCARD
447
+ # ========================================================================
448
+ # Check for service-level wildcards (e.g., "iam:*", "s3:*", "ec2:*")
449
+ # These grant ALL permissions for a service (often too permissive)
450
+ # Exception: Some services like logs, cloudwatch are typically safe
451
+ #
452
+ # Template placeholders supported in message/suggestion/example:
453
+ # - {action}: The wildcard action found (e.g., "s3:*")
454
+ # - {service}: The service name (e.g., "s3")
455
+ "service_wildcard": {
456
+ "enabled": True,
457
+ "severity": "high", # Security issue
458
+ "description": "Checks for service-level wildcards (e.g., 'iam:*', 's3:*')",
459
+ # Services that are allowed to use wildcards (default: logs, cloudwatch, xray)
460
+ # See: iam_validator/core/config/wildcards.py
461
+ "allowed_services": list(DEFAULT_SERVICE_WILDCARDS),
462
+ "message": "Service wildcard '{action}' grants all permissions for the {service} service",
463
+ "suggestion": (
464
+ "Replace '{action}' with specific actions needed for your use case to follow least-privilege principle.\n"
465
+ "Find valid {service} actions: https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html"
466
+ ),
467
+ "example": (
468
+ "Replace:\n"
469
+ ' "Action": ["{action}"]\n'
470
+ "\n"
471
+ "With specific actions:\n"
472
+ ' "Action": ["{service}:Describe*", "{service}:List*"]\n'
473
+ ),
474
+ },
475
+ # ========================================================================
476
+ # 17. SENSITIVE ACTION
477
+ # ========================================================================
478
+ # Check for sensitive actions without IAM conditions
479
+ # Sensitive actions: IAM changes, secrets access, destructive operations
480
+ # Default: 490 actions across 4 security risk categories
481
+ #
482
+ # Categories (with action counts):
483
+ # - credential_exposure (46): Actions exposing credentials, secrets, or tokens
484
+ # - data_access (109): Actions retrieving sensitive data
485
+ # - priv_esc (27): Actions enabling privilege escalation
486
+ # - resource_exposure (321): Actions modifying resource policies/permissions
487
+ #
488
+ # Scans at BOTH statement-level AND policy-level for security patterns
489
+ # See: iam_validator/core/config/sensitive_actions.py
490
+ # Source: https://github.com/primeharbor/sensitive_iam_actions
491
+ #
492
+ # Python API:
493
+ # from iam_validator.core.config.sensitive_actions import get_sensitive_actions
494
+ # # Get all sensitive actions (default)
495
+ # all_actions = get_sensitive_actions()
496
+ # # Get only specific categories
497
+ # priv_esc_only = get_sensitive_actions(['priv_esc'])
498
+ # # Get multiple categories
499
+ # critical = get_sensitive_actions(['credential_exposure', 'priv_esc'])
500
+ #
501
+ # Avoiding Duplicate Alerts:
502
+ # If you configure specific actions in action_condition_enforcement,
503
+ # use ignore_patterns to prevent duplicate alerts from sensitive_action:
504
+ #
505
+ # ignore_patterns:
506
+ # - action_matches: "^(iam:PassRole|iam:CreateUser|s3:PutObject)$"
507
+ #
508
+ # Template placeholders supported:
509
+ # - message_single uses {action}: Single action name (e.g., "iam:CreateRole")
510
+ # - message_multiple uses {actions}: Comma-separated list (e.g., "iam:CreateRole', 'iam:PutUserPolicy")
511
+ # - suggestion and example support both {action} and {actions}
512
+ "sensitive_action": {
513
+ "enabled": True,
514
+ "severity": "medium", # Security issue (can be overridden per-category)
515
+ "description": "Checks for sensitive actions without conditions",
516
+ # Categories to check (default: all categories enabled)
517
+ # Set to specific categories to limit scope:
518
+ # categories: ['credential_exposure', 'priv_esc'] # Only check critical actions
519
+ # categories: ['data_access'] # Only check data access actions
520
+ # Set to empty list to disable: categories: []
521
+ "categories": [
522
+ "credential_exposure", # Critical: Credential/secret exposure (46 actions)
523
+ "data_access", # High: Sensitive data retrieval (109 actions)
524
+ "priv_esc", # Critical: Privilege escalation (27 actions)
525
+ "resource_exposure", # High: Resource policy modifications (321 actions)
526
+ ],
527
+ # Per-category severity overrides (optional)
528
+ # If not specified, uses the default severity above
529
+ "category_severities": {
530
+ "credential_exposure": "critical", # Override: credential exposure is critical
531
+ "priv_esc": "critical", # Override: privilege escalation is critical
532
+ "data_access": "high", # Override: data access is high
533
+ "resource_exposure": "high", # Override: resource exposure is high
534
+ },
535
+ # Category-specific ABAC suggestions and examples
536
+ # These provide tailored guidance for each security risk category
537
+ # See: iam_validator/core/config/category_suggestions.py
538
+ # Can be overridden to customize suggestions per category
539
+ "category_suggestions": get_category_suggestions(),
540
+ # Custom message templates (support {action} and {actions} placeholders)
541
+ "message_single": "Sensitive action '{action}' should have conditions to limit when it can be used",
542
+ "message_multiple": "Sensitive actions '{actions}' should have conditions to limit when they can be used",
543
+ # Ignore patterns to prevent duplicate alerts
544
+ # Useful when you have specific condition enforcement for certain actions
545
+ # Example: Ignore iam:PassRole since it's checked by action_condition_enforcement
546
+ "ignore_patterns": [
547
+ {"action": "^iam:PassRole$"},
548
+ ],
549
+ # Cross-statement privilege escalation patterns (policy-wide detection)
550
+ # These patterns detect dangerous action combinations across ANY statements in the policy
551
+ # Uses all_of logic: ALL actions must exist somewhere in the policy
552
+ "sensitive_actions": [
553
+ # User privilege escalation: Create user + attach admin policy
554
+ {
555
+ "all_of": ["iam:CreateUser", "iam:AttachUserPolicy"],
556
+ "severity": "critical",
557
+ "message": "Policy grants {actions} across statements - enables privilege escalation. {statements}",
558
+ "suggestion": (
559
+ "This combination allows an attacker to:\n"
560
+ "1. Create a new IAM user\n"
561
+ "2. Attach AdministratorAccess policy to that user\n"
562
+ "3. Escalate to full account access\n\n"
563
+ "Mitigation options:\n"
564
+ "• Remove both of these permissions\n"
565
+ "• Add strict IAM conditions (IP restrictions, tags, force a specific policy with `iam:PolicyARN` condition)\n"
566
+ ),
567
+ "example": (
568
+ "{\n"
569
+ ' "Condition": {\n'
570
+ ' "StringEquals": {\n'
571
+ ' "iam:PolicyARN": "arn:aws:iam::*:policy/ReadOnlyAccess"\n'
572
+ " },\n"
573
+ ' "IpAddress": {\n'
574
+ ' "aws:SourceIp": ["10.0.0.0/8"]\n'
575
+ " }\n"
576
+ " }\n"
577
+ "}\n"
578
+ ),
579
+ },
580
+ # Role privilege escalation: Create role + attach admin policy
581
+ {
582
+ "all_of": ["iam:CreateRole", "iam:AttachRolePolicy"],
583
+ "severity": "high",
584
+ "message": "Policy grants {actions} across statements - enables privilege escalation. {statements}",
585
+ "suggestion": (
586
+ "This combination allows creating privileged roles with admin policies.\n\n"
587
+ "Mitigation options:\n"
588
+ "• Remove both of these permissions\n"
589
+ "• Add strict IAM conditions with a Permissions Boundary and ABAC Tagging, force a specific policy with `iam:PolicyARN` condition\n"
590
+ ),
591
+ "example": (
592
+ "{\n"
593
+ ' "Condition": {\n'
594
+ ' "StringEquals": {\n'
595
+ ' "iam:PermissionsBoundary": "arn:aws:iam::*:policy/MaxPermissions"\n'
596
+ " }\n"
597
+ " }\n"
598
+ "}\n"
599
+ "OR\n"
600
+ "{\n"
601
+ ' "Condition": {\n'
602
+ ' "StringEquals": {\n'
603
+ ' "iam:PolicyARN": "arn:aws:iam::*:policy/MaxPermissions"\n'
604
+ " }\n"
605
+ " }\n"
606
+ "}\n"
607
+ ),
608
+ },
609
+ # Lambda backdoor: Create/update function + invoke
610
+ {
611
+ "all_of": ["lambda:CreateFunction", "lambda:InvokeFunction"],
612
+ "severity": "medium",
613
+ "message": "Policy grants {actions} across statements - enables code execution. {statements}",
614
+ "suggestion": (
615
+ "This combination allows an attacker to:\n"
616
+ "1. Create a Lambda function with malicious code\n"
617
+ "2. Execute the function to perform operations with the Lambda's role\n\n"
618
+ "Mitigation options:\n"
619
+ "• Restrict Lambda creation to specific function names/paths\n"
620
+ "• Require resource tags on functions and tag-based invocation controls\n"
621
+ "• Require MFA for Lambda function creation\n"
622
+ "• Use separate policies for creation vs invocation"
623
+ ),
624
+ "example": (
625
+ "{\n"
626
+ ' "Condition": {\n'
627
+ ' "StringEquals": {\n'
628
+ ' "aws:PrincipalTag/team": "${aws:ResourceTag/team}"\n'
629
+ " },\n"
630
+ ' "SourceIp": {\n'
631
+ ' "aws:SourceIp": ["10.0.0.0/8"]\n'
632
+ " }\n"
633
+ " }\n"
634
+ "}\n"
635
+ ),
636
+ },
637
+ # Lambda code modification backdoor
638
+ {
639
+ "all_of": ["lambda:UpdateFunctionCode", "lambda:InvokeFunction"],
640
+ "severity": "medium",
641
+ "message": "Policy grants {actions} across statements - enables code injection. {statements}",
642
+ "suggestion": (
643
+ "This combination allows modifying existing Lambda functions and executing them.\n\n"
644
+ "Mitigation options:\n"
645
+ "• Use resource-based policies to restrict which functions can be modified\n"
646
+ "• Require MFA for code updates\n"
647
+ "• Use separate policies for code updates vs invocation\n"
648
+ "• Implement code signing for Lambda functions"
649
+ ),
650
+ "example": (
651
+ "{\n"
652
+ ' "Condition": {\n'
653
+ ' "StringEquals": {\n'
654
+ ' "aws:ResourceAccount": "${aws:PrincipalAccount}"\n'
655
+ " }\n"
656
+ " }\n"
657
+ "}\n"
658
+ ),
659
+ },
660
+ # EC2 instance privilege escalation
661
+ {
662
+ "all_of": ["ec2:RunInstances", "iam:PassRole"],
663
+ "severity": "high",
664
+ "message": "Policy grants {actions} across statements - enables privilege escalation via instance profile. {statements}",
665
+ "suggestion": (
666
+ "This combination allows launching EC2 instances with privileged roles.\n\n"
667
+ "Mitigation options:\n"
668
+ "• Add iam:PassedToService condition requiring ec2.amazonaws.com\n"
669
+ "• Restrict instance creation to specific AMIs or instance types\n"
670
+ "• Limit PassRole to specific low-privilege roles\n"
671
+ "• Require tagging and ABAC controls"
672
+ ),
673
+ "example": (
674
+ "{\n"
675
+ ' "Condition": {\n'
676
+ ' "StringEquals": {\n'
677
+ ' "iam:PassedToService": "ec2.amazonaws.com"\n'
678
+ " },\n"
679
+ ' "ArnLike": {\n'
680
+ ' "iam:AssociatedResourceArn": "arn:aws:ec2:*:*:instance/*"\n'
681
+ " }\n"
682
+ " }\n"
683
+ "}\n"
684
+ ),
685
+ },
686
+ ],
687
+ },
688
+ # ========================================================================
689
+ # 18. ACTION CONDITION ENFORCEMENT
690
+ # ========================================================================
691
+ # Enforce specific IAM condition requirements for actions
692
+ # Examples: iam:PassRole must specify iam:PassedToService,
693
+ # S3 writes must require MFA, EC2 launches must use tags
694
+ #
695
+ # Default: 5 enabled requirements
696
+ # Available requirements:
697
+ # Default (enabled):
698
+ # - iam_pass_role: Requires iam:PassedToService
699
+ # - s3_org_boundary: Prevents S3 data exfiltration (reads + writes)
700
+ # - source_ip_restrictions: Restricts to corporate IPs
701
+ # - s3_secure_transport: Prevents insecure transport
702
+ # - prevent_public_ip: Prevents 0.0.0.0/0 IP ranges
703
+ #
704
+ # See: iam_validator/core/config/condition_requirements.py
705
+ "action_condition_enforcement": {
706
+ "enabled": True,
707
+ "severity": "high", # Default severity (can be overridden per-requirement)
708
+ "description": "Enforces conditions (MFA, IP, tags, etc.) for specific actions at both statement and policy level",
709
+ # CRITICAL: This key is used by sensitive_action check for filtering
710
+ # It must be named "requirements" (not "action_condition_requirements")
711
+ # to enable automatic deduplication of warnings
712
+ "requirements": __import__("copy").deepcopy(CONDITION_REQUIREMENTS),
713
+ # POLICY-LEVEL: Scan entire policy and enforce conditions across ALL matching statements
714
+ # Example: "If ANY statement grants iam:CreateUser, then ALL such statements must have MFA"
715
+ # Default: Empty list (opt-in feature)
716
+ # To enable, add requirements like:
717
+ # policy_level_requirements:
718
+ # - actions:
719
+ # any_of: ["iam:CreateUser", "iam:AttachUserPolicy"]
720
+ # scope: "policy"
721
+ # required_conditions:
722
+ # - condition_key: "aws:MultiFactorAuthPresent"
723
+ # expected_value: true
724
+ # severity: "critical"
725
+ "policy_level_requirements": [],
726
+ },
727
+ }
728
+
729
+
730
+ def get_default_config() -> dict:
731
+ """
732
+ Get a deep copy of the default configuration.
733
+
734
+ Returns:
735
+ A deep copy of the default configuration dictionary
736
+ """
737
+ import copy # pylint: disable=import-outside-toplevel
738
+
739
+ return copy.deepcopy(DEFAULT_CONFIG)