iam-policy-validator 1.7.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.

Potentially problematic release.


This version of iam-policy-validator might be problematic. Click here for more details.

Files changed (83) hide show
  1. iam_policy_validator-1.7.0.dist-info/METADATA +1057 -0
  2. iam_policy_validator-1.7.0.dist-info/RECORD +83 -0
  3. iam_policy_validator-1.7.0.dist-info/WHEEL +4 -0
  4. iam_policy_validator-1.7.0.dist-info/entry_points.txt +2 -0
  5. iam_policy_validator-1.7.0.dist-info/licenses/LICENSE +21 -0
  6. iam_validator/__init__.py +27 -0
  7. iam_validator/__main__.py +11 -0
  8. iam_validator/__version__.py +7 -0
  9. iam_validator/checks/__init__.py +43 -0
  10. iam_validator/checks/action_condition_enforcement.py +884 -0
  11. iam_validator/checks/action_resource_matching.py +441 -0
  12. iam_validator/checks/action_validation.py +72 -0
  13. iam_validator/checks/condition_key_validation.py +92 -0
  14. iam_validator/checks/condition_type_mismatch.py +259 -0
  15. iam_validator/checks/full_wildcard.py +71 -0
  16. iam_validator/checks/mfa_condition_check.py +112 -0
  17. iam_validator/checks/policy_size.py +147 -0
  18. iam_validator/checks/policy_type_validation.py +305 -0
  19. iam_validator/checks/principal_validation.py +776 -0
  20. iam_validator/checks/resource_validation.py +138 -0
  21. iam_validator/checks/sensitive_action.py +254 -0
  22. iam_validator/checks/service_wildcard.py +107 -0
  23. iam_validator/checks/set_operator_validation.py +157 -0
  24. iam_validator/checks/sid_uniqueness.py +170 -0
  25. iam_validator/checks/utils/__init__.py +1 -0
  26. iam_validator/checks/utils/policy_level_checks.py +143 -0
  27. iam_validator/checks/utils/sensitive_action_matcher.py +294 -0
  28. iam_validator/checks/utils/wildcard_expansion.py +87 -0
  29. iam_validator/checks/wildcard_action.py +67 -0
  30. iam_validator/checks/wildcard_resource.py +135 -0
  31. iam_validator/commands/__init__.py +25 -0
  32. iam_validator/commands/analyze.py +531 -0
  33. iam_validator/commands/base.py +48 -0
  34. iam_validator/commands/cache.py +392 -0
  35. iam_validator/commands/download_services.py +255 -0
  36. iam_validator/commands/post_to_pr.py +86 -0
  37. iam_validator/commands/validate.py +600 -0
  38. iam_validator/core/__init__.py +14 -0
  39. iam_validator/core/access_analyzer.py +671 -0
  40. iam_validator/core/access_analyzer_report.py +640 -0
  41. iam_validator/core/aws_fetcher.py +940 -0
  42. iam_validator/core/check_registry.py +607 -0
  43. iam_validator/core/cli.py +134 -0
  44. iam_validator/core/condition_validators.py +626 -0
  45. iam_validator/core/config/__init__.py +81 -0
  46. iam_validator/core/config/aws_api.py +35 -0
  47. iam_validator/core/config/aws_global_conditions.py +160 -0
  48. iam_validator/core/config/category_suggestions.py +104 -0
  49. iam_validator/core/config/condition_requirements.py +155 -0
  50. iam_validator/core/config/config_loader.py +472 -0
  51. iam_validator/core/config/defaults.py +523 -0
  52. iam_validator/core/config/principal_requirements.py +421 -0
  53. iam_validator/core/config/sensitive_actions.py +672 -0
  54. iam_validator/core/config/service_principals.py +95 -0
  55. iam_validator/core/config/wildcards.py +124 -0
  56. iam_validator/core/constants.py +74 -0
  57. iam_validator/core/formatters/__init__.py +27 -0
  58. iam_validator/core/formatters/base.py +147 -0
  59. iam_validator/core/formatters/console.py +59 -0
  60. iam_validator/core/formatters/csv.py +170 -0
  61. iam_validator/core/formatters/enhanced.py +440 -0
  62. iam_validator/core/formatters/html.py +672 -0
  63. iam_validator/core/formatters/json.py +33 -0
  64. iam_validator/core/formatters/markdown.py +63 -0
  65. iam_validator/core/formatters/sarif.py +251 -0
  66. iam_validator/core/models.py +327 -0
  67. iam_validator/core/policy_checks.py +656 -0
  68. iam_validator/core/policy_loader.py +396 -0
  69. iam_validator/core/pr_commenter.py +424 -0
  70. iam_validator/core/report.py +872 -0
  71. iam_validator/integrations/__init__.py +28 -0
  72. iam_validator/integrations/github_integration.py +815 -0
  73. iam_validator/integrations/ms_teams.py +442 -0
  74. iam_validator/sdk/__init__.py +187 -0
  75. iam_validator/sdk/arn_matching.py +382 -0
  76. iam_validator/sdk/context.py +222 -0
  77. iam_validator/sdk/exceptions.py +48 -0
  78. iam_validator/sdk/helpers.py +177 -0
  79. iam_validator/sdk/policy_utils.py +425 -0
  80. iam_validator/sdk/shortcuts.py +283 -0
  81. iam_validator/utils/__init__.py +31 -0
  82. iam_validator/utils/cache.py +105 -0
  83. iam_validator/utils/regex.py +206 -0
@@ -0,0 +1,134 @@
1
+ """Command-line interface for IAM Policy Validator."""
2
+
3
+ import argparse
4
+ import asyncio
5
+ import logging
6
+ import os
7
+ import sys
8
+
9
+ from iam_validator.__version__ import __version__
10
+ from iam_validator.commands import ALL_COMMANDS
11
+
12
+
13
+ def setup_logging(log_level: str | None = None, verbose: bool = False) -> None:
14
+ """Setup logging configuration.
15
+
16
+ Args:
17
+ log_level: Log level from CLI argument (debug, info, warning, error, critical)
18
+ verbose: Enable verbose logging (deprecated, use --log-level debug instead)
19
+
20
+ Environment Variables:
21
+ LOG_LEVEL: Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
22
+
23
+ Priority:
24
+ 1. --log-level CLI argument (highest priority)
25
+ 2. LOG_LEVEL environment variable
26
+ 3. --verbose flag (sets DEBUG level)
27
+ 4. Default: WARNING (lowest priority)
28
+ """
29
+ # Check for LOG_LEVEL environment variable
30
+ env_log_level = os.getenv("LOG_LEVEL", "").upper()
31
+
32
+ # Map string to logging level
33
+ level_map = {
34
+ "DEBUG": logging.DEBUG,
35
+ "INFO": logging.INFO,
36
+ "WARNING": logging.WARNING,
37
+ "ERROR": logging.ERROR,
38
+ "CRITICAL": logging.CRITICAL,
39
+ }
40
+
41
+ # Priority: CLI --log-level > LOG_LEVEL env var > --verbose flag > default (WARNING)
42
+ if log_level:
43
+ level = level_map[log_level.upper()]
44
+ elif env_log_level in level_map:
45
+ level = level_map[env_log_level]
46
+ elif verbose:
47
+ level = logging.DEBUG
48
+ else:
49
+ level = logging.WARNING
50
+
51
+ logging.basicConfig(
52
+ level=level,
53
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
54
+ datefmt="%Y-%m-%d %H:%M:%S",
55
+ )
56
+
57
+
58
+ def main() -> int:
59
+ """Main entry point for the CLI.
60
+
61
+ Returns:
62
+ Exit code
63
+ """
64
+ parser = argparse.ArgumentParser(
65
+ description="Validate AWS IAM policies for correctness and security",
66
+ formatter_class=argparse.RawDescriptionHelpFormatter,
67
+ )
68
+
69
+ # Add version argument
70
+ parser.add_argument(
71
+ "--version",
72
+ action="version",
73
+ version=f"iam-validator {__version__}",
74
+ help="Show version information and exit",
75
+ )
76
+
77
+ # Add global log level argument
78
+ parser.add_argument(
79
+ "--log-level",
80
+ choices=["debug", "info", "warning", "error", "critical"],
81
+ default=None,
82
+ help="Set logging level (default: warning)",
83
+ )
84
+
85
+ subparsers = parser.add_subparsers(dest="command", help="Command to run")
86
+
87
+ # Register all commands
88
+ command_map = {}
89
+ for command in ALL_COMMANDS:
90
+ cmd_parser = subparsers.add_parser(
91
+ command.name,
92
+ help=command.help,
93
+ formatter_class=argparse.RawDescriptionHelpFormatter,
94
+ epilog=command.epilog,
95
+ )
96
+ command.add_arguments(cmd_parser)
97
+ command_map[command.name] = command
98
+
99
+ # Parse arguments
100
+ args = parser.parse_args()
101
+
102
+ if not args.command:
103
+ parser.print_help()
104
+ return 1
105
+
106
+ # Setup logging
107
+ log_level = getattr(args, "log_level", None)
108
+ verbose = getattr(args, "verbose", False)
109
+ setup_logging(log_level, verbose)
110
+
111
+ # Execute command
112
+ try:
113
+ command = command_map[args.command]
114
+ exit_code = asyncio.run(command.execute(args))
115
+ return exit_code
116
+ except KeyboardInterrupt:
117
+ logging.warning("Interrupted by user")
118
+ return 130 # Standard exit code for SIGINT
119
+ except asyncio.CancelledError:
120
+ logging.warning("Operation cancelled")
121
+ return 130
122
+ except FileNotFoundError as e:
123
+ logging.error(f"File not found: {e}")
124
+ return 1
125
+ except PermissionError as e:
126
+ logging.error(f"Permission denied: {e}")
127
+ return 1
128
+ except Exception as e:
129
+ logging.error(f"Unexpected error: {e}", exc_info=True)
130
+ return 1
131
+
132
+
133
+ if __name__ == "__main__":
134
+ sys.exit(main())