iam-policy-validator 1.14.5__py3-none-any.whl → 1.14.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iam-policy-validator
3
- Version: 1.14.5
3
+ Version: 1.14.7
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
- Project-URL: Documentation, https://github.com/boogy/iam-policy-validator/tree/main/docs
6
+ Project-URL: Documentation, https://boogy.github.io/iam-policy-validator
7
7
  Project-URL: Repository, https://github.com/boogy/iam-policy-validator
8
8
  Project-URL: Issues, https://github.com/boogy/iam-policy-validator/issues
9
- Project-URL: Changelog, https://github.com/boogy/iam-policy-validator/blob/main/docs/CHANGELOG.md
9
+ Project-URL: Changelog, https://github.com/boogy/iam-policy-validator/blob/main/CHANGELOG.md
10
10
  Author-email: boogy <0xboogy@gmail.com>
11
11
  License: MIT
12
12
  License-File: LICENSE
@@ -38,11 +38,17 @@ Requires-Dist: pytest>=7.0.0; extra == 'dev'
38
38
  Requires-Dist: ruff>=0.1.0; extra == 'dev'
39
39
  Requires-Dist: types-boto3; extra == 'dev'
40
40
  Requires-Dist: types-pyyaml; extra == 'dev'
41
+ Provides-Extra: docs
42
+ Requires-Dist: mkdocs-gen-files>=0.5.0; extra == 'docs'
43
+ Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == 'docs'
44
+ Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
45
+ Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
46
+ Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
41
47
  Description-Content-Type: text/markdown
42
48
 
43
49
  # IAM Policy Validator
44
50
 
45
- **Catch IAM policy errors before they reach AWS** — Validate syntax, security misconfigurations, and dangerous permission combinations in CI/CD pipelines.
51
+ **Stop IAM misconfigurations before they become breaches** — Catch overprivileged permissions, dangerous wildcards, and policy errors before deployment.
46
52
 
