iam-policy-validator 1.4.0__py3-none-any.whl → 1.6.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.4.0.dist-info → iam_policy_validator-1.6.0.dist-info}/METADATA +106 -78
- iam_policy_validator-1.6.0.dist-info/RECORD +82 -0
- iam_validator/__version__.py +1 -1
- iam_validator/checks/__init__.py +20 -4
- iam_validator/checks/action_condition_enforcement.py +165 -8
- iam_validator/checks/action_resource_matching.py +424 -0
- iam_validator/checks/condition_key_validation.py +24 -2
- iam_validator/checks/condition_type_mismatch.py +259 -0
- iam_validator/checks/full_wildcard.py +67 -0
- iam_validator/checks/mfa_condition_check.py +112 -0
- iam_validator/checks/principal_validation.py +497 -3
- iam_validator/checks/sensitive_action.py +250 -0
- iam_validator/checks/service_wildcard.py +105 -0
- iam_validator/checks/set_operator_validation.py +157 -0
- iam_validator/checks/utils/sensitive_action_matcher.py +74 -32
- iam_validator/checks/wildcard_action.py +62 -0
- iam_validator/checks/wildcard_resource.py +131 -0
- iam_validator/commands/cache.py +1 -1
- iam_validator/commands/download_services.py +3 -8
- iam_validator/commands/validate.py +72 -13
- iam_validator/core/aws_fetcher.py +114 -64
- iam_validator/core/check_registry.py +167 -29
- iam_validator/core/condition_validators.py +626 -0
- iam_validator/core/config/__init__.py +81 -0
- iam_validator/core/config/aws_api.py +35 -0
- iam_validator/core/config/aws_global_conditions.py +160 -0
- iam_validator/core/config/category_suggestions.py +104 -0
- iam_validator/core/config/condition_requirements.py +155 -0
- iam_validator/core/{config_loader.py → config/config_loader.py} +32 -9
- iam_validator/core/config/defaults.py +523 -0
- iam_validator/core/config/principal_requirements.py +421 -0
- iam_validator/core/config/sensitive_actions.py +672 -0
- iam_validator/core/config/service_principals.py +95 -0
- iam_validator/core/config/wildcards.py +124 -0
- iam_validator/core/formatters/enhanced.py +11 -5
- iam_validator/core/formatters/sarif.py +78 -14
- iam_validator/core/models.py +14 -1
- iam_validator/core/policy_checks.py +4 -4
- iam_validator/core/pr_commenter.py +1 -1
- iam_validator/sdk/__init__.py +187 -0
- iam_validator/sdk/arn_matching.py +274 -0
- iam_validator/sdk/context.py +222 -0
- iam_validator/sdk/exceptions.py +48 -0
- iam_validator/sdk/helpers.py +177 -0
- iam_validator/sdk/policy_utils.py +425 -0
- iam_validator/sdk/shortcuts.py +283 -0
- iam_validator/utils/__init__.py +31 -0
- iam_validator/utils/cache.py +105 -0
- iam_validator/utils/regex.py +206 -0
- iam_policy_validator-1.4.0.dist-info/RECORD +0 -56
- iam_validator/checks/action_resource_constraint.py +0 -151
- iam_validator/checks/security_best_practices.py +0 -536
- iam_validator/core/aws_global_conditions.py +0 -137
- iam_validator/core/defaults.py +0 -393
- {iam_policy_validator-1.4.0.dist-info → iam_policy_validator-1.6.0.dist-info}/WHEEL +0 -0
- {iam_policy_validator-1.4.0.dist-info → iam_policy_validator-1.6.0.dist-info}/entry_points.txt +0 -0
- {iam_policy_validator-1.4.0.dist-info → iam_policy_validator-1.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
AWS Global Condition Keys Management.
|
|
3
|
-
|
|
4
|
-
Provides access to the list of valid AWS global condition keys
|
|
5
|
-
that can be used across all AWS services.
|
|
6
|
-
|
|
7
|
-
Reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html
|
|
8
|
-
Last updated: 2025-01-17
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
import re
|
|
12
|
-
from typing import Any
|
|
13
|
-
|
|
14
|
-
# AWS Global Condition Keys
|
|
15
|
-
# These condition keys are available for use in IAM policies across all AWS services
|
|
16
|
-
AWS_GLOBAL_CONDITION_KEYS = {
|
|
17
|
-
# Properties of the Principal
|
|
18
|
-
"aws:PrincipalArn", # ARN of the principal making the request
|
|
19
|
-
"aws:PrincipalAccount", # Account to which the requesting principal belongs
|
|
20
|
-
"aws:PrincipalOrgPaths", # AWS Organizations path for the principal
|
|
21
|
-
"aws:PrincipalOrgID", # Organization identifier of the principal
|
|
22
|
-
"aws:PrincipalIsAWSService", # Checks if call is made directly by AWS service principal
|
|
23
|
-
"aws:PrincipalServiceName", # Service principal name making the request
|
|
24
|
-
"aws:PrincipalServiceNamesList", # List of all service principal names
|
|
25
|
-
"aws:PrincipalType", # Type of principal making the request
|
|
26
|
-
"aws:userid", # Principal identifier of the requester
|
|
27
|
-
"aws:username", # User name of the requester
|
|
28
|
-
# Properties of a Role Session
|
|
29
|
-
"aws:AssumedRoot", # Checks if request used AssumeRoot for privileged access
|
|
30
|
-
"aws:FederatedProvider", # Principal's issuing identity provider
|
|
31
|
-
"aws:TokenIssueTime", # When temporary security credentials were issued
|
|
32
|
-
"aws:MultiFactorAuthAge", # Seconds since MFA authorization
|
|
33
|
-
"aws:MultiFactorAuthPresent", # Whether MFA was used for temporary credentials
|
|
34
|
-
"aws:ChatbotSourceArn", # Source chat configuration ARN
|
|
35
|
-
"aws:Ec2InstanceSourceVpc", # VPC where EC2 IAM role credentials were delivered
|
|
36
|
-
"aws:Ec2InstanceSourcePrivateIPv4", # Private IPv4 of EC2 instance
|
|
37
|
-
"aws:SourceIdentity", # Source identity set when assuming a role
|
|
38
|
-
"ec2:RoleDelivery", # Instance metadata service version
|
|
39
|
-
# Network Properties
|
|
40
|
-
"aws:SourceIp", # Requester's IP address (IPv4/IPv6)
|
|
41
|
-
"aws:SourceVpc", # VPC through which request travels
|
|
42
|
-
"aws:SourceVpce", # VPC endpoint identifier
|
|
43
|
-
"aws:VpceAccount", # AWS account owning the VPC endpoint
|
|
44
|
-
"aws:VpceOrgID", # Organization ID of VPC endpoint owner
|
|
45
|
-
"aws:VpceOrgPaths", # AWS Organizations path of VPC endpoint
|
|
46
|
-
"aws:VpcSourceIp", # IP address from VPC endpoint request
|
|
47
|
-
# Resource Properties
|
|
48
|
-
"aws:ResourceAccount", # Resource owner's AWS account ID
|
|
49
|
-
"aws:ResourceOrgID", # Organization ID of resource owner
|
|
50
|
-
"aws:ResourceOrgPaths", # AWS Organizations path of resource
|
|
51
|
-
# Request Properties
|
|
52
|
-
"aws:CurrentTime", # Current date and time
|
|
53
|
-
"aws:EpochTime", # Request timestamp in epoch format
|
|
54
|
-
"aws:referer", # HTTP referer header value (note: lowercase 'r')
|
|
55
|
-
"aws:Referer", # HTTP referer header value (alternate capitalization)
|
|
56
|
-
"aws:RequestedRegion", # AWS Region for the request
|
|
57
|
-
"aws:TagKeys", # Tag keys present in request
|
|
58
|
-
"aws:SecureTransport", # Whether HTTPS was used
|
|
59
|
-
"aws:SourceAccount", # Account making the request
|
|
60
|
-
"aws:SourceArn", # ARN of request source
|
|
61
|
-
"aws:SourceOrgID", # Organization ID of request source
|
|
62
|
-
"aws:SourceOrgPaths", # Organization paths of request source
|
|
63
|
-
"aws:UserAgent", # HTTP user agent string
|
|
64
|
-
# Cross-Service Keys
|
|
65
|
-
"aws:CalledVia", # Services called in request chain
|
|
66
|
-
"aws:CalledViaFirst", # First service in call chain
|
|
67
|
-
"aws:CalledViaLast", # Last service in call chain
|
|
68
|
-
"aws:ViaAWSService", # Whether AWS service made the request
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
# Patterns that should be recognized (wildcards and tag-based keys)
|
|
72
|
-
# These allow things like aws:RequestTag/Department or aws:PrincipalTag/Environment
|
|
73
|
-
AWS_CONDITION_KEY_PATTERNS = [
|
|
74
|
-
{
|
|
75
|
-
"pattern": r"^aws:RequestTag/[a-zA-Z0-9+\-=._:/@]+$",
|
|
76
|
-
"description": "Tag keys in the request (for tag-based access control)",
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"pattern": r"^aws:ResourceTag/[a-zA-Z0-9+\-=._:/@]+$",
|
|
80
|
-
"description": "Tags on the resource being accessed",
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"pattern": r"^aws:PrincipalTag/[a-zA-Z0-9+\-=._:/@]+$",
|
|
84
|
-
"description": "Tags attached to the principal making the request",
|
|
85
|
-
},
|
|
86
|
-
]
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
class AWSGlobalConditions:
|
|
90
|
-
"""Manages AWS global condition keys."""
|
|
91
|
-
|
|
92
|
-
def __init__(self):
|
|
93
|
-
"""Initialize with global condition keys."""
|
|
94
|
-
self._global_keys: set[str] = AWS_GLOBAL_CONDITION_KEYS.copy()
|
|
95
|
-
self._patterns: list[dict[str, Any]] = AWS_CONDITION_KEY_PATTERNS.copy()
|
|
96
|
-
|
|
97
|
-
def is_valid_global_key(self, condition_key: str) -> bool:
|
|
98
|
-
"""
|
|
99
|
-
Check if a condition key is a valid AWS global condition key.
|
|
100
|
-
|
|
101
|
-
Args:
|
|
102
|
-
condition_key: The condition key to validate (e.g., "aws:SourceIp")
|
|
103
|
-
|
|
104
|
-
Returns:
|
|
105
|
-
True if valid global condition key, False otherwise
|
|
106
|
-
"""
|
|
107
|
-
# Check exact matches first
|
|
108
|
-
if condition_key in self._global_keys:
|
|
109
|
-
return True
|
|
110
|
-
|
|
111
|
-
# Check patterns (for tags and wildcards)
|
|
112
|
-
for pattern_config in self._patterns:
|
|
113
|
-
pattern = pattern_config["pattern"]
|
|
114
|
-
if re.match(pattern, condition_key):
|
|
115
|
-
return True
|
|
116
|
-
|
|
117
|
-
return False
|
|
118
|
-
|
|
119
|
-
def get_all_keys(self) -> set[str]:
|
|
120
|
-
"""Get all explicit global condition keys."""
|
|
121
|
-
return self._global_keys.copy()
|
|
122
|
-
|
|
123
|
-
def get_patterns(self) -> list[dict[str, Any]]:
|
|
124
|
-
"""Get all condition key patterns."""
|
|
125
|
-
return self._patterns.copy()
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# Singleton instance
|
|
129
|
-
_global_conditions_instance = None
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def get_global_conditions() -> AWSGlobalConditions:
|
|
133
|
-
"""Get singleton instance of AWSGlobalConditions."""
|
|
134
|
-
global _global_conditions_instance
|
|
135
|
-
if _global_conditions_instance is None:
|
|
136
|
-
_global_conditions_instance = AWSGlobalConditions()
|
|
137
|
-
return _global_conditions_instance
|
iam_validator/core/defaults.py
DELETED
|
@@ -1,393 +0,0 @@
|
|
|
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 is synced with the default-config.yaml file.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
# ============================================================================
|
|
12
|
-
# SEVERITY LEVELS
|
|
13
|
-
# ============================================================================
|
|
14
|
-
# The validator uses two types of severity levels:
|
|
15
|
-
#
|
|
16
|
-
# 1. IAM VALIDITY SEVERITIES (for AWS IAM policy correctness):
|
|
17
|
-
# - error: Policy violates AWS IAM rules (invalid actions, ARNs, etc.)
|
|
18
|
-
# - warning: Policy may have IAM-related issues but is technically valid
|
|
19
|
-
# - info: Informational messages about the policy structure
|
|
20
|
-
#
|
|
21
|
-
# 2. SECURITY SEVERITIES (for security best practices):
|
|
22
|
-
# - critical: Critical security risk (e.g., wildcard action + resource)
|
|
23
|
-
# - high: High security risk (e.g., missing required conditions)
|
|
24
|
-
# - medium: Medium security risk (e.g., overly permissive wildcards)
|
|
25
|
-
# - low: Low security risk (e.g., minor best practice violations)
|
|
26
|
-
#
|
|
27
|
-
# Use 'error' for policy validity issues, and 'critical/high/medium/low' for
|
|
28
|
-
# security best practices. This distinction helps separate "broken policies"
|
|
29
|
-
# from "insecure but valid policies".
|
|
30
|
-
# ============================================================================
|
|
31
|
-
|
|
32
|
-
# Default configuration dictionary
|
|
33
|
-
DEFAULT_CONFIG = {
|
|
34
|
-
"settings": {
|
|
35
|
-
"fail_fast": False,
|
|
36
|
-
"max_concurrent": 10,
|
|
37
|
-
"enable_builtin_checks": True,
|
|
38
|
-
"parallel_execution": True,
|
|
39
|
-
"aws_services_dir": None,
|
|
40
|
-
"cache_enabled": True,
|
|
41
|
-
"cache_ttl_hours": 168,
|
|
42
|
-
"fail_on_severity": ["error", "critical", "high"],
|
|
43
|
-
},
|
|
44
|
-
"sid_uniqueness_check": {
|
|
45
|
-
"enabled": True,
|
|
46
|
-
"severity": "error",
|
|
47
|
-
"description": "Validates that Statement IDs (Sids) are unique and follow AWS naming requirements",
|
|
48
|
-
},
|
|
49
|
-
"policy_size_check": {
|
|
50
|
-
"enabled": True,
|
|
51
|
-
"severity": "error",
|
|
52
|
-
"description": "Validates that IAM policies don't exceed AWS size limits",
|
|
53
|
-
"policy_type": "managed",
|
|
54
|
-
},
|
|
55
|
-
"action_validation_check": {
|
|
56
|
-
"enabled": True,
|
|
57
|
-
"severity": "error",
|
|
58
|
-
"description": "Validates that actions exist in AWS services",
|
|
59
|
-
},
|
|
60
|
-
"condition_key_validation_check": {
|
|
61
|
-
"enabled": True,
|
|
62
|
-
"severity": "error",
|
|
63
|
-
"description": "Validates condition keys against AWS service definitions for specified actions",
|
|
64
|
-
"validate_aws_global_keys": True,
|
|
65
|
-
},
|
|
66
|
-
"resource_validation_check": {
|
|
67
|
-
"enabled": True,
|
|
68
|
-
"severity": "error",
|
|
69
|
-
"description": "Validates ARN format for resources",
|
|
70
|
-
"arn_pattern": "^arn:(aws|aws-cn|aws-us-gov|aws-eusc|aws-iso|aws-iso-b|aws-iso-e|aws-iso-f):[a-z0-9\\-]+:[a-z0-9\\-*]*:[0-9*]*:.+$",
|
|
71
|
-
},
|
|
72
|
-
"principal_validation_check": {
|
|
73
|
-
"enabled": True,
|
|
74
|
-
"severity": "high",
|
|
75
|
-
"description": "Validates Principal elements in resource policies for security best practices",
|
|
76
|
-
"blocked_principals": ["*"],
|
|
77
|
-
"allowed_principals": [],
|
|
78
|
-
"require_conditions_for": {
|
|
79
|
-
"*": ["aws:SourceArn", "aws:SourceAccount"],
|
|
80
|
-
},
|
|
81
|
-
"allowed_service_principals": [
|
|
82
|
-
"cloudfront.amazonaws.com",
|
|
83
|
-
"s3.amazonaws.com",
|
|
84
|
-
"sns.amazonaws.com",
|
|
85
|
-
"lambda.amazonaws.com",
|
|
86
|
-
"logs.amazonaws.com",
|
|
87
|
-
"events.amazonaws.com",
|
|
88
|
-
],
|
|
89
|
-
},
|
|
90
|
-
"action_resource_constraint_check": {
|
|
91
|
-
"enabled": True,
|
|
92
|
-
"severity": "error",
|
|
93
|
-
"description": "Validates that actions without required resource types use Resource: '*'",
|
|
94
|
-
},
|
|
95
|
-
"security_best_practices_check": {
|
|
96
|
-
"enabled": True,
|
|
97
|
-
"description": "Checks for common security anti-patterns",
|
|
98
|
-
"allowed_wildcards": [
|
|
99
|
-
"autoscaling:Describe*",
|
|
100
|
-
"cloudwatch:Describe*",
|
|
101
|
-
"cloudwatch:Get*",
|
|
102
|
-
"cloudwatch:List*",
|
|
103
|
-
"dynamodb:Describe*",
|
|
104
|
-
"ec2:Describe*",
|
|
105
|
-
"elasticloadbalancing:Describe*",
|
|
106
|
-
"iam:Get*",
|
|
107
|
-
"iam:List*",
|
|
108
|
-
"kms:Describe*",
|
|
109
|
-
"lambda:Get*",
|
|
110
|
-
"lambda:List*",
|
|
111
|
-
"logs:Describe*",
|
|
112
|
-
"logs:Filter*",
|
|
113
|
-
"logs:Get*",
|
|
114
|
-
"rds:Describe*",
|
|
115
|
-
"route53:Get*",
|
|
116
|
-
"route53:List*",
|
|
117
|
-
"s3:Describe*",
|
|
118
|
-
"s3:GetBucket*",
|
|
119
|
-
"s3:GetM*",
|
|
120
|
-
"s3:List*",
|
|
121
|
-
"sqs:Get*",
|
|
122
|
-
"sqs:List*",
|
|
123
|
-
"apigateway:GET",
|
|
124
|
-
],
|
|
125
|
-
"wildcard_action_check": {
|
|
126
|
-
"enabled": True,
|
|
127
|
-
"severity": "medium",
|
|
128
|
-
"message": "Statement allows all actions (*)",
|
|
129
|
-
"suggestion": "Replace wildcard with specific actions needed for your use case",
|
|
130
|
-
"example": """Replace:
|
|
131
|
-
"Action": ["*"]
|
|
132
|
-
|
|
133
|
-
With specific actions:
|
|
134
|
-
"Action": [
|
|
135
|
-
"s3:GetObject",
|
|
136
|
-
"s3:PutObject",
|
|
137
|
-
"s3:ListBucket"
|
|
138
|
-
]
|
|
139
|
-
""",
|
|
140
|
-
},
|
|
141
|
-
"wildcard_resource_check": {
|
|
142
|
-
"enabled": True,
|
|
143
|
-
"severity": "medium",
|
|
144
|
-
"message": "Statement applies to all resources (*)",
|
|
145
|
-
"suggestion": "Replace wildcard with specific resource ARNs",
|
|
146
|
-
"example": """Replace:
|
|
147
|
-
"Resource": "*"
|
|
148
|
-
|
|
149
|
-
With specific ARNs:
|
|
150
|
-
"Resource": [
|
|
151
|
-
"arn:aws:service:region:account-id:resource-type/resource-id",
|
|
152
|
-
"arn:aws:service:region:account-id:resource-type/*"
|
|
153
|
-
]
|
|
154
|
-
""",
|
|
155
|
-
},
|
|
156
|
-
"full_wildcard_check": {
|
|
157
|
-
"enabled": True,
|
|
158
|
-
"severity": "critical",
|
|
159
|
-
"message": "Statement allows all actions on all resources - CRITICAL SECURITY RISK",
|
|
160
|
-
"suggestion": "This grants full administrative access. Replace both wildcards with specific actions and resources to follow least-privilege principle",
|
|
161
|
-
"example": """Replace:
|
|
162
|
-
"Action": "*",
|
|
163
|
-
"Resource": "*"
|
|
164
|
-
|
|
165
|
-
With specific values:
|
|
166
|
-
"Action": [
|
|
167
|
-
"s3:GetObject",
|
|
168
|
-
"s3:PutObject"
|
|
169
|
-
],
|
|
170
|
-
"Resource": [
|
|
171
|
-
"arn:aws:s3:::my-bucket/*"
|
|
172
|
-
]
|
|
173
|
-
""",
|
|
174
|
-
},
|
|
175
|
-
"service_wildcard_check": {
|
|
176
|
-
"enabled": True,
|
|
177
|
-
"severity": "high",
|
|
178
|
-
"allowed_services": ["logs", "cloudwatch", "xray"],
|
|
179
|
-
},
|
|
180
|
-
"sensitive_action_check": {
|
|
181
|
-
"enabled": True,
|
|
182
|
-
"severity": "medium",
|
|
183
|
-
"message_single": "Sensitive action '{action}' should have conditions to limit when it can be used",
|
|
184
|
-
"message_multiple": "Sensitive actions '{actions}' should have conditions to limit when they can be used",
|
|
185
|
-
"suggestion": "Add IAM conditions to limit when this action can be used. Consider: ABAC (ResourceTag OR RequestTag must match PrincipalTag), IP restrictions (aws:SourceIp), MFA requirements (aws:MultiFactorAuthPresent), or time-based restrictions (aws:CurrentTime)",
|
|
186
|
-
"example": """"Condition": {
|
|
187
|
-
"StringEquals": {
|
|
188
|
-
"aws:ResourceTag/owner": "${aws:PrincipalTag/owner}"
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
""",
|
|
192
|
-
"sensitive_actions": [
|
|
193
|
-
"iam:AddClientIDToOpenIDConnectProvider",
|
|
194
|
-
"iam:AttachRolePolicy",
|
|
195
|
-
"iam:AttachUserPolicy",
|
|
196
|
-
"iam:CreateAccessKey",
|
|
197
|
-
"iam:CreateOpenIDConnectProvider",
|
|
198
|
-
"iam:CreatePolicyVersion",
|
|
199
|
-
"iam:CreateRole",
|
|
200
|
-
"iam:CreateSAMLProvider",
|
|
201
|
-
"iam:CreateUser",
|
|
202
|
-
"iam:DeleteAccessKey",
|
|
203
|
-
"iam:DeleteLoginProfile",
|
|
204
|
-
"iam:DeleteOpenIDConnectProvider",
|
|
205
|
-
"iam:DeleteRole",
|
|
206
|
-
"iam:DeleteRolePolicy",
|
|
207
|
-
"iam:DeleteSAMLProvider",
|
|
208
|
-
"iam:DeleteUser",
|
|
209
|
-
"iam:DeleteUserPolicy",
|
|
210
|
-
"iam:DetachRolePolicy",
|
|
211
|
-
"iam:DetachUserPolicy",
|
|
212
|
-
"iam:PutRolePolicy",
|
|
213
|
-
"iam:PutUserPolicy",
|
|
214
|
-
"iam:SetDefaultPolicyVersion",
|
|
215
|
-
"iam:UpdateAccessKey",
|
|
216
|
-
"iam:UpdateAssumeRolePolicy",
|
|
217
|
-
"kms:DisableKey",
|
|
218
|
-
"kms:PutKeyPolicy",
|
|
219
|
-
"kms:ScheduleKeyDeletion",
|
|
220
|
-
"secretsmanager:DeleteSecret",
|
|
221
|
-
"secretsmanager:GetSecretValue",
|
|
222
|
-
"secretsmanager:PutSecretValue",
|
|
223
|
-
"ssm:DeleteParameter",
|
|
224
|
-
"ssm:PutParameter",
|
|
225
|
-
"ec2:DeleteSnapshot",
|
|
226
|
-
"ec2:DeleteVolume",
|
|
227
|
-
"ec2:DeleteVpc",
|
|
228
|
-
"ec2:ModifyInstanceAttribute",
|
|
229
|
-
"ec2:TerminateInstances",
|
|
230
|
-
"ecr:DeleteRepository",
|
|
231
|
-
"ecs:DeleteCluster",
|
|
232
|
-
"ecs:DeleteService",
|
|
233
|
-
"eks:DeleteCluster",
|
|
234
|
-
"lambda:DeleteFunction",
|
|
235
|
-
"lambda:DeleteFunctionConcurrency",
|
|
236
|
-
"lambda:PutFunctionConcurrency",
|
|
237
|
-
"dynamodb:DeleteTable",
|
|
238
|
-
"efs:DeleteFileSystem",
|
|
239
|
-
"elasticache:DeleteCacheCluster",
|
|
240
|
-
"fsx:DeleteFileSystem",
|
|
241
|
-
"rds:DeleteDBCluster",
|
|
242
|
-
"rds:DeleteDBInstance",
|
|
243
|
-
"redshift:DeleteCluster",
|
|
244
|
-
"backup:DeleteBackupVault",
|
|
245
|
-
"glacier:DeleteArchive",
|
|
246
|
-
"s3:DeleteBucket",
|
|
247
|
-
"s3:DeleteBucketPolicy",
|
|
248
|
-
"s3:DeleteObject",
|
|
249
|
-
"s3:PutBucketPolicy",
|
|
250
|
-
"s3:PutLifecycleConfiguration",
|
|
251
|
-
"ec2:AuthorizeSecurityGroupIngress",
|
|
252
|
-
"ec2:DeleteSecurityGroup",
|
|
253
|
-
"ec2:DisassociateRouteTable",
|
|
254
|
-
"ec2:RevokeSecurityGroupEgress",
|
|
255
|
-
"cloudtrail:DeleteTrail",
|
|
256
|
-
"cloudtrail:StopLogging",
|
|
257
|
-
"cloudwatch:DeleteLogGroup",
|
|
258
|
-
"config:DeleteConfigurationRecorder",
|
|
259
|
-
"guardduty:DeleteDetector",
|
|
260
|
-
"account:CloseAccount",
|
|
261
|
-
"account:CreateAccount",
|
|
262
|
-
"organizations:LeaveOrganization",
|
|
263
|
-
"organizations:RemoveAccountFromOrganization",
|
|
264
|
-
],
|
|
265
|
-
},
|
|
266
|
-
},
|
|
267
|
-
"action_condition_enforcement_check": {
|
|
268
|
-
"enabled": True,
|
|
269
|
-
"severity": "high",
|
|
270
|
-
"description": "Enforce specific IAM condition requirements (unified: MFA, IP, tags, etc.)",
|
|
271
|
-
"action_condition_requirements": [
|
|
272
|
-
{
|
|
273
|
-
"actions": ["iam:PassRole"],
|
|
274
|
-
"severity": "high",
|
|
275
|
-
"required_conditions": [
|
|
276
|
-
{
|
|
277
|
-
"condition_key": "iam:PassedToService",
|
|
278
|
-
"description": "Specify which AWS services are allowed to use the passed role to prevent privilege escalation",
|
|
279
|
-
"example": """"Condition": {
|
|
280
|
-
"StringEquals": {
|
|
281
|
-
"iam:PassedToService": [
|
|
282
|
-
"lambda.amazonaws.com",
|
|
283
|
-
"ecs-tasks.amazonaws.com",
|
|
284
|
-
"ec2.amazonaws.com",
|
|
285
|
-
"glue.amazonaws.com",
|
|
286
|
-
"lambda.amazonaws.com"
|
|
287
|
-
]
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
""",
|
|
291
|
-
},
|
|
292
|
-
],
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
"actions": [
|
|
296
|
-
"iam:CreateRole",
|
|
297
|
-
"iam:PutRolePolicy*",
|
|
298
|
-
"iam:PutUserPolicy",
|
|
299
|
-
"iam:PutRolePolicy",
|
|
300
|
-
"iam:Attach*Policy*",
|
|
301
|
-
"iam:AttachUserPolicy",
|
|
302
|
-
"iam:AttachRolePolicy",
|
|
303
|
-
],
|
|
304
|
-
"severity": "high",
|
|
305
|
-
"required_conditions": [
|
|
306
|
-
{
|
|
307
|
-
"condition_key": "iam:PermissionsBoundary",
|
|
308
|
-
"description": "Require permissions boundary for sensitive IAM operations to prevent privilege escalation",
|
|
309
|
-
"expected_value": "arn:aws:iam::*:policy/DeveloperBoundary",
|
|
310
|
-
"example": """# See: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html
|
|
311
|
-
"Condition": {
|
|
312
|
-
"StringEquals": {
|
|
313
|
-
"iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/XCompanyBoundaries"
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
""",
|
|
317
|
-
},
|
|
318
|
-
],
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
"actions": ["s3:PutObject"],
|
|
322
|
-
"severity": "medium",
|
|
323
|
-
"required_conditions": [
|
|
324
|
-
{
|
|
325
|
-
"condition_key": "aws:ResourceOrgId",
|
|
326
|
-
"description": "Require aws:ResourceOrgId condition for S3 write actions to enforce organization-level access control",
|
|
327
|
-
"example": """"Condition": {
|
|
328
|
-
"StringEquals": {
|
|
329
|
-
"aws:ResourceOrgId": "${aws:PrincipalOrgID}"
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
""",
|
|
333
|
-
},
|
|
334
|
-
],
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
"action_patterns": [
|
|
338
|
-
"^ssm:StartSession$",
|
|
339
|
-
"^ssm:Run.*$",
|
|
340
|
-
"^s3:GetObject$",
|
|
341
|
-
"^rds-db:Connect$",
|
|
342
|
-
],
|
|
343
|
-
"severity": "low",
|
|
344
|
-
"required_conditions": [
|
|
345
|
-
{
|
|
346
|
-
"condition_key": "aws:SourceIp",
|
|
347
|
-
"description": "Restrict access to corporate IP ranges",
|
|
348
|
-
"example": """"Condition": {
|
|
349
|
-
"IpAddress": {
|
|
350
|
-
"aws:SourceIp": [
|
|
351
|
-
"10.0.0.0/8",
|
|
352
|
-
"172.16.0.0/12"
|
|
353
|
-
]
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
""",
|
|
357
|
-
},
|
|
358
|
-
],
|
|
359
|
-
},
|
|
360
|
-
{
|
|
361
|
-
"actions": ["s3:GetObject", "s3:PutObject"],
|
|
362
|
-
"required_conditions": {
|
|
363
|
-
"none_of": [
|
|
364
|
-
{
|
|
365
|
-
"condition_key": "aws:SecureTransport",
|
|
366
|
-
"expected_value": False,
|
|
367
|
-
"description": "Never allow insecure transport to be explicitly permitted",
|
|
368
|
-
"example": """# Set this condition to true to enforce secure transport or remove it entirely
|
|
369
|
-
"Condition": {
|
|
370
|
-
"Bool": {
|
|
371
|
-
"aws:SecureTransport": "true"
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
""",
|
|
375
|
-
},
|
|
376
|
-
],
|
|
377
|
-
},
|
|
378
|
-
},
|
|
379
|
-
],
|
|
380
|
-
},
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
def get_default_config() -> dict:
|
|
385
|
-
"""
|
|
386
|
-
Get a deep copy of the default configuration.
|
|
387
|
-
|
|
388
|
-
Returns:
|
|
389
|
-
A deep copy of the default configuration dictionary
|
|
390
|
-
"""
|
|
391
|
-
import copy
|
|
392
|
-
|
|
393
|
-
return copy.deepcopy(DEFAULT_CONFIG)
|
|
File without changes
|
{iam_policy_validator-1.4.0.dist-info → iam_policy_validator-1.6.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{iam_policy_validator-1.4.0.dist-info → iam_policy_validator-1.6.0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|