iam-policy-validator 1.5.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.5.0.dist-info → iam_policy_validator-1.6.0.dist-info}/METADATA +89 -60
- {iam_policy_validator-1.5.0.dist-info → iam_policy_validator-1.6.0.dist-info}/RECORD +40 -25
- iam_validator/__version__.py +1 -1
- iam_validator/checks/__init__.py +9 -3
- iam_validator/checks/action_condition_enforcement.py +164 -2
- iam_validator/checks/action_resource_matching.py +424 -0
- iam_validator/checks/condition_key_validation.py +3 -1
- iam_validator/checks/condition_type_mismatch.py +259 -0
- iam_validator/checks/mfa_condition_check.py +112 -0
- iam_validator/checks/sensitive_action.py +78 -6
- iam_validator/checks/set_operator_validation.py +157 -0
- iam_validator/checks/utils/sensitive_action_matcher.py +35 -1
- iam_validator/commands/cache.py +1 -1
- iam_validator/commands/validate.py +44 -11
- iam_validator/core/aws_fetcher.py +89 -52
- iam_validator/core/check_registry.py +165 -21
- iam_validator/core/condition_validators.py +626 -0
- iam_validator/core/config/__init__.py +13 -15
- 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 +5 -385
- iam_validator/core/{config_loader.py → config/config_loader.py} +3 -0
- iam_validator/core/config/defaults.py +187 -54
- iam_validator/core/config/sensitive_actions.py +620 -81
- 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_validator/checks/action_resource_constraint.py +0 -151
- iam_validator/core/aws_global_conditions.py +0 -137
- {iam_policy_validator-1.5.0.dist-info → iam_policy_validator-1.6.0.dist-info}/WHEEL +0 -0
- {iam_policy_validator-1.5.0.dist-info → iam_policy_validator-1.6.0.dist-info}/entry_points.txt +0 -0
- {iam_policy_validator-1.5.0.dist-info → iam_policy_validator-1.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,13 +5,6 @@ This module defines default condition requirements for sensitive actions,
|
|
|
5
5
|
making it easy to manage complex condition enforcement rules without
|
|
6
6
|
deeply nested YAML/dict structures.
|
|
7
7
|
|
|
8
|
-
Using Python provides:
|
|
9
|
-
- Better readability and maintainability
|
|
10
|
-
- Type hints and IDE support
|
|
11
|
-
- Easy to add/modify requirements
|
|
12
|
-
- No parsing overhead
|
|
13
|
-
- Compiled to .pyc
|
|
14
|
-
|
|
15
8
|
Configuration Fields Reference:
|
|
16
9
|
- description: Technical description of what the requirement does (shown in output)
|
|
17
10
|
- example: Concrete code example showing proper condition usage
|
|
@@ -57,39 +50,6 @@ IAM_PASS_ROLE_REQUIREMENT: Final[dict[str, Any]] = {
|
|
|
57
50
|
],
|
|
58
51
|
}
|
|
59
52
|
|
|
60
|
-
# IAM Write Operations - Require permissions boundary
|
|
61
|
-
IAM_WRITE_PERMISSIONS_BOUNDARY: Final[dict[str, Any]] = {
|
|
62
|
-
"actions": [
|
|
63
|
-
"iam:CreateRole",
|
|
64
|
-
"iam:PutRolePolicy*",
|
|
65
|
-
"iam:PutUserPolicy",
|
|
66
|
-
"iam:PutRolePolicy",
|
|
67
|
-
"iam:Attach*Policy*",
|
|
68
|
-
"iam:AttachUserPolicy",
|
|
69
|
-
"iam:AttachRolePolicy",
|
|
70
|
-
],
|
|
71
|
-
"severity": "high",
|
|
72
|
-
"required_conditions": [
|
|
73
|
-
{
|
|
74
|
-
"condition_key": "iam:PermissionsBoundary",
|
|
75
|
-
"description": (
|
|
76
|
-
"Require permissions boundary for sensitive IAM operations to prevent privilege escalation"
|
|
77
|
-
),
|
|
78
|
-
"expected_value": "arn:aws:iam::*:policy/DeveloperBoundary",
|
|
79
|
-
"example": (
|
|
80
|
-
"# See: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html\n"
|
|
81
|
-
"{\n"
|
|
82
|
-
' "Condition": {\n'
|
|
83
|
-
' "StringEquals": {\n'
|
|
84
|
-
' "iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/XCompanyBoundaries"\n'
|
|
85
|
-
" }\n"
|
|
86
|
-
" }\n"
|
|
87
|
-
"}"
|
|
88
|
-
),
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
}
|
|
92
|
-
|
|
93
53
|
# S3 Write Operations - Require organization ID
|
|
94
54
|
S3_WRITE_ORG_ID: Final[dict[str, Any]] = {
|
|
95
55
|
"actions": ["s3:PutObject"],
|
|
@@ -98,7 +58,7 @@ S3_WRITE_ORG_ID: Final[dict[str, Any]] = {
|
|
|
98
58
|
{
|
|
99
59
|
"condition_key": "aws:ResourceOrgId",
|
|
100
60
|
"description": (
|
|
101
|
-
"Require aws:
|
|
61
|
+
"Require aws:ResourceAccount, aws:ResourceOrgID or aws:ResourceOrgPaths condition(s) for S3 write actions to enforce organization-level access control"
|
|
102
62
|
),
|
|
103
63
|
"example": (
|
|
104
64
|
"{\n"
|
|
@@ -145,6 +105,7 @@ SOURCE_IP_RESTRICTIONS: Final[dict[str, Any]] = {
|
|
|
145
105
|
# S3 Secure Transport - Never allow insecure transport
|
|
146
106
|
S3_SECURE_TRANSPORT: Final[dict[str, Any]] = {
|
|
147
107
|
"actions": ["s3:GetObject", "s3:PutObject"],
|
|
108
|
+
"severity": "critical",
|
|
148
109
|
"required_conditions": {
|
|
149
110
|
"none_of": [
|
|
150
111
|
{
|
|
@@ -166,171 +127,6 @@ S3_SECURE_TRANSPORT: Final[dict[str, Any]] = {
|
|
|
166
127
|
},
|
|
167
128
|
}
|
|
168
129
|
|
|
169
|
-
# ============================================================================
|
|
170
|
-
# Optional Requirements (Commented Examples for Users)
|
|
171
|
-
# ============================================================================
|
|
172
|
-
# These are disabled by default but can be enabled by users
|
|
173
|
-
|
|
174
|
-
# S3 Destructive Operations - Require MFA
|
|
175
|
-
S3_DESTRUCTIVE_MFA: Final[dict[str, Any]] = {
|
|
176
|
-
"actions": [
|
|
177
|
-
"s3:DeleteBucket",
|
|
178
|
-
"s3:DeleteBucketPolicy",
|
|
179
|
-
"s3:PutBucketPolicy",
|
|
180
|
-
],
|
|
181
|
-
"severity": "high",
|
|
182
|
-
"required_conditions": [
|
|
183
|
-
{
|
|
184
|
-
"condition_key": "aws:MultiFactorAuthPresent",
|
|
185
|
-
"description": "Require MFA for S3 destructive operations",
|
|
186
|
-
"expected_value": "true",
|
|
187
|
-
"example": (
|
|
188
|
-
"{\n"
|
|
189
|
-
' "Condition": {\n'
|
|
190
|
-
' "Bool": {\n'
|
|
191
|
-
' "aws:MultiFactorAuthPresent": "true"\n'
|
|
192
|
-
" }\n"
|
|
193
|
-
" }\n"
|
|
194
|
-
"}"
|
|
195
|
-
),
|
|
196
|
-
},
|
|
197
|
-
],
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
# All S3 Operations - Require HTTPS
|
|
201
|
-
S3_REQUIRE_HTTPS: Final[dict[str, Any]] = {
|
|
202
|
-
"action_patterns": ["^s3:.*"],
|
|
203
|
-
"severity": "medium",
|
|
204
|
-
"required_conditions": [
|
|
205
|
-
{
|
|
206
|
-
"condition_key": "aws:SecureTransport",
|
|
207
|
-
"description": "Require HTTPS for all S3 operations",
|
|
208
|
-
"expected_value": True,
|
|
209
|
-
"example": (
|
|
210
|
-
"{\n"
|
|
211
|
-
' "Condition": {\n'
|
|
212
|
-
' "Bool": {\n'
|
|
213
|
-
' "aws:SecureTransport": "true"\n'
|
|
214
|
-
" }\n"
|
|
215
|
-
" }\n"
|
|
216
|
-
"}"
|
|
217
|
-
),
|
|
218
|
-
},
|
|
219
|
-
],
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
# EC2 Instances - Must be in specific VPCs
|
|
223
|
-
EC2_VPC_RESTRICTION: Final[dict[str, Any]] = {
|
|
224
|
-
"actions": ["ec2:RunInstances"],
|
|
225
|
-
"severity": "high",
|
|
226
|
-
"required_conditions": [
|
|
227
|
-
{
|
|
228
|
-
"condition_key": "ec2:Vpc",
|
|
229
|
-
"description": "EC2 instances must be launched in approved VPCs",
|
|
230
|
-
"example": (
|
|
231
|
-
"{\n"
|
|
232
|
-
' "Condition": {\n'
|
|
233
|
-
' "StringEquals": {\n'
|
|
234
|
-
' "ec2:Vpc": "arn:aws:ec2:us-east-1:123456789012:vpc/vpc-12345678"\n'
|
|
235
|
-
" }\n"
|
|
236
|
-
" }\n"
|
|
237
|
-
"}"
|
|
238
|
-
),
|
|
239
|
-
},
|
|
240
|
-
],
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
# EC2 Instances - Tag requirements (ABAC)
|
|
244
|
-
EC2_TAG_REQUIREMENTS: Final[dict[str, Any]] = {
|
|
245
|
-
"actions": ["ec2:RunInstances"],
|
|
246
|
-
"severity": "high",
|
|
247
|
-
"required_conditions": {
|
|
248
|
-
"all_of": [
|
|
249
|
-
{
|
|
250
|
-
"condition_key": "aws:RequestTag/env",
|
|
251
|
-
"operator": "StringEquals",
|
|
252
|
-
"expected_value": ["prod", "pre", "dev", "sandbox"],
|
|
253
|
-
"description": "Must specify a valid Environment tag",
|
|
254
|
-
},
|
|
255
|
-
],
|
|
256
|
-
"any_of": [
|
|
257
|
-
{
|
|
258
|
-
"condition_key": "aws:ResourceTag/owner",
|
|
259
|
-
"operator": "StringEquals",
|
|
260
|
-
"expected_value": "${aws:PrincipalTag/owner}",
|
|
261
|
-
"description": "Resource owner must match the principal's owner tag",
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
"condition_key": "aws:RequestTag/owner",
|
|
265
|
-
"description": "Must specify resource owner",
|
|
266
|
-
"expected_value": "${aws:PrincipalTag/owner}",
|
|
267
|
-
},
|
|
268
|
-
],
|
|
269
|
-
},
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
# RDS - Database tag requirements
|
|
273
|
-
RDS_TAG_REQUIREMENTS: Final[dict[str, Any]] = {
|
|
274
|
-
"action_patterns": [
|
|
275
|
-
"^rds:Create.*",
|
|
276
|
-
"^rds:Modify.*",
|
|
277
|
-
],
|
|
278
|
-
"severity": "medium",
|
|
279
|
-
"required_conditions": {
|
|
280
|
-
"all_of": [
|
|
281
|
-
{
|
|
282
|
-
"condition_key": "aws:RequestTag/DataClassification",
|
|
283
|
-
"description": "Must specify data classification",
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
"condition_key": "aws:RequestTag/BackupPolicy",
|
|
287
|
-
"description": "Must specify backup policy",
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
"condition_key": "aws:RequestTag/Owner",
|
|
291
|
-
"description": "Must specify resource owner",
|
|
292
|
-
},
|
|
293
|
-
],
|
|
294
|
-
},
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
# S3 Bucket Operations - Data classification matching
|
|
298
|
-
S3_BUCKET_TAG_REQUIREMENTS: Final[dict[str, Any]] = {
|
|
299
|
-
"actions": ["s3:CreateBucket", "s3:PutObject"],
|
|
300
|
-
"severity": "medium",
|
|
301
|
-
"required_conditions": {
|
|
302
|
-
"all_of": [
|
|
303
|
-
{
|
|
304
|
-
"condition_key": "aws:ResourceTag/DataClassification",
|
|
305
|
-
"operator": "StringEquals",
|
|
306
|
-
"expected_value": "${aws:PrincipalTag/DataClassification}",
|
|
307
|
-
"description": "Data classification must match principal's tag",
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
"condition_key": "aws:RequestTag/Owner",
|
|
311
|
-
"description": "Must specify owner",
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
"condition_key": "aws:RequestTag/CostCenter",
|
|
315
|
-
"description": "Must specify cost center",
|
|
316
|
-
},
|
|
317
|
-
],
|
|
318
|
-
},
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
# Forbidden Actions - Flag if these dangerous actions appear
|
|
322
|
-
FORBIDDEN_ACTIONS: Final[dict[str, Any]] = {
|
|
323
|
-
"actions": {
|
|
324
|
-
"none_of": [
|
|
325
|
-
"iam:*",
|
|
326
|
-
"s3:DeleteBucket",
|
|
327
|
-
"s3:DeleteBucketPolicy",
|
|
328
|
-
],
|
|
329
|
-
},
|
|
330
|
-
"severity": "critical",
|
|
331
|
-
"description": "These highly sensitive actions are forbidden in this policy",
|
|
332
|
-
}
|
|
333
|
-
|
|
334
130
|
# Prevent overly permissive IP ranges
|
|
335
131
|
PREVENT_PUBLIC_IP: Final[dict[str, Any]] = {
|
|
336
132
|
"action_patterns": ["^s3:.*"],
|
|
@@ -347,189 +143,13 @@ PREVENT_PUBLIC_IP: Final[dict[str, Any]] = {
|
|
|
347
143
|
}
|
|
348
144
|
|
|
349
145
|
# ============================================================================
|
|
350
|
-
#
|
|
146
|
+
# Condition Requirements
|
|
351
147
|
# ============================================================================
|
|
352
148
|
|
|
353
|
-
|
|
354
|
-
DEFAULT_CONDITION_REQUIREMENTS: Final[list[dict[str, Any]]] = [
|
|
149
|
+
CONDITION_REQUIREMENTS: Final[list[dict[str, Any]]] = [
|
|
355
150
|
IAM_PASS_ROLE_REQUIREMENT,
|
|
356
|
-
IAM_WRITE_PERMISSIONS_BOUNDARY,
|
|
357
151
|
S3_WRITE_ORG_ID,
|
|
358
152
|
SOURCE_IP_RESTRICTIONS,
|
|
359
153
|
S3_SECURE_TRANSPORT,
|
|
154
|
+
PREVENT_PUBLIC_IP,
|
|
360
155
|
]
|
|
361
|
-
|
|
362
|
-
# All available requirements (including optional ones)
|
|
363
|
-
ALL_CONDITION_REQUIREMENTS: Final[dict[str, dict[str, Any]]] = {
|
|
364
|
-
# Default (enabled)
|
|
365
|
-
"iam_pass_role": IAM_PASS_ROLE_REQUIREMENT,
|
|
366
|
-
"iam_permissions_boundary": IAM_WRITE_PERMISSIONS_BOUNDARY,
|
|
367
|
-
"s3_org_id": S3_WRITE_ORG_ID,
|
|
368
|
-
"source_ip_restrictions": SOURCE_IP_RESTRICTIONS,
|
|
369
|
-
"s3_secure_transport": S3_SECURE_TRANSPORT,
|
|
370
|
-
# Optional (disabled by default)
|
|
371
|
-
"s3_destructive_mfa": S3_DESTRUCTIVE_MFA,
|
|
372
|
-
"s3_require_https": S3_REQUIRE_HTTPS,
|
|
373
|
-
"ec2_vpc_restriction": EC2_VPC_RESTRICTION,
|
|
374
|
-
"ec2_tag_requirements": EC2_TAG_REQUIREMENTS,
|
|
375
|
-
"rds_tag_requirements": RDS_TAG_REQUIREMENTS,
|
|
376
|
-
"s3_bucket_tag_requirements": S3_BUCKET_TAG_REQUIREMENTS,
|
|
377
|
-
"forbidden_actions": FORBIDDEN_ACTIONS,
|
|
378
|
-
"prevent_public_ip": PREVENT_PUBLIC_IP,
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
# ============================================================================
|
|
383
|
-
# Helper Functions
|
|
384
|
-
# ============================================================================
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
def get_default_requirements() -> list[dict[str, Any]]:
|
|
388
|
-
"""
|
|
389
|
-
Get the default condition requirements.
|
|
390
|
-
|
|
391
|
-
Returns:
|
|
392
|
-
List of default condition requirement configurations
|
|
393
|
-
"""
|
|
394
|
-
# Return a copy to prevent modification
|
|
395
|
-
import copy
|
|
396
|
-
|
|
397
|
-
return copy.deepcopy(DEFAULT_CONDITION_REQUIREMENTS)
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
def get_requirement(name: str) -> dict[str, Any] | None:
|
|
401
|
-
"""
|
|
402
|
-
Get a specific requirement by name.
|
|
403
|
-
|
|
404
|
-
Args:
|
|
405
|
-
name: Requirement name (e.g., "iam_pass_role", "s3_destructive_mfa")
|
|
406
|
-
|
|
407
|
-
Returns:
|
|
408
|
-
Requirement configuration dict, or None if not found
|
|
409
|
-
"""
|
|
410
|
-
import copy
|
|
411
|
-
|
|
412
|
-
req = ALL_CONDITION_REQUIREMENTS.get(name)
|
|
413
|
-
return copy.deepcopy(req) if req else None
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
def get_all_requirement_names() -> list[str]:
|
|
417
|
-
"""
|
|
418
|
-
Get list of all available requirement names.
|
|
419
|
-
|
|
420
|
-
Returns:
|
|
421
|
-
List of requirement names
|
|
422
|
-
"""
|
|
423
|
-
return list(ALL_CONDITION_REQUIREMENTS.keys())
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
def get_requirements_by_names(names: list[str]) -> list[dict[str, Any]]:
|
|
427
|
-
"""
|
|
428
|
-
Get multiple requirements by name.
|
|
429
|
-
|
|
430
|
-
Args:
|
|
431
|
-
names: List of requirement names
|
|
432
|
-
|
|
433
|
-
Returns:
|
|
434
|
-
List of requirement configurations
|
|
435
|
-
"""
|
|
436
|
-
import copy
|
|
437
|
-
|
|
438
|
-
requirements = []
|
|
439
|
-
for name in names:
|
|
440
|
-
req = ALL_CONDITION_REQUIREMENTS.get(name)
|
|
441
|
-
if req:
|
|
442
|
-
requirements.append(copy.deepcopy(req))
|
|
443
|
-
return requirements
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
def get_requirements_by_severity(
|
|
447
|
-
min_severity: str = "low",
|
|
448
|
-
) -> list[dict[str, Any]]:
|
|
449
|
-
"""
|
|
450
|
-
Get requirements filtered by minimum severity.
|
|
451
|
-
|
|
452
|
-
Args:
|
|
453
|
-
min_severity: Minimum severity level (low, medium, high, critical)
|
|
454
|
-
|
|
455
|
-
Returns:
|
|
456
|
-
List of requirements matching severity criteria
|
|
457
|
-
"""
|
|
458
|
-
import copy
|
|
459
|
-
|
|
460
|
-
severity_order = {"low": 0, "medium": 1, "high": 2, "critical": 3}
|
|
461
|
-
min_level = severity_order.get(min_severity, 0)
|
|
462
|
-
|
|
463
|
-
requirements = []
|
|
464
|
-
for req in ALL_CONDITION_REQUIREMENTS.values():
|
|
465
|
-
req_severity = req.get("severity", "low")
|
|
466
|
-
req_level = severity_order.get(req_severity, 0)
|
|
467
|
-
if req_level >= min_level:
|
|
468
|
-
requirements.append(copy.deepcopy(req))
|
|
469
|
-
|
|
470
|
-
return requirements
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
def describe_requirement(name: str) -> dict[str, Any]:
|
|
474
|
-
"""
|
|
475
|
-
Get description and metadata for a requirement.
|
|
476
|
-
|
|
477
|
-
Args:
|
|
478
|
-
name: Requirement name
|
|
479
|
-
|
|
480
|
-
Returns:
|
|
481
|
-
Dictionary with requirement metadata
|
|
482
|
-
"""
|
|
483
|
-
descriptions = {
|
|
484
|
-
"iam_pass_role": {
|
|
485
|
-
"name": "IAM PassRole Restriction",
|
|
486
|
-
"category": "privilege_escalation",
|
|
487
|
-
"severity": "high",
|
|
488
|
-
"description": "Prevents privilege escalation by requiring iam:PassedToService condition",
|
|
489
|
-
"required": True,
|
|
490
|
-
},
|
|
491
|
-
"iam_permissions_boundary": {
|
|
492
|
-
"name": "IAM Permissions Boundary",
|
|
493
|
-
"category": "privilege_escalation",
|
|
494
|
-
"severity": "high",
|
|
495
|
-
"description": "Requires permissions boundary for IAM write operations",
|
|
496
|
-
"required": True,
|
|
497
|
-
},
|
|
498
|
-
"s3_org_id": {
|
|
499
|
-
"name": "S3 Organization ID",
|
|
500
|
-
"category": "data_exfiltration",
|
|
501
|
-
"severity": "medium",
|
|
502
|
-
"description": "Ensures S3 operations stay within organization",
|
|
503
|
-
"required": True,
|
|
504
|
-
},
|
|
505
|
-
"source_ip_restrictions": {
|
|
506
|
-
"name": "Source IP Restrictions",
|
|
507
|
-
"category": "network_security",
|
|
508
|
-
"severity": "low",
|
|
509
|
-
"description": "Restricts access to corporate IP ranges",
|
|
510
|
-
"required": False,
|
|
511
|
-
},
|
|
512
|
-
"s3_secure_transport": {
|
|
513
|
-
"name": "S3 Secure Transport",
|
|
514
|
-
"category": "encryption",
|
|
515
|
-
"severity": "medium",
|
|
516
|
-
"description": "Prevents explicitly allowing insecure transport",
|
|
517
|
-
"required": True,
|
|
518
|
-
},
|
|
519
|
-
"s3_destructive_mfa": {
|
|
520
|
-
"name": "S3 Destructive MFA",
|
|
521
|
-
"category": "data_protection",
|
|
522
|
-
"severity": "high",
|
|
523
|
-
"description": "Requires MFA for destructive S3 operations",
|
|
524
|
-
"required": False,
|
|
525
|
-
},
|
|
526
|
-
"ec2_tag_requirements": {
|
|
527
|
-
"name": "EC2 Tag Requirements (ABAC)",
|
|
528
|
-
"category": "abac",
|
|
529
|
-
"severity": "high",
|
|
530
|
-
"description": "Enforces tag-based access control for EC2 instances",
|
|
531
|
-
"required": False,
|
|
532
|
-
},
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
return descriptions.get(name, {"name": "Unknown", "description": "Unknown requirement"})
|
|
@@ -267,6 +267,9 @@ class ConfigLoader:
|
|
|
267
267
|
config=check_config_dict,
|
|
268
268
|
description=check_config_dict.get("description", check.description),
|
|
269
269
|
root_config=config.config_dict, # Pass full config for cross-check access
|
|
270
|
+
ignore_patterns=check_config_dict.get(
|
|
271
|
+
"ignore_patterns", []
|
|
272
|
+
), # NEW: Ignore patterns
|
|
270
273
|
)
|
|
271
274
|
|
|
272
275
|
registry.configure_check(check_id, check_config)
|