47
53
  [![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-Ready-blue)](https://github.com/marketplace/actions/iam-policy-validator)
48
54
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
@@ -120,7 +126,7 @@ iam-validator validate --path examples/quick-start/ --format enhanced
120
126
  ```
121
127
  ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
122
128
  │ │
123
- │ IAM Policy Validation Report (v1.10.3) │
129
+ │ IAM Policy Validation Report (v1.14.1) │
124
130
  │ │
125
131
  ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
126
132
  ───────────────────────────────────────── Detailed Results ─────────────────────────────────────────
@@ -294,7 +300,7 @@ sensitive_action:
294
300
  message: "CloudFormation + PassRole enables infrastructure privilege escalation"
295
301
  ```
296
302
 
297
- See [docs/privilege-escalation.md](docs/privilege-escalation.md) for all built-in patterns and custom configuration.
303
+ See [Security Checks Documentation](docs/user-guide/checks/security-checks.md) for all built-in patterns and custom configuration.
298
304
 
299
305
  **Comparison:**
300
306
 
@@ -635,7 +641,7 @@ sensitive_action:
635
641
 
636
642
  For more details, see:
637
643
 
638
- - [docs/condition-requirements.md](docs/condition-requirements.md) - How to configure condition requirements
644
+ - [Configuration Guide](docs/user-guide/configuration.md) - How to configure condition requirements
639
645
  - [examples/configs/full-reference-config.yaml](examples/configs/full-reference-config.yaml) - Complete configuration reference
640
646
 
641
647
  ---
@@ -710,12 +716,12 @@ iam-validator analyze --path new-policy.json \
710
716
 
711
717
  **Guides:**
712
718
 
713
- - [Check Reference](docs/check-reference.md) - All 19 checks with examples
714
- - [Configuration Guide](docs/configuration.md) - Customize checks and behavior
715
- - [GitHub Actions Guide](docs/github-actions-workflows.md) - CI/CD integration
716
- - [Python Library Guide](docs/python-library-usage.md) - Use as Python package
717
- - [Trust Policy Guide](examples/trust-policies/README.md) - Trust policy validation
718
- - [Query Command](docs/query-command.md) - Query AWS service definitions
719
+ - [Check Reference](docs/user-guide/checks/) - All checks with examples
720
+ - [Configuration Guide](docs/user-guide/configuration.md) - Customize checks and behavior
721
+ - [GitHub Actions Guide](docs/integrations/github-actions.md) - CI/CD integration
722
+ - [Python Library Guide](docs/developer-guide/sdk/) - Use as Python package
723
+ - [Trust Policy Examples](examples/trust-policies/) - Trust policy validation examples
724
+ - [Changelog](CHANGELOG.md) - Version history and migration guides
719
725
 
720
726
  **Examples:**
721
727
 
@@ -1,6 +1,6 @@
1
1
  iam_validator/__init__.py,sha256=xHdUASOxFHwEXfT_GSr_KrkLlnxZ-pAAr1wW1PwAGko,693
2
2
  iam_validator/__main__.py,sha256=to_nz3n_IerJpVVZZ6WSFlFR5s_06J0csfPOTfQZG8g,197
3
- iam_validator/__version__.py,sha256=8ouM89pP7JLVFY6dwrTsOuZeWcu_xuQ3YwT7-1g9xn8,374
3
+ iam_validator/__version__.py,sha256=gzNFhw4Ir0RuOpe7hw6D6K-mQnE1zvBtL7jSlcAUnrE,374
4
4
  iam_validator/checks/__init__.py,sha256=OTkPnmlelu4YjMO8krjhu2wXiTV72RzopA5u1SfPQA0,1990
5
5
  iam_validator/checks/action_condition_enforcement.py,sha256=2-XUMbof9tQ7SHZNmAHMkR1DgbOIzY2eFWlp9S9dwLk,60625
6
6
  iam_validator/checks/action_resource_matching.py,sha256=qND0hfDgNoxFEdLWwrxOPVDfdj3k50nzedT2qF7nK7o,19428
@@ -54,7 +54,7 @@ iam_validator/core/models.py,sha256=lXUadIsTpp_j0Vt89Ez7aJkTKs2GD2ty3Ukl2NeY9Zo,
54
54
  iam_validator/core/policy_checks.py,sha256=FNVuS2GTffwCjjrlupVIazC172gSxKYAAT_ObV6Apbo,8803
55
55
  iam_validator/core/policy_loader.py,sha256=iid3mGfDzSXASzKDqbLnrqJHBdVQvvebofVqNImsGKM,29201
56
56
  iam_validator/core/pr_commenter.py,sha256=IZu2FQqzw73U_8ugTUq197ECLqk9mRCQpTWXPu5qk0k,35490
57
- iam_validator/core/report.py,sha256=IEHjNe6v_9nvcGA8_FNbXdG0AoV-yHVjiP1KQKnpEys,41376
57
+ iam_validator/core/report.py,sha256=IDjBjSrzrE_JdkA8eTiSxyUL3g36sJMhTkxehEYzuBQ,45476
58
58
  iam_validator/core/aws_service/__init__.py,sha256=UqMh4HUdGlx2QF5OoueJJ2UlCnhX4QW_x3KeE_bxRQc,735
59
59
  iam_validator/core/aws_service/cache.py,sha256=DPuOOPPJC867KAYgV1e0RyQs_k3mtefMdYli3jPaN64,3589
60
60
  iam_validator/core/aws_service/client.py,sha256=Zv7rIpEFdUCDXKGp3migPDkj8L5eZltgrGe64M2t2Ko,7336
@@ -85,11 +85,11 @@ iam_validator/core/formatters/json.py,sha256=A7gZ8P32GEdbDvrSn6v56yQ4fOP_kyMaoFV
85
85
  iam_validator/core/formatters/markdown.py,sha256=dk4STeY-tOEZsVrlmolIEqZvWYP9JhRtygxxNA49DEE,2293
86
86
  iam_validator/core/formatters/sarif.py,sha256=03MHSyuZm9FlzaPeWg7wH-UTzzCDhSy6vMPrFpFNkS8,18884
87
87
  iam_validator/integrations/__init__.py,sha256=7Hlor_X9j0NZaEjFuSvoXAAuSKQ-zgY19Rk-Dz3JpKo,616
88
- iam_validator/integrations/github_integration.py,sha256=IKhJW_v_lGZiuyPN_xWULzv2YBbaXHn8zBfaOdUm28g,69054
88
+ iam_validator/integrations/github_integration.py,sha256=0aeQ_RPTZf5ij7dsBjmtIDz4oHl0BXLno9GperFzTbc,69004
89
89
  iam_validator/integrations/ms_teams.py,sha256=t2PlWuTDb6GGH-eDU1jnOKd8D1w4FCB68bahGA7MJcE,14475
90
- iam_validator/sdk/__init__.py,sha256=AZLnfdn3A9AWb0pMhsbu3GAOAzt6rV7Fi3E3d9_3ZdI,6388
90
+ iam_validator/sdk/__init__.py,sha256=1voMXldzhLJ0mZ4AxwYPXwJd_kKFjQ-zp_tN8eWvkP4,6209
91
91
  iam_validator/sdk/arn_matching.py,sha256=HSDpLltOYISq-SoPebAlM89mKOaUaghq_04urchEFDA,12778
92
- iam_validator/sdk/context.py,sha256=FvAEyUa_s7tHWoSdgjSkzHf1CLlYpAEmLZANxs2IJ4A,6826
92
+ iam_validator/sdk/context.py,sha256=b2XXlvsnqxl42d1wsdoynTqsZOy8nRjV73RgxIdKdPQ,6940
93
93
  iam_validator/sdk/exceptions.py,sha256=tm91TxIwU157U_UHN7w5qICf_OhU11agj6pV5W_YP-4,1023
94
94
  iam_validator/sdk/helpers.py,sha256=sjfK0na_Fo7O8GhEVhl44rVHqOdw6nAKkBL4FVL-QdU,5697
95
95
  iam_validator/sdk/policy_utils.py,sha256=bGdJ1X1aC72dVXXpAnAwyBpAiiX-qXvblpetY5BsjKU,13658
@@ -99,8 +99,8 @@ iam_validator/utils/__init__.py,sha256=NveA2F3G1E6-ANZzFr7J6Q6u5mogvMp862iFokmYu
99
99
  iam_validator/utils/cache.py,sha256=wOQKOBeoG6QqC5f0oXcHz63Cjtu_-SsSS-0pTSwyAiM,3254
100
100
  iam_validator/utils/regex.py,sha256=xHoMECttb7qaMhts-c9b0GIxdhHNZTt-UBr7wNhWfzg,6219
101
101
  iam_validator/utils/terminal.py,sha256=FsRaRMH_JAyDgXWBCOgOEhbS89cs17HCmKYoughq5io,724
102
- iam_policy_validator-1.14.5.dist-info/METADATA,sha256=h6M6__GqJW5fWPtV0cEDqZ4sK259K5ulz68Jgt6COQE,34456
103
- iam_policy_validator-1.14.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
104
- iam_policy_validator-1.14.5.dist-info/entry_points.txt,sha256=8HtWd8O7mvPiPdZR5YbzY8or_qcqLM4-pKaFdhtFT8M,62
105
- iam_policy_validator-1.14.5.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
106
- iam_policy_validator-1.14.5.dist-info/RECORD,,
102
+ iam_policy_validator-1.14.7.dist-info/METADATA,sha256=l4PstdoYzO1kqFBTI2M7UDbvoQMAcVC9sHamKl43x9Y,34741
103
+ iam_policy_validator-1.14.7.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
104
+ iam_policy_validator-1.14.7.dist-info/entry_points.txt,sha256=8HtWd8O7mvPiPdZR5YbzY8or_qcqLM4-pKaFdhtFT8M,62
105
+ iam_policy_validator-1.14.7.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
106
+ iam_policy_validator-1.14.7.dist-info/RECORD,,
@@ -3,7 +3,7 @@
3
3
  This file is the single source of truth for the package version.
4
4
  """
5
5
 
6
- __version__ = "1.14.5"
6
+ __version__ = "1.14.7"
7
7
  # Parse version, handling pre-release suffixes like -rc, -alpha, -beta
8
8
  _version_base = __version__.split("-", maxsplit=1)[0] # Remove pre-release suffix if present
9
9
  __version_info__ = tuple(int(part) for part in _version_base.split("."))
@@ -478,13 +478,14 @@ class ReportGenerator:
478
478
 
479
479
  # Issue breakdown
480
480
  if report.total_issues > 0:
481
- # Count issues - support both IAM validity and security severities
482
- errors = sum(
483
- 1
484
- for r in report.results
485
- for i in r.issues
486
- if i.severity in constants.HIGH_SEVERITY_LEVELS
481
+ # Count issues - separate validity errors from security findings
482
+ validity_errors = sum(
483
+ 1 for r in report.results for i in r.issues if i.severity == "error"
487
484
  )
485
+ critical_findings = sum(
486
+ 1 for r in report.results for i in r.issues if i.severity == "critical"
487
+ )
488
+ high_findings = sum(1 for r in report.results for i in r.issues if i.severity == "high")
488
489
  warnings = sum(
489
490
  1 for r in report.results for i in r.issues if i.severity in ("warning", "medium")
490
491
  )
@@ -496,8 +497,12 @@ class ReportGenerator:
496
497
  lines.append("")
497
498
  lines.append("| Severity | Count |")
498
499
  lines.append("|----------|------:|")
499
- if errors > 0:
500
- lines.append(f"| 🔴 **Errors** | {errors} |")
500
+ if validity_errors > 0:
501
+ lines.append(f"| 🔴 **Errors** | {validity_errors} |")
502
+ if critical_findings > 0:
503
+ lines.append(f"| 🟣 **Critical** | {critical_findings} |")
504
+ if high_findings > 0:
505
+ lines.append(f"| 🔶 **High** | {high_findings} |")
501
506
  if warnings > 0:
502
507
  lines.append(f"| 🟡 **Warnings** | {warnings} |")
503
508
  if infos > 0:
@@ -578,15 +583,31 @@ class ReportGenerator:
578
583
  )
579
584
  lines.append("")
580
585
 
581
- # Group issues by severity - support both IAM validity and security severities
582
- errors = [i for i in result.issues if i.severity in constants.HIGH_SEVERITY_LEVELS]
586
+ # Group issues by severity - separate validity errors from security findings
587
+ validity_errors = [i for i in result.issues if i.severity == "error"]
588
+ critical_findings = [i for i in result.issues if i.severity == "critical"]
589
+ high_findings = [i for i in result.issues if i.severity == "high"]
583
590
  warnings = [i for i in result.issues if i.severity in constants.MEDIUM_SEVERITY_LEVELS]
584
591
  infos = [i for i in result.issues if i.severity in constants.LOW_SEVERITY_LEVELS]
585
592
 
586
- if errors:
593
+ if validity_errors:
587
594
  lines.append("### 🔴 Errors")
588
595
  lines.append("")
589
- for issue in errors:
596
+ for issue in validity_errors:
597
+ lines.append(self._format_issue_markdown(issue, result.policy_file))
598
+ lines.append("")
599
+
600
+ if critical_findings:
601
+ lines.append("### 🟣 Critical")
602
+ lines.append("")
603
+ for issue in critical_findings:
604
+ lines.append(self._format_issue_markdown(issue, result.policy_file))
605
+ lines.append("")
606
+
607
+ if high_findings:
608
+ lines.append("### 🔶 High")
609
+ lines.append("")
610
+ for issue in high_findings:
590
611
  lines.append(self._format_issue_markdown(issue, result.policy_file))
591
612
  lines.append("")
592
613
 
@@ -693,13 +714,14 @@ class ReportGenerator:
693
714
 
694
715
  # Issue breakdown
695
716
  if report.total_issues > 0:
696
- # Count issues - support both IAM validity and security severities
697
- errors = sum(
698
- 1
699
- for r in report.results
700
- for i in r.issues
701
- if i.severity in constants.HIGH_SEVERITY_LEVELS
717
+ # Count issues - separate validity errors from security findings
718
+ validity_errors = sum(
719
+ 1 for r in report.results for i in r.issues if i.severity == "error"
702
720
  )
721
+ critical_findings = sum(
722
+ 1 for r in report.results for i in r.issues if i.severity == "critical"
723
+ )
724
+ high_findings = sum(1 for r in report.results for i in r.issues if i.severity == "high")
703
725
  warnings = sum(
704
726
  1 for r in report.results for i in r.issues if i.severity in ("warning", "medium")
705
727
  )
@@ -711,8 +733,12 @@ class ReportGenerator:
711
733
  lines.append("")
712
734
  lines.append("| Severity | Count |")
713
735
  lines.append("|----------|------:|")
714
- if errors > 0:
715
- lines.append(f"| 🔴 **Errors** | {errors} |")
736
+ if validity_errors > 0:
737
+ lines.append(f"| 🔴 **Errors** | {validity_errors} |")
738
+ if critical_findings > 0:
739
+ lines.append(f"| 🟣 **Critical** | {critical_findings} |")
740
+ if high_findings > 0:
741
+ lines.append(f"| 🔶 **High** | {high_findings} |")
716
742
  if warnings > 0:
717
743
  lines.append(f"| 🟡 **Warnings** | {warnings} |")
718
744
  if infos > 0:
@@ -789,15 +815,21 @@ class ReportGenerator:
789
815
 
790
816
  policy_lines = []
791
817
 
792
- # Group issues by severity - support both IAM validity and security severities
793
- errors = [i for i in result.issues if i.severity in constants.HIGH_SEVERITY_LEVELS]
818
+ # Group issues by severity - separate validity errors from security findings
819
+ validity_errors = [i for i in result.issues if i.severity == "error"]
820
+ critical_findings = [i for i in result.issues if i.severity == "critical"]
821
+ high_findings = [i for i in result.issues if i.severity == "high"]
794
822
  warnings = [i for i in result.issues if i.severity in ("warning", "medium")]
795
823
  infos = [i for i in result.issues if i.severity in ("info", "low")]
796
824
 
797
825
  # Build severity summary for header
798
826
  severity_parts = []
799
- if errors:
800
- severity_parts.append(f"🔴 {len(errors)}")
827
+ if validity_errors:
828
+ severity_parts.append(f"🔴 {len(validity_errors)}")
829
+ if critical_findings:
830
+ severity_parts.append(f"🟣 {len(critical_findings)}")
831
+ if high_findings:
832
+ severity_parts.append(f"🔶 {len(high_findings)}")
801
833
  if warnings:
802
834
  severity_parts.append(f"🟡 {len(warnings)}")
803
835
  if infos:
@@ -812,11 +844,57 @@ class ReportGenerator:
812
844
  )
813
845
  policy_lines.append("")
814
846
 
815
- # Add errors (prioritized)
816
- if errors:
847
+ # Add validity errors (prioritized)
848
+ if validity_errors:
817
849
  policy_lines.append("### 🔴 Errors")
818
850
  policy_lines.append("")
819
- for i, issue in enumerate(errors):
851
+ for i, issue in enumerate(validity_errors):
852
+ issue_content = self._format_issue_markdown(issue, result.policy_file)
853
+ test_length = len("\n".join(details_lines + policy_lines)) + len(
854
+ issue_content
855
+ )
856
+ if test_length > available_length:
857
+ truncated = True
858
+ break
859
+ policy_lines.append(issue_content)
860
+ issues_shown += 1
861
+ # Add separator between issues within same severity
862
+ if i < len(validity_errors) - 1:
863
+ policy_lines.append("---")
864
+ policy_lines.append("")
865
+ policy_lines.append("")
866
+
867
+ if truncated:
868
+ break
869
+
870
+ # Add critical security findings
871
+ if critical_findings:
872
+ policy_lines.append("### 🟣 Critical")
873
+ policy_lines.append("")
874
+ for i, issue in enumerate(critical_findings):
875
+ issue_content = self._format_issue_markdown(issue, result.policy_file)
876
+ test_length = len("\n".join(details_lines + policy_lines)) + len(
877
+ issue_content
878
+ )
879
+ if test_length > available_length:
880
+ truncated = True
881
+ break
882
+ policy_lines.append(issue_content)
883
+ issues_shown += 1
884
+ # Add separator between issues within same severity
885
+ if i < len(critical_findings) - 1:
886
+ policy_lines.append("---")
887
+ policy_lines.append("")
888
+ policy_lines.append("")
889
+
890
+ if truncated:
891
+ break
892
+
893
+ # Add high security findings
894
+ if high_findings:
895
+ policy_lines.append("### 🔶 High")
896
+ policy_lines.append("")
897
+ for i, issue in enumerate(high_findings):
820
898
  issue_content = self._format_issue_markdown(issue, result.policy_file)
821
899
  test_length = len("\n".join(details_lines + policy_lines)) + len(
822
900
  issue_content
@@ -827,7 +905,7 @@ class ReportGenerator:
827
905
  policy_lines.append(issue_content)
828
906
  issues_shown += 1
829
907
  # Add separator between issues within same severity
830
- if i < len(errors) - 1:
908
+ if i < len(high_findings) - 1:
831
909
  policy_lines.append("---")
832
910
  policy_lines.append("")
833
911
  policy_lines.append("")
@@ -1278,7 +1278,7 @@ class GitHubIntegration:
1278
1278
  logger.info(f"Submitting {event.value} review (no inline comments)")
1279
1279
  success = await self.create_review_with_comments(
1280
1280
  comments=[],
1281
- body=body or f"<!-- {identifier} -->\nValidation complete.",
1281
+ body=body,
1282
1282
  event=event,
1283
1283
  )
1284
1284
  if not success:
@@ -1,66 +1,71 @@
1
- """
2
- IAM Policy Validator SDK - Public API for library usage.
1
+ """IAM Policy Validator SDK - Public API for library usage.
3
2
 
4
3
  This module provides the complete public API for using IAM Policy Validator
5
4
  as a Python library. It exposes both high-level convenience functions and
6
5
  low-level components for custom integrations.
7
6
 
8
- Quick Start:
9
- Basic validation:
10
- >>> from iam_validator.sdk import validate_file
11
- >>> result = await validate_file("policy.json")
12
- >>> print(f"Valid: {result.is_valid}")
13
-
14
- With context manager:
15
- >>> from iam_validator.sdk import validator
16
- >>> async with validator() as v:
17
- ... result = await v.validate_file("policy.json")
18
- ... v.generate_report([result])
19
-
20
- Policy manipulation:
21
- >>> from iam_validator.sdk import parse_policy, get_policy_summary
22
- >>> policy = parse_policy(policy_json)
23
- >>> summary = get_policy_summary(policy)
24
- >>> print(f"Actions: {summary['action_count']}")
25
-
26
- Query AWS service definitions:
27
- >>> from iam_validator.sdk import AWSServiceFetcher, query_actions, query_arn_formats
28
- >>> async with AWSServiceFetcher() as fetcher:
29
- ... # Query all S3 write actions
30
- ... write_actions = await query_actions(fetcher, "s3", access_level="write")
31
- ... # Get ARN formats for S3
32
- ... arns = await query_arn_formats(fetcher, "s3")
33
-
34
- Custom check development:
35
- >>> from iam_validator.sdk import PolicyCheck, CheckHelper
36
- >>> class MyCheck(PolicyCheck):
37
- ... @property
38
- ... def check_id(self) -> str:
39
- ... return "my_check"
40
- ... async def execute(self, statement, idx, fetcher, config):
41
- ... helper = CheckHelper(fetcher)
42
- ... # Use helper.arn_matches(), helper.create_issue(), etc.
43
- ... return []
44
- """
7
+ Example:
8
+ Basic validation::
45
9
 
46
- # === High-level validation functions (shortcuts) ===
47
- # === AWS utilities ===
48
- from iam_validator.core.aws_service import AWSServiceFetcher
10
+ from iam_validator.sdk import validate_file
49
11
 
50
- # === Core validation components (for advanced usage) ===
51
- from iam_validator.core.check_registry import CheckRegistry, PolicyCheck
12
+ result = await validate_file("policy.json")
13
+ print(f"Valid: {result.is_valid}")
14
+
15
+ With context manager::
16
+
17
+ from iam_validator.sdk import validator
18
+
19
+ async with validator() as v:
20
+ result = await v.validate_file("policy.json")
21
+ v.generate_report([result])
22
+
23
+ Policy manipulation::
24
+
25
+ from iam_validator.sdk import parse_policy, get_policy_summary
26
+
27
+ policy = parse_policy(policy_json)
28
+ summary = get_policy_summary(policy)
29
+ print(f"Actions: {summary['action_count']}")
30
+
31
+ Query AWS service definitions::
32
+
33
+ from iam_validator.sdk import AWSServiceFetcher, query_actions
34
+
35
+ async with AWSServiceFetcher() as fetcher:
36
+ # Query all S3 write actions
37
+ write_actions = await query_actions(fetcher, "s3", access_level="write")
38
+
39
+ Custom check development::
40
+
41
+ from iam_validator.sdk import PolicyCheck, CheckHelper
52
42
 
53
- # === ValidatorConfiguration ===
54
- from iam_validator.core.config.config_loader import ValidatorConfig, load_validator_config
43
+ class MyCheck(PolicyCheck):
44
+ check_id = "my_check"
45
+ description = "My custom check"
46
+ default_severity = "medium"
55
47
 
56
- # === Reporting ===
48
+ async def execute(self, statement, idx, fetcher, config):
49
+ helper = CheckHelper(fetcher)
50
+ # Use helper.arn_matches(), helper.create_issue(), etc.
51
+ return []
52
+ """
53
+
54
+ # ruff: noqa: E402
55
+ # Imports are organized by category with comments, which triggers E402.
56
+ # This is intentional for readability in this public API module.
57
+
58
+ from iam_validator.core.aws_service import AWSServiceFetcher
59
+ from iam_validator.core.check_registry import CheckRegistry, PolicyCheck
60
+ from iam_validator.core.config.config_loader import (
61
+ ValidatorConfig,
62
+ load_validator_config,
63
+ )
57
64
  from iam_validator.core.formatters.csv import CSVFormatter
58
65
  from iam_validator.core.formatters.html import HTMLFormatter
59
66
  from iam_validator.core.formatters.json import JSONFormatter
60
67
  from iam_validator.core.formatters.markdown import MarkdownFormatter
61
68
  from iam_validator.core.formatters.sarif import SARIFFormatter
62
-
63
- # === Models (for type hints and inspection) ===
64
69
  from iam_validator.core.models import (
65
70
  IAMPolicy,
66
71
  PolicyValidationResult,
@@ -70,23 +75,17 @@ from iam_validator.core.models import (
70
75
  from iam_validator.core.policy_checks import validate_policies
71
76
  from iam_validator.core.policy_loader import PolicyLoader
72
77
  from iam_validator.core.report import ReportGenerator
73
-
74
- # === ARN matching utilities ===
75
78
  from iam_validator.sdk.arn_matching import (
76
79
  arn_matches,
77
80
  arn_strictly_valid,
78
81
  convert_aws_pattern_to_wildcard,
79
82
  is_glob_match,
80
83
  )
81
-
82
- # === Context managers ===
83
84
  from iam_validator.sdk.context import (
84
85
  ValidationContext,
85
86
  validator,
86
87
  validator_from_config,
87
88
  )
88
-
89
- # === Public exceptions ===
90
89
  from iam_validator.sdk.exceptions import (
91
90
  AWSServiceError,
92
91
  ConfigurationError,
@@ -96,11 +95,7 @@ from iam_validator.sdk.exceptions import (
96
95
  PolicyValidationError,
97
96
  UnsupportedPolicyTypeError,
98
97
  )
99
-
100
- # === Custom check development ===
101
98
  from iam_validator.sdk.helpers import CheckHelper, expand_actions
102
-
103
- # === Policy manipulation utilities ===
104
99
  from iam_validator.sdk.policy_utils import (
105
100
  extract_actions,
106
101
  extract_condition_keys,
@@ -116,8 +111,6 @@ from iam_validator.sdk.policy_utils import (
116
111
  policy_to_dict,
117
112
  policy_to_json,
118
113
  )
119
-
120
- # === Query utilities (AWS service definition queries) ===
121
114
  from iam_validator.sdk.query_utils import (
122
115
  get_actions_by_access_level,
123
116
  get_actions_supporting_condition,
@@ -139,6 +132,9 @@ from iam_validator.sdk.shortcuts import (
139
132
  validate_json,
140
133
  )
141
134
 
135
+ # Alias for convenience (matches documentation)
136
+ Config = ValidatorConfig
137
+
142
138
  __all__ = [
143
139
  # === High-level shortcuts ===
144
140
  "validate_file",
@@ -203,6 +199,7 @@ __all__ = [
203
199
  "Statement",
204
200
  # === ValidatorConfiguration ===
205
201
  "ValidatorConfig",
202
+ "Config", # Alias for ValidatorConfig
206
203
  "load_validator_config",
207
204
  # === AWS utilities ===
208
205
  "AWSServiceFetcher",
@@ -214,7 +211,9 @@ __all__ = [
214
211
  "AWSServiceError",
215
212
  "InvalidPolicyFormatError",
216
213
  "UnsupportedPolicyTypeError",
214
+ # Version
215
+ "__version__",
217
216
  ]
218
217
 
219
- # SDK version
220
- __version__ = "0.1.0"
218
+ # SDK version (same as main package)
219
+ from iam_validator.__version__ import __version__
@@ -5,6 +5,7 @@ This module provides context managers that handle resource lifecycle
5
5
  and make the validation API more convenient to use.
6
6
  """
7
7
 
8
+ from collections.abc import AsyncIterator
8
9
  from contextlib import asynccontextmanager
9
10
  from pathlib import Path
10
11
 
@@ -169,7 +170,7 @@ class ValidationContext:
169
170
  @asynccontextmanager
170
171
  async def validator(
171
172
  config_path: str | None = None,
172
- ):
173
+ ) -> AsyncIterator[ValidationContext]:
173
174
  """
174
175
  Context manager that handles AWS fetcher lifecycle.
175
176
 
@@ -201,7 +202,7 @@ async def validator(
201
202
 
202
203
 
203
204
  @asynccontextmanager
204
- async def validator_from_config(config_path: str):
205
+ async def validator_from_config(config_path: str) -> AsyncIterator[ValidationContext]:
205
206
  """
206
207
  Context manager that loads configuration and creates a validator.
207
208