iam-policy-validator 1.3.1__py3-none-any.whl → 1.5.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.3.1.dist-info → iam_policy_validator-1.5.0.dist-info}/METADATA +164 -19
- iam_policy_validator-1.5.0.dist-info/RECORD +67 -0
- iam_validator/__version__.py +1 -1
- iam_validator/checks/__init__.py +15 -3
- iam_validator/checks/action_condition_enforcement.py +1 -6
- iam_validator/checks/condition_key_validation.py +21 -1
- iam_validator/checks/full_wildcard.py +67 -0
- iam_validator/checks/policy_size.py +1 -0
- iam_validator/checks/policy_type_validation.py +299 -0
- iam_validator/checks/principal_validation.py +776 -0
- iam_validator/checks/sensitive_action.py +178 -0
- iam_validator/checks/service_wildcard.py +105 -0
- iam_validator/checks/sid_uniqueness.py +45 -7
- iam_validator/checks/utils/sensitive_action_matcher.py +39 -31
- iam_validator/checks/wildcard_action.py +62 -0
- iam_validator/checks/wildcard_resource.py +131 -0
- iam_validator/commands/download_services.py +3 -8
- iam_validator/commands/post_to_pr.py +7 -0
- iam_validator/commands/validate.py +204 -16
- iam_validator/core/aws_fetcher.py +25 -12
- iam_validator/core/check_registry.py +25 -21
- iam_validator/core/config/__init__.py +83 -0
- iam_validator/core/config/aws_api.py +35 -0
- iam_validator/core/config/condition_requirements.py +535 -0
- iam_validator/core/config/defaults.py +390 -0
- iam_validator/core/config/principal_requirements.py +421 -0
- iam_validator/core/config/sensitive_actions.py +133 -0
- iam_validator/core/config/service_principals.py +95 -0
- iam_validator/core/config/wildcards.py +124 -0
- iam_validator/core/config_loader.py +29 -9
- iam_validator/core/formatters/enhanced.py +11 -5
- iam_validator/core/formatters/sarif.py +78 -14
- iam_validator/core/models.py +13 -3
- iam_validator/core/policy_checks.py +39 -6
- iam_validator/core/pr_commenter.py +30 -9
- iam_policy_validator-1.3.1.dist-info/RECORD +0 -54
- iam_validator/checks/security_best_practices.py +0 -535
- iam_validator/core/defaults.py +0 -366
- {iam_policy_validator-1.3.1.dist-info → iam_policy_validator-1.5.0.dist-info}/WHEEL +0 -0
- {iam_policy_validator-1.3.1.dist-info → iam_policy_validator-1.5.0.dist-info}/entry_points.txt +0 -0
- {iam_policy_validator-1.3.1.dist-info → iam_policy_validator-1.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iam-policy-validator
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.0
|
|
4
4
|
Summary: Validate AWS IAM policies for correctness and security using AWS Service Reference API
|
|
5
5
|
Project-URL: Homepage, https://github.com/boogy/iam-policy-validator
|
|
6
6
|
Project-URL: Documentation, https://github.com/boogy/iam-policy-validator/tree/main/docs
|
|
@@ -448,13 +448,11 @@ settings:
|
|
|
448
448
|
enable_builtin_checks: true
|
|
449
449
|
|
|
450
450
|
# Custom check configurations
|
|
451
|
-
|
|
451
|
+
wildcard_action:
|
|
452
452
|
enabled: true
|
|
453
|
-
|
|
454
|
-
enabled: true
|
|
455
|
-
severity: high
|
|
453
|
+
severity: high
|
|
456
454
|
|
|
457
|
-
|
|
455
|
+
action_condition_enforcement:
|
|
458
456
|
enabled: true
|
|
459
457
|
severity: critical
|
|
460
458
|
action_condition_requirements:
|
|
@@ -465,7 +463,7 @@ action_condition_enforcement_check:
|
|
|
465
463
|
- condition_key: "iam:PassedToService"
|
|
466
464
|
```
|
|
467
465
|
|
|
468
|
-
See [
|
|
466
|
+
See [examples/configs/full-reference-config.yaml](examples/configs/full-reference-config.yaml) for a complete configuration reference with all available options.
|
|
469
467
|
|
|
470
468
|
### GitHub Action Inputs
|
|
471
469
|
|
|
@@ -478,10 +476,11 @@ See [default-config.yaml](default-config.yaml) for a complete configuration exam
|
|
|
478
476
|
| `recursive` | Recursively search directories for policy files | No | `true` |
|
|
479
477
|
|
|
480
478
|
#### GitHub Integration
|
|
481
|
-
| Input
|
|
482
|
-
|
|
|
483
|
-
| `post-comment`
|
|
484
|
-
| `create-review`
|
|
479
|
+
| Input | Description | Required | Default |
|
|
480
|
+
| ---------------- | --------------------------------------------------------- | -------- | ------- |
|
|
481
|
+
| `post-comment` | Post validation summary as PR conversation comment | No | `true` |
|
|
482
|
+
| `create-review` | Create line-specific review comments on PR files | No | `true` |
|
|
483
|
+
| `github-summary` | Write summary to GitHub Actions job summary (Actions tab) | No | `false` |
|
|
485
484
|
|
|
486
485
|
#### Output Options
|
|
487
486
|
| Input | Description | Required | Default |
|
|
@@ -490,12 +489,12 @@ See [default-config.yaml](default-config.yaml) for a complete configuration exam
|
|
|
490
489
|
| `output-file` | Path to save output file (for non-console formats) | No | `""` |
|
|
491
490
|
|
|
492
491
|
#### AWS Access Analyzer
|
|
493
|
-
| Input | Description
|
|
494
|
-
| ------------------------ |
|
|
495
|
-
| `use-access-analyzer` | Use AWS IAM Access Analyzer for validation
|
|
496
|
-
| `access-analyzer-region` | AWS region for Access Analyzer
|
|
497
|
-
| `policy-type` | Policy type: `IDENTITY_POLICY`, `RESOURCE_POLICY`, `SERVICE_CONTROL_POLICY` | No | `IDENTITY_POLICY` |
|
|
498
|
-
| `run-all-checks` | Run custom checks after Access Analyzer (sequential mode)
|
|
492
|
+
| Input | Description | Required | Default |
|
|
493
|
+
| ------------------------ | ------------------------------------------------------------------------------------------------------ | -------- | ----------------- |
|
|
494
|
+
| `use-access-analyzer` | Use AWS IAM Access Analyzer for validation | No | `false` |
|
|
495
|
+
| `access-analyzer-region` | AWS region for Access Analyzer | No | `us-east-1` |
|
|
496
|
+
| `policy-type` | Policy type: `IDENTITY_POLICY`, `RESOURCE_POLICY`, `SERVICE_CONTROL_POLICY`, `RESOURCE_CONTROL_POLICY` | No | `IDENTITY_POLICY` |
|
|
497
|
+
| `run-all-checks` | Run custom checks after Access Analyzer (sequential mode) | No | `false` |
|
|
499
498
|
|
|
500
499
|
#### Custom Policy Checks (Access Analyzer)
|
|
501
500
|
| Input | Description | Required | Default |
|
|
@@ -518,7 +517,7 @@ See [default-config.yaml](default-config.yaml) for a complete configuration exam
|
|
|
518
517
|
- Configure `aws-services-dir` in your config file for offline validation
|
|
519
518
|
- The action automatically filters IAM policies from mixed JSON/YAML files
|
|
520
519
|
|
|
521
|
-
See [examples/github-actions/](examples/github-actions/) for
|
|
520
|
+
See [examples/github-actions/](examples/github-actions/) for 9 ready-to-use workflow examples.
|
|
522
521
|
|
|
523
522
|
### As a CLI Tool
|
|
524
523
|
|
|
@@ -540,6 +539,12 @@ iam-validator validate --path ./policies/
|
|
|
540
539
|
# Validate multiple paths
|
|
541
540
|
iam-validator validate --path policy1.json --path ./policies/ --path ./more-policies/
|
|
542
541
|
|
|
542
|
+
# Validate resource policies (S3 bucket policies, SNS topics, etc.)
|
|
543
|
+
iam-validator validate --path ./bucket-policies/ --policy-type RESOURCE_POLICY
|
|
544
|
+
|
|
545
|
+
# Validate AWS Organizations Resource Control Policies (RCPs)
|
|
546
|
+
iam-validator validate --path ./rcps/ --policy-type RESOURCE_CONTROL_POLICY
|
|
547
|
+
|
|
543
548
|
# Generate JSON output
|
|
544
549
|
iam-validator validate --path ./policies/ --format json --output report.json
|
|
545
550
|
|
|
@@ -557,6 +562,106 @@ iam-validator analyze \
|
|
|
557
562
|
--github-review
|
|
558
563
|
```
|
|
559
564
|
|
|
565
|
+
### Policy Type Validation
|
|
566
|
+
|
|
567
|
+
The validator supports four AWS policy types, each with specific validation rules:
|
|
568
|
+
|
|
569
|
+
#### 🔷 IDENTITY_POLICY (Default)
|
|
570
|
+
Standard IAM policies attached to users, groups, or roles.
|
|
571
|
+
|
|
572
|
+
**Requirements:**
|
|
573
|
+
- Should NOT have `Principal` element (implicit - the attached entity)
|
|
574
|
+
- Must have `Action` and `Resource` elements
|
|
575
|
+
|
|
576
|
+
**Example:**
|
|
577
|
+
```bash
|
|
578
|
+
iam-validator validate --path ./user-policies/ --policy-type IDENTITY_POLICY
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
#### 🔶 RESOURCE_POLICY
|
|
582
|
+
Policies attached to AWS resources (S3 buckets, SNS topics, KMS keys, etc.).
|
|
583
|
+
|
|
584
|
+
**Requirements:**
|
|
585
|
+
- MUST have `Principal` element (who can access)
|
|
586
|
+
- Must have `Action`, `Effect`, and `Resource` elements
|
|
587
|
+
- Can use configurable security checks for principal validation
|
|
588
|
+
|
|
589
|
+
**Example:**
|
|
590
|
+
```bash
|
|
591
|
+
iam-validator validate --path ./bucket-policies/ --policy-type RESOURCE_POLICY
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
**Advanced Principal Validation:**
|
|
595
|
+
```yaml
|
|
596
|
+
# config.yaml
|
|
597
|
+
principal_validation:
|
|
598
|
+
enabled: true
|
|
599
|
+
severity: high
|
|
600
|
+
# Block public access
|
|
601
|
+
blocked_principals: ["*"]
|
|
602
|
+
# Or require specific conditions for public access
|
|
603
|
+
require_conditions_for:
|
|
604
|
+
"*":
|
|
605
|
+
- "aws:SourceArn"
|
|
606
|
+
- "aws:SourceAccount"
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
#### 🔷 SERVICE_CONTROL_POLICY
|
|
610
|
+
AWS Organizations SCPs that set permission guardrails.
|
|
611
|
+
|
|
612
|
+
**Requirements:**
|
|
613
|
+
- Must NOT have `Principal` element (applies to all principals in OU)
|
|
614
|
+
- Typically uses `Deny` effect for guardrails
|
|
615
|
+
- Must have `Action` and `Resource` elements
|
|
616
|
+
|
|
617
|
+
**Example:**
|
|
618
|
+
```bash
|
|
619
|
+
iam-validator validate --path ./scps/ --policy-type SERVICE_CONTROL_POLICY
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
#### 🆕 RESOURCE_CONTROL_POLICY
|
|
623
|
+
AWS Organizations RCPs for resource-level access control (released 2024).
|
|
624
|
+
|
|
625
|
+
**Strict Requirements:**
|
|
626
|
+
- `Effect` MUST be `Deny` (only AWS-managed `RCPFullAWSAccess` can use `Allow`)
|
|
627
|
+
- `Principal` MUST be exactly `"*"` (use `Condition` to restrict)
|
|
628
|
+
- `Action` cannot use `"*"` alone (must be service-specific like `"s3:*"`)
|
|
629
|
+
- Only **5 supported services**: `s3`, `sts`, `sqs`, `secretsmanager`, `kms`
|
|
630
|
+
- `NotAction` and `NotPrincipal` are NOT supported
|
|
631
|
+
- Must have `Resource` or `NotResource` element
|
|
632
|
+
|
|
633
|
+
**Example:**
|
|
634
|
+
```bash
|
|
635
|
+
iam-validator validate --path ./rcps/ --policy-type RESOURCE_CONTROL_POLICY
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
**Valid RCP:**
|
|
639
|
+
```json
|
|
640
|
+
{
|
|
641
|
+
"Version": "2012-10-17",
|
|
642
|
+
"Statement": [{
|
|
643
|
+
"Sid": "EnforceEncryptionInTransit",
|
|
644
|
+
"Effect": "Deny",
|
|
645
|
+
"Principal": "*",
|
|
646
|
+
"Action": ["s3:*", "sqs:*"],
|
|
647
|
+
"Resource": "*",
|
|
648
|
+
"Condition": {
|
|
649
|
+
"BoolIfExists": {
|
|
650
|
+
"aws:SecureTransport": "false"
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}]
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
**What the validator catches:**
|
|
658
|
+
```
|
|
659
|
+
✓ Effect is "Deny" (required for RCPs)
|
|
660
|
+
✓ Principal is "*" (required - restrictions via Condition)
|
|
661
|
+
✓ Actions from supported services (s3, sqs)
|
|
662
|
+
✓ Uses Condition to scope the deny
|
|
663
|
+
```
|
|
664
|
+
|
|
560
665
|
### Custom Policy Checks
|
|
561
666
|
|
|
562
667
|
AWS IAM Access Analyzer provides specialized checks to validate policies against specific security requirements:
|
|
@@ -744,6 +849,44 @@ Identifies potential security risks:
|
|
|
744
849
|
|
|
745
850
|
## GitHub Integration Features
|
|
746
851
|
|
|
852
|
+
### Flexible Comment Options
|
|
853
|
+
|
|
854
|
+
The validator provides **three independent ways** to display validation results in GitHub:
|
|
855
|
+
|
|
856
|
+
#### 1. **PR Summary Comment** (`--github-comment`)
|
|
857
|
+
Posts a high-level summary to the PR conversation with:
|
|
858
|
+
- Overall metrics (total policies, issues, severities)
|
|
859
|
+
- Grouped findings by file
|
|
860
|
+
- Detailed issue descriptions with suggestions
|
|
861
|
+
|
|
862
|
+
#### 2. **Line-Specific Review Comments** (`--github-review`)
|
|
863
|
+
Creates inline review comments on the "Files changed" tab:
|
|
864
|
+
- Comments appear directly on problematic lines
|
|
865
|
+
- Includes rich context (examples, suggestions)
|
|
866
|
+
- Automatically cleaned up on subsequent runs
|
|
867
|
+
- Review status (REQUEST_CHANGES or COMMENT) based on `fail_on_severity` config
|
|
868
|
+
|
|
869
|
+
#### 3. **GitHub Actions Job Summary** (`--github-summary`)
|
|
870
|
+
Writes a high-level overview to the Actions tab:
|
|
871
|
+
- Visible in workflow run summary
|
|
872
|
+
- Shows key metrics and severity breakdown
|
|
873
|
+
- Clean dashboard view without overwhelming details
|
|
874
|
+
|
|
875
|
+
**Mix and Match:** Use any combination of these options:
|
|
876
|
+
```bash
|
|
877
|
+
# All three for maximum visibility
|
|
878
|
+
--github-comment --github-review --github-summary
|
|
879
|
+
|
|
880
|
+
# Only line-specific review comments (clean, minimal)
|
|
881
|
+
--github-review
|
|
882
|
+
|
|
883
|
+
# Only PR summary comment
|
|
884
|
+
--github-comment
|
|
885
|
+
|
|
886
|
+
# Only Actions job summary
|
|
887
|
+
--github-summary
|
|
888
|
+
```
|
|
889
|
+
|
|
747
890
|
### Smart PR Comment Management
|
|
748
891
|
|
|
749
892
|
The validator intelligently manages PR comments to keep your PRs clean:
|
|
@@ -757,8 +900,9 @@ The validator intelligently manages PR comments to keep your PRs clean:
|
|
|
757
900
|
**Behavior:**
|
|
758
901
|
- ✅ **No Duplicates**: Summary comments are updated, not duplicated
|
|
759
902
|
- ✅ **Clean PR**: Old review comments automatically deleted before new validation
|
|
760
|
-
- ✅ **Identifiable**: All bot comments
|
|
903
|
+
- ✅ **Identifiable**: All bot comments use HTML identifiers (invisible to users)
|
|
761
904
|
- ✅ **Progressive**: In streaming mode, comments appear file-by-file
|
|
905
|
+
- ✅ **Smart Review Status**: Uses `fail_on_severity` config to determine REQUEST_CHANGES vs COMMENT
|
|
762
906
|
|
|
763
907
|
**Example:**
|
|
764
908
|
```
|
|
@@ -830,6 +974,7 @@ The comprehensive [DOCS.md](DOCS.md) file contains everything you need:
|
|
|
830
974
|
- [Custom Checks](examples/custom_checks/)
|
|
831
975
|
- [Configuration Files](examples/configs/)
|
|
832
976
|
- [Test IAM Policies](examples/iam-test-policies/)
|
|
977
|
+
- **[Roadmap](docs/ROADMAP.md)** - Planned features and improvements
|
|
833
978
|
- **[AWS Services Backup Guide](docs/aws-services-backup.md)** - Offline validation
|
|
834
979
|
- **[Contributing Guide](CONTRIBUTING.md)** - Contribution guidelines
|
|
835
980
|
- **[Publishing Guide](docs/development/PUBLISHING.md)** - Release process
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
iam_validator/__init__.py,sha256=APnMR3Fu4fHhxfsHBvUM2dJIwazgvLKQbfOsSgFPidg,693
|
|
2
|
+
iam_validator/__main__.py,sha256=to_nz3n_IerJpVVZZ6WSFlFR5s_06J0csfPOTfQZG8g,197
|
|
3
|
+
iam_validator/__version__.py,sha256=aNFKvgY68bb-MhUFw2OC-8_0VmwOTwY6_J5GPtri6os,206
|
|
4
|
+
iam_validator/checks/__init__.py,sha256=OSgwk2WO_lLYOgSrTAycUNgRHw0NSU33Rse39thvVSk,1456
|
|
5
|
+
iam_validator/checks/action_condition_enforcement.py,sha256=bKQEkD7PJYA0g9CwfrgfQSAKcVJkQgqfSnpXKE3Rz_0,29588
|
|
6
|
+
iam_validator/checks/action_resource_constraint.py,sha256=p-gP7S9QYR6M7vffrnJY6LOlMUTn0kpEbrxQ8pTY5rs,6031
|
|
7
|
+
iam_validator/checks/action_validation.py,sha256=IpxtTsk58f2zEZ-xzAoyHw4QK8BCRV43OffP-8ydf9E,2578
|
|
8
|
+
iam_validator/checks/condition_key_validation.py,sha256=XmlwSDHq7p48dEDxjUJiRtaqtfAiFgpBJnj2jY_25LU,3796
|
|
9
|
+
iam_validator/checks/full_wildcard.py,sha256=8zkmkQo2TkflgNgbclThH73mIBRHbuiob0YO2HwQhuE,2371
|
|
10
|
+
iam_validator/checks/policy_size.py,sha256=gJD8rFHa1CstKaZ2Dj9B5XEI3o0wsGv7ksqjqZXoSXI,5771
|
|
11
|
+
iam_validator/checks/policy_type_validation.py,sha256=w85W4zdZ6ZrDy0DmHxxnAXbJGfN8peRDjLfJ4Bp1dWc,15009
|
|
12
|
+
iam_validator/checks/principal_validation.py,sha256=DLmqX_QbfuV8O5XtcuocBeR_Vwa50_3RBx35XuLQob8,29837
|
|
13
|
+
iam_validator/checks/resource_validation.py,sha256=AEIoiR6AKYLuVaA8ne3QE5qy6NCMDe98_2JAiwE9-JU,4261
|
|
14
|
+
iam_validator/checks/sensitive_action.py,sha256=mGxUELAuzsY_zK382WgJeeRGJDl8lumIsWgGIm_tmPs,6852
|
|
15
|
+
iam_validator/checks/service_wildcard.py,sha256=1O3NF8_T1LsCzpm8SFViv1KTh9NYQSqXN8-D3xx6Erw,4156
|
|
16
|
+
iam_validator/checks/sid_uniqueness.py,sha256=1Ux9W1hPPhzgdCzfxwxvD-nSBRo1SyrxFWlnTXDcOys,6887
|
|
17
|
+
iam_validator/checks/wildcard_action.py,sha256=KsAej_GP6qL2XpmvGnS56SIJw3Z-5xyvZ7VDfsERFrU,2045
|
|
18
|
+
iam_validator/checks/wildcard_resource.py,sha256=V5aBmb1pr8KhbVv2G4nzjBlZWz0kCOCgW6jKnb2_U60,5504
|
|
19
|
+
iam_validator/checks/utils/__init__.py,sha256=j0X4ibUB6RGx2a-kNoJnlVZwHfoEvzZsIeTmJIAoFzA,45
|
|
20
|
+
iam_validator/checks/utils/policy_level_checks.py,sha256=2V60C0zhKfsFPjQ-NMlD3EemtwA9S6-4no8nETgXdQE,5274
|
|
21
|
+
iam_validator/checks/utils/sensitive_action_matcher.py,sha256=Wl_YHktQR1LthkePaLMVF5iCeBpax2QgNRN0_azgfD8,9295
|
|
22
|
+
iam_validator/checks/utils/wildcard_expansion.py,sha256=V3V_KRpapOzPBhpUObJjGHoMhvCH90QvDxppeEHIG_U,3152
|
|
23
|
+
iam_validator/commands/__init__.py,sha256=M-5bo8w0TCWydK0cXgJyPD2fmk8bpQs-3b26YbgLzlc,565
|
|
24
|
+
iam_validator/commands/analyze.py,sha256=TWlDaZ8gVOdNv6__KQQfzeLVW36qLiL5IzlhGYfvq_g,16501
|
|
25
|
+
iam_validator/commands/base.py,sha256=5baCCMwxz7pdQ6XMpWfXFNz7i1l5dB8Qv9dKKR04Gzs,1074
|
|
26
|
+
iam_validator/commands/cache.py,sha256=NHfbIDWI8tj-3o-4fIZJQS-Vvd9bxIH3Lk6kBtNuiUU,14212
|
|
27
|
+
iam_validator/commands/download_services.py,sha256=KKz3ybMLT8DQUf9aFZ0tilJ-o1b6PE8Pf1pC4K6cT8I,9175
|
|
28
|
+
iam_validator/commands/post_to_pr.py,sha256=CvUXs2xvO-UhluxdfNM6F0TCWD8hDBEOiYw60fm1Dms,2363
|
|
29
|
+
iam_validator/commands/validate.py,sha256=Nz6nC8UoRSLjnxTjv5n1qc5SOC88vK1ZwV04nH4oPDI,22333
|
|
30
|
+
iam_validator/core/__init__.py,sha256=1FvJPMrbzJfS9YbRUJCshJLd5gzWwR9Fd_slS0Aq9c8,416
|
|
31
|
+
iam_validator/core/access_analyzer.py,sha256=poeT1i74jXpKr1B3UmvqiTvCTbq82zffWgZHwiFUwoo,24337
|
|
32
|
+
iam_validator/core/access_analyzer_report.py,sha256=IrQVszlhFfQ6WykYLpig7TU3hf8dnQTegPDsOvHjR5Q,24873
|
|
33
|
+
iam_validator/core/aws_fetcher.py,sha256=raEnvUi3rFaE1Bf9h6Am0bKeDSUN0WI6MPuVt4LSQzg,34169
|
|
34
|
+
iam_validator/core/aws_global_conditions.py,sha256=ADVcMEWhgvDZWdBmRUQN3HB7a9OycbTLecXFAy3LPbo,5837
|
|
35
|
+
iam_validator/core/check_registry.py,sha256=-3MDcJvzN07cyMbi9UTzw_JcPJCcB-tXGl5hKX-Y2ZY,16067
|
|
36
|
+
iam_validator/core/cli.py,sha256=PkXiZjlgrQ21QustBbspefYsdbxst4gxoClyG2_HQR8,3843
|
|
37
|
+
iam_validator/core/config_loader.py,sha256=qPdRokl8Hdc1t1vX--JQjOC_colgnnq1MrKsGtcW56s,17609
|
|
38
|
+
iam_validator/core/models.py,sha256=8v-b8Z8PFqpbdEpkZZ33kuZ_5D81Z2lIHzlFLu3i5mE,11094
|
|
39
|
+
iam_validator/core/policy_checks.py,sha256=zmA1GupD5jE1avCdaYLdZ7WA7CVG0CWjmgkd_2F-p7A,26429
|
|
40
|
+
iam_validator/core/policy_loader.py,sha256=TR7SpzlRG3TwH4HBGEFUuhNOmxIR8Cud2SQ-AmHWBpM,14040
|
|
41
|
+
iam_validator/core/pr_commenter.py,sha256=7wt1q1rQE3bozNfrynWaE2RVkyRxu4CUNKX7u1_Ii1c,11593
|
|
42
|
+
iam_validator/core/report.py,sha256=Yeh_u9jQvTyDV3ignyPcWEQVfFcxNZNrxf4T0fjeWb4,33283
|
|
43
|
+
iam_validator/core/config/__init__.py,sha256=e9Dh-NtUtW6-Kk_RwLiOzLn8X09E4_VqgNp0Cuva7y0,2655
|
|
44
|
+
iam_validator/core/config/aws_api.py,sha256=HLIzOItQ0A37wxHcgWck6ZFO0wmNY8JNTiWMMK6JKYU,1248
|
|
45
|
+
iam_validator/core/config/condition_requirements.py,sha256=45HITvpClti453CgrMLlV1AwoZVUbSTVVhflaxapJTM,17021
|
|
46
|
+
iam_validator/core/config/defaults.py,sha256=_GcVnGkMMqqG1OCxQy4lsS5pM7rDD3phXHTq1w3ECJU,19334
|
|
47
|
+
iam_validator/core/config/principal_requirements.py,sha256=VCX7fBDgeDTJQyoz7_x7GI7Kf9O1Eu-sbihoHOrKv6o,15105
|
|
48
|
+
iam_validator/core/config/sensitive_actions.py,sha256=J03x_Y3z2gqU4QmeQF2iDWEZfeWKoNls1qL2VgtwtOU,4464
|
|
49
|
+
iam_validator/core/config/service_principals.py,sha256=gQSROsxUWBD6P2F9qP320UZV4lHGlsyvHSkMyy0njrU,2685
|
|
50
|
+
iam_validator/core/config/wildcards.py,sha256=H_v6hb-rZ0UUz4cul9lxkVI39e6knaK4Y-MbWz2Ebpw,3228
|
|
51
|
+
iam_validator/core/formatters/__init__.py,sha256=fnCKAEBXItnOf2m4rhVs7zwMaTxbG6ESh3CF8V5j5ec,868
|
|
52
|
+
iam_validator/core/formatters/base.py,sha256=SShDeDiy5mYQnS6BpA8xYg91N-KX1EObkOtlrVHqx1Q,4451
|
|
53
|
+
iam_validator/core/formatters/console.py,sha256=lX4Yp4bTW61fxe0fCiHuO6bCZtC_6cjCwqDNQ55nT_8,1937
|
|
54
|
+
iam_validator/core/formatters/csv.py,sha256=2FaN6Y_0TPMFOb3A3tNtj0-9bkEc5P-6eZ7eLROIqFE,5899
|
|
55
|
+
iam_validator/core/formatters/enhanced.py,sha256=S0UgYKFOgILfOqwnBC8-WFab3F1CiEko33g0nbaswtk,17085
|
|
56
|
+
iam_validator/core/formatters/html.py,sha256=j4sQi-wXiD9kCHldW5JCzbJe0frhiP5uQI9KlH3Sj_g,22994
|
|
57
|
+
iam_validator/core/formatters/json.py,sha256=A7gZ8P32GEdbDvrSn6v56yQ4fOP_kyMaoFVXG2bgnew,939
|
|
58
|
+
iam_validator/core/formatters/markdown.py,sha256=aPAY6FpZBHsVBDag3FAsB_X9CZzznFjX9dQr0ysDrTE,2251
|
|
59
|
+
iam_validator/core/formatters/sarif.py,sha256=O3pn7whqFq5xxk-tuoqSb2k4Fk5ai_A2SKX_ph8GLV4,10469
|
|
60
|
+
iam_validator/integrations/__init__.py,sha256=7Hlor_X9j0NZaEjFuSvoXAAuSKQ-zgY19Rk-Dz3JpKo,616
|
|
61
|
+
iam_validator/integrations/github_integration.py,sha256=bKs94vNT4PmcmUPUeuY2WJFhCYpUY2SWiBP1vj-andA,25673
|
|
62
|
+
iam_validator/integrations/ms_teams.py,sha256=t2PlWuTDb6GGH-eDU1jnOKd8D1w4FCB68bahGA7MJcE,14475
|
|
63
|
+
iam_policy_validator-1.5.0.dist-info/METADATA,sha256=D5TTVNQDeankIcLYRBT_UzysyZgWTZtaHzby0CHH_Vc,34222
|
|
64
|
+
iam_policy_validator-1.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
65
|
+
iam_policy_validator-1.5.0.dist-info/entry_points.txt,sha256=8HtWd8O7mvPiPdZR5YbzY8or_qcqLM4-pKaFdhtFT8M,62
|
|
66
|
+
iam_policy_validator-1.5.0.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
|
|
67
|
+
iam_policy_validator-1.5.0.dist-info/RECORD,,
|
iam_validator/__version__.py
CHANGED
iam_validator/checks/__init__.py
CHANGED
|
@@ -5,21 +5,33 @@ Built-in policy checks for IAM Policy Validator.
|
|
|
5
5
|
from iam_validator.checks.action_condition_enforcement import (
|
|
6
6
|
ActionConditionEnforcementCheck,
|
|
7
7
|
)
|
|
8
|
-
from iam_validator.checks.action_resource_constraint import
|
|
8
|
+
from iam_validator.checks.action_resource_constraint import (
|
|
9
|
+
ActionResourceConstraintCheck,
|
|
10
|
+
)
|
|
9
11
|
from iam_validator.checks.action_validation import ActionValidationCheck
|
|
10
12
|
from iam_validator.checks.condition_key_validation import ConditionKeyValidationCheck
|
|
13
|
+
from iam_validator.checks.full_wildcard import FullWildcardCheck
|
|
11
14
|
from iam_validator.checks.policy_size import PolicySizeCheck
|
|
15
|
+
from iam_validator.checks.principal_validation import PrincipalValidationCheck
|
|
12
16
|
from iam_validator.checks.resource_validation import ResourceValidationCheck
|
|
13
|
-
from iam_validator.checks.
|
|
17
|
+
from iam_validator.checks.sensitive_action import SensitiveActionCheck
|
|
18
|
+
from iam_validator.checks.service_wildcard import ServiceWildcardCheck
|
|
14
19
|
from iam_validator.checks.sid_uniqueness import SidUniquenessCheck
|
|
20
|
+
from iam_validator.checks.wildcard_action import WildcardActionCheck
|
|
21
|
+
from iam_validator.checks.wildcard_resource import WildcardResourceCheck
|
|
15
22
|
|
|
16
23
|
__all__ = [
|
|
17
24
|
"ActionConditionEnforcementCheck",
|
|
18
25
|
"ActionResourceConstraintCheck",
|
|
19
26
|
"ActionValidationCheck",
|
|
20
27
|
"ConditionKeyValidationCheck",
|
|
28
|
+
"FullWildcardCheck",
|
|
21
29
|
"PolicySizeCheck",
|
|
30
|
+
"PrincipalValidationCheck",
|
|
22
31
|
"ResourceValidationCheck",
|
|
23
|
-
"
|
|
32
|
+
"SensitiveActionCheck",
|
|
33
|
+
"ServiceWildcardCheck",
|
|
24
34
|
"SidUniquenessCheck",
|
|
35
|
+
"WildcardActionCheck",
|
|
36
|
+
"WildcardResourceCheck",
|
|
25
37
|
]
|
|
@@ -607,10 +607,7 @@ class ActionConditionEnforcementCheck(PolicyCheck):
|
|
|
607
607
|
statement_sid=statement.sid,
|
|
608
608
|
statement_index=statement_idx,
|
|
609
609
|
issue_type="missing_required_condition",
|
|
610
|
-
message=(
|
|
611
|
-
f"{message_prefix} Action(s) {matching_actions} require condition '{condition_key}'. "
|
|
612
|
-
f"{description}"
|
|
613
|
-
),
|
|
610
|
+
message=f"{message_prefix} Action(s) {matching_actions} require condition '{condition_key}'",
|
|
614
611
|
action=", ".join(matching_actions),
|
|
615
612
|
condition_key=condition_key,
|
|
616
613
|
suggestion=self._build_suggestion(
|
|
@@ -707,8 +704,6 @@ class ActionConditionEnforcementCheck(PolicyCheck):
|
|
|
707
704
|
)
|
|
708
705
|
if expected_value is not None:
|
|
709
706
|
message += f" with value '{expected_value}'"
|
|
710
|
-
if description:
|
|
711
|
-
message += f". {description}"
|
|
712
707
|
|
|
713
708
|
suggestion = f"Remove the '{condition_key}' condition from the statement"
|
|
714
709
|
if description:
|
|
@@ -34,6 +34,9 @@ class ConditionKeyValidationCheck(PolicyCheck):
|
|
|
34
34
|
if not statement.condition:
|
|
35
35
|
return issues
|
|
36
36
|
|
|
37
|
+
# Check if global condition key warnings are enabled (default: True)
|
|
38
|
+
warn_on_global_keys = config.config.get("warn_on_global_condition_keys", True)
|
|
39
|
+
|
|
37
40
|
statement_sid = statement.sid
|
|
38
41
|
line_number = statement.line_number
|
|
39
42
|
actions = statement.get_actions()
|
|
@@ -47,7 +50,7 @@ class ConditionKeyValidationCheck(PolicyCheck):
|
|
|
47
50
|
if action == "*":
|
|
48
51
|
continue
|
|
49
52
|
|
|
50
|
-
is_valid, error_msg = await fetcher.validate_condition_key(
|
|
53
|
+
is_valid, error_msg, warning_msg = await fetcher.validate_condition_key(
|
|
51
54
|
action, condition_key
|
|
52
55
|
)
|
|
53
56
|
|
|
@@ -66,5 +69,22 @@ class ConditionKeyValidationCheck(PolicyCheck):
|
|
|
66
69
|
)
|
|
67
70
|
# Only report once per condition key (not per action)
|
|
68
71
|
break
|
|
72
|
+
elif warning_msg and warn_on_global_keys:
|
|
73
|
+
# Add warning for global condition keys with action-specific keys
|
|
74
|
+
# Only if warn_on_global_condition_keys is enabled
|
|
75
|
+
issues.append(
|
|
76
|
+
ValidationIssue(
|
|
77
|
+
severity="warning",
|
|
78
|
+
statement_sid=statement_sid,
|
|
79
|
+
statement_index=statement_idx,
|
|
80
|
+
issue_type="global_condition_key_with_action_specific",
|
|
81
|
+
message=warning_msg,
|
|
82
|
+
action=action,
|
|
83
|
+
condition_key=condition_key,
|
|
84
|
+
line_number=line_number,
|
|
85
|
+
)
|
|
86
|
+
)
|
|
87
|
+
# Only report once per condition key (not per action)
|
|
88
|
+
break
|
|
69
89
|
|
|
70
90
|
return issues
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Full wildcard check - detects Action: '*' AND Resource: '*' together (critical security risk)."""
|
|
2
|
+
|
|
3
|
+
from iam_validator.core.aws_fetcher import AWSServiceFetcher
|
|
4
|
+
from iam_validator.core.check_registry import CheckConfig, PolicyCheck
|
|
5
|
+
from iam_validator.core.models import Statement, ValidationIssue
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FullWildcardCheck(PolicyCheck):
|
|
9
|
+
"""Checks for both Action: '*' AND Resource: '*' which grants full administrative access."""
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def check_id(self) -> str:
|
|
13
|
+
return "full_wildcard"
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def description(self) -> str:
|
|
17
|
+
return "Checks for both action and resource wildcards together (critical risk)"
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def default_severity(self) -> str:
|
|
21
|
+
return "critical"
|
|
22
|
+
|
|
23
|
+
async def execute(
|
|
24
|
+
self,
|
|
25
|
+
statement: Statement,
|
|
26
|
+
statement_idx: int,
|
|
27
|
+
fetcher: AWSServiceFetcher,
|
|
28
|
+
config: CheckConfig,
|
|
29
|
+
) -> list[ValidationIssue]:
|
|
30
|
+
"""Execute full wildcard check on a statement."""
|
|
31
|
+
issues = []
|
|
32
|
+
|
|
33
|
+
# Only check Allow statements
|
|
34
|
+
if statement.effect != "Allow":
|
|
35
|
+
return issues
|
|
36
|
+
|
|
37
|
+
actions = statement.get_actions()
|
|
38
|
+
resources = statement.get_resources()
|
|
39
|
+
|
|
40
|
+
# Check for both wildcards together (CRITICAL)
|
|
41
|
+
if "*" in actions and "*" in resources:
|
|
42
|
+
message = config.config.get(
|
|
43
|
+
"message",
|
|
44
|
+
"Statement allows all actions on all resources - CRITICAL SECURITY RISK",
|
|
45
|
+
)
|
|
46
|
+
suggestion_text = config.config.get(
|
|
47
|
+
"suggestion",
|
|
48
|
+
"This grants full administrative access. Replace both wildcards with specific actions and resources to follow least-privilege principle",
|
|
49
|
+
)
|
|
50
|
+
example = config.config.get("example", "")
|
|
51
|
+
|
|
52
|
+
# Combine suggestion + example
|
|
53
|
+
suggestion = f"{suggestion_text}\nExample:\n{example}" if example else suggestion_text
|
|
54
|
+
|
|
55
|
+
issues.append(
|
|
56
|
+
ValidationIssue(
|
|
57
|
+
severity=self.get_severity(config),
|
|
58
|
+
statement_sid=statement.sid,
|
|
59
|
+
statement_index=statement_idx,
|
|
60
|
+
issue_type="security_risk",
|
|
61
|
+
message=message,
|
|
62
|
+
suggestion=suggestion,
|
|
63
|
+
line_number=statement.line_number,
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return issues
|