iam-policy-validator 1.9.0__py3-none-any.whl → 1.10.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iam-policy-validator
3
- Version: 1.9.0
3
+ Version: 1.10.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
@@ -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=IUF2zxBY8L_m2_x_tEDJHqdJthjPhXgbZg7CYXJCCrA,361
3
+ iam_validator/__version__.py,sha256=FvUNUrZJC1gRVPHFBok-yxk6rVZGHH_JjnMPCje10kg,362
4
4
  iam_validator/checks/__init__.py,sha256=OTkPnmlelu4YjMO8krjhu2wXiTV72RzopA5u1SfPQA0,1990
5
5
  iam_validator/checks/action_condition_enforcement.py,sha256=0dCH_xX-Xc0uLxtNeRjrpNjWYbdWQRzO1XNcLTSn6sI,51698
6
6
  iam_validator/checks/action_resource_matching.py,sha256=WiGJmCIJfx5yituMjZxpKmk-99N6nK20ueN02ddy9oM,19296
@@ -31,7 +31,7 @@ iam_validator/commands/base.py,sha256=5baCCMwxz7pdQ6XMpWfXFNz7i1l5dB8Qv9dKKR04Gz
31
31
  iam_validator/commands/cache.py,sha256=llfyQzPE5Azd5YcW0ohYcYjF_OCyiQ1GoJQ982t71lQ,14294
32
32
  iam_validator/commands/download_services.py,sha256=KKz3ybMLT8DQUf9aFZ0tilJ-o1b6PE8Pf1pC4K6cT8I,9175
33
33
  iam_validator/commands/post_to_pr.py,sha256=CvUXs2xvO-UhluxdfNM6F0TCWD8hDBEOiYw60fm1Dms,2363
34
- iam_validator/commands/validate.py,sha256=Z6GHLeKV8oINSTXaZ0asBxa56S1G4ORwOBqrAz3Xx-M,23945
34
+ iam_validator/commands/validate.py,sha256=cvrgYagYm7W29MYsitZsLcttIIqVKQMRm-bCGY7N3fU,24355
35
35
  iam_validator/core/__init__.py,sha256=hYXkSbxplKzhM6dqrVzV4M3k7GKLsZbgExypxKq74gs,376
36
36
  iam_validator/core/access_analyzer.py,sha256=mtMaY-FnKjKEVITky_9ywZe1FaCAm61ElRv5Z_ZeC7E,24562
37
37
  iam_validator/core/access_analyzer_report.py,sha256=UMm2RNGj2rAKav1zsCw_htQZZRwRC0jjayd2zvKma1A,24896
@@ -41,10 +41,11 @@ iam_validator/core/cli.py,sha256=PkXiZjlgrQ21QustBbspefYsdbxst4gxoClyG2_HQR8,384
41
41
  iam_validator/core/condition_validators.py,sha256=7zBjlcf2xGFKGbcFrXSLvWT5tFhWxoqwzhsJqS2E8uY,21524
42
42
  iam_validator/core/constants.py,sha256=cVBPgbXr4ALltH_NTSKsgBi6wmndLnOyUWhyBx0ZwrM,6113
43
43
  iam_validator/core/ignore_patterns.py,sha256=pZqDJBtkbck-85QK5eFPM5ZOPEKs3McRh3avqiCT5z0,10398
44
+ iam_validator/core/label_manager.py,sha256=48CRASWg98wyjfVF_1pUzj6dm9itzmG7SeIWf0TSUfc,7502
44
45
  iam_validator/core/models.py,sha256=f5d9ovtO1xMSwhyBrKIgc2psEq0eugnd3S3ioqurqEE,13242
45
46
  iam_validator/core/policy_checks.py,sha256=FNVuS2GTffwCjjrlupVIazC172gSxKYAAT_ObV6Apbo,8803
46
47
  iam_validator/core/policy_loader.py,sha256=2KJnXzGg3g9pDXWZHk3DO0xpZnZZ-wXWFEOdQ_naJ8s,17862
47
- iam_validator/core/pr_commenter.py,sha256=MU-t7SfdHUpSc6BDbh8_dNAbxDiG-bZBCry-jUXivAc,15066
48
+ iam_validator/core/pr_commenter.py,sha256=NTKoSmjvspYX2rbl3Xn8d611XkTNSfYlGUY0zBHBP4g,16801
48
49
  iam_validator/core/report.py,sha256=kzSeWnT1LqWZVA5pqKKz-maVowXVj0djdoShfRhhpz4,35899
49
50
  iam_validator/core/aws_service/__init__.py,sha256=UqMh4HUdGlx2QF5OoueJJ2UlCnhX4QW_x3KeE_bxRQc,735
50
51
  iam_validator/core/aws_service/cache.py,sha256=DPuOOPPJC867KAYgV1e0RyQs_k3mtefMdYli3jPaN64,3589
@@ -60,7 +61,7 @@ iam_validator/core/config/aws_global_conditions.py,sha256=gdmMxXGBy95B3uYUG-J7rn
60
61
  iam_validator/core/config/category_suggestions.py,sha256=QlrYi4BTkxDSTlL7NZGE9BWN-atWetZ6XjkI9F_7YzI,4370
61
62
  iam_validator/core/config/condition_requirements.py,sha256=qauIP73HFnOw1dchUeFpg1x7Y7QWkILo3GfxV_dxdQo,7696
62
63
  iam_validator/core/config/config_loader.py,sha256=qKD8aR8YAswaFf68pnYJLFNwKznvcc6lNxSQWU3i6SY,17713
63
- iam_validator/core/config/defaults.py,sha256=rWzDrlw0AAudtm_If6zjNFvruLg71jpLJEdRgKYSKMQ,27917
64
+ iam_validator/core/config/defaults.py,sha256=qpFP534dgCQ-vjCdhkK7ZslDoTm9Ftgy20qmYZsSYUI,28637
64
65
  iam_validator/core/config/principal_requirements.py,sha256=VCX7fBDgeDTJQyoz7_x7GI7Kf9O1Eu-sbihoHOrKv6o,15105
65
66
  iam_validator/core/config/sensitive_actions.py,sha256=uATDIp_TD3OQQlsYTZp79qd1mSK2Bf9hJ0JwcqLBr84,25344
66
67
  iam_validator/core/config/service_principals.py,sha256=8pys5H_yycVJ9KTyimAKFYBg83Aol2Iri53wiHjtnEM,3959
@@ -88,8 +89,8 @@ iam_validator/utils/__init__.py,sha256=NveA2F3G1E6-ANZzFr7J6Q6u5mogvMp862iFokmYu
88
89
  iam_validator/utils/cache.py,sha256=wOQKOBeoG6QqC5f0oXcHz63Cjtu_-SsSS-0pTSwyAiM,3254
89
90
  iam_validator/utils/regex.py,sha256=xHoMECttb7qaMhts-c9b0GIxdhHNZTt-UBr7wNhWfzg,6219
90
91
  iam_validator/utils/terminal.py,sha256=FsRaRMH_JAyDgXWBCOgOEhbS89cs17HCmKYoughq5io,724
91
- iam_policy_validator-1.9.0.dist-info/METADATA,sha256=y2uizxt2ScM8UTUd1UPHqkazCKhTMdyzVGKFEJQqc18,19069
92
- iam_policy_validator-1.9.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- iam_policy_validator-1.9.0.dist-info/entry_points.txt,sha256=8HtWd8O7mvPiPdZR5YbzY8or_qcqLM4-pKaFdhtFT8M,62
94
- iam_policy_validator-1.9.0.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
95
- iam_policy_validator-1.9.0.dist-info/RECORD,,
92
+ iam_policy_validator-1.10.0.dist-info/METADATA,sha256=ksZBI5NOZxypD5leqm2BSUOnak43V9EeLBOw1XoLXd0,19070
93
+ iam_policy_validator-1.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
+ iam_policy_validator-1.10.0.dist-info/entry_points.txt,sha256=8HtWd8O7mvPiPdZR5YbzY8or_qcqLM4-pKaFdhtFT8M,62
95
+ iam_policy_validator-1.10.0.dist-info/licenses/LICENSE,sha256=AMnbFTBDcK4_MITe2wiQBkj0vg-jjBBhsc43ydC7tt4,1098
96
+ iam_policy_validator-1.10.0.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.9.0"
6
+ __version__ = "1.10.0"
7
7
  # Parse version, handling pre-release suffixes like -rc, -alpha, -beta
8
8
  _version_base = __version__.split("-")[0] # Remove pre-release suffix if present
9
9
  __version_info__ = tuple(int(part) for part in _version_base.split("."))
@@ -302,12 +302,17 @@ Examples:
302
302
  from iam_validator.core.config.config_loader import ConfigLoader
303
303
  from iam_validator.core.pr_commenter import PRCommenter
304
304
 
305
- # Load config to get fail_on_severity setting
305
+ # Load config to get fail_on_severity and severity_labels settings
306
306
  config = ConfigLoader.load_config(config_path)
307
307
  fail_on_severities = config.get_setting("fail_on_severity", ["error", "critical"])
308
+ severity_labels = config.get_setting("severity_labels", {})
308
309
 
309
310
  async with GitHubIntegration() as github:
310
- commenter = PRCommenter(github, fail_on_severities=fail_on_severities)
311
+ commenter = PRCommenter(
312
+ github,
313
+ fail_on_severities=fail_on_severities,
314
+ severity_labels=severity_labels,
315
+ )
311
316
  success = await commenter.post_findings_to_pr(
312
317
  report,
313
318
  create_review=getattr(args, "github_review", False),
@@ -426,12 +431,17 @@ Examples:
426
431
  from iam_validator.core.config.config_loader import ConfigLoader
427
432
  from iam_validator.core.pr_commenter import PRCommenter
428
433
 
429
- # Load config to get fail_on_severity setting
434
+ # Load config to get fail_on_severity and severity_labels settings
430
435
  config = ConfigLoader.load_config(config_path)
431
436
  fail_on_severities = config.get_setting("fail_on_severity", ["error", "critical"])
437
+ severity_labels = config.get_setting("severity_labels", {})
432
438
 
433
439
  async with GitHubIntegration() as github:
434
- commenter = PRCommenter(github, fail_on_severities=fail_on_severities)
440
+ commenter = PRCommenter(
441
+ github,
442
+ fail_on_severities=fail_on_severities,
443
+ severity_labels=severity_labels,
444
+ )
435
445
  success = await commenter.post_findings_to_pr(
436
446
  report,
437
447
  create_review=False, # Already posted per-file reviews in streaming mode
@@ -75,6 +75,16 @@ DEFAULT_CONFIG = {
75
75
  # IAM Validity: error, warning, info
76
76
  # Security: critical, high, medium, low
77
77
  "fail_on_severity": list(constants.HIGH_SEVERITY_LEVELS),
78
+ # GitHub PR label mapping based on severity findings
79
+ # When issues with these severities are found, apply the corresponding labels
80
+ # If no issues with these severities exist, remove the labels if present
81
+ # Supports both single labels and lists of labels per severity
82
+ # Examples:
83
+ # Single label per severity: {"error": "iam-validity-error", "critical": "security-critical"}
84
+ # Multiple labels per severity: {"error": ["iam-error", "needs-fix"], "critical": ["security-critical", "needs-review"]}
85
+ # Mixed: {"error": "iam-validity-error", "critical": ["security-critical", "needs-review"]}
86
+ # Default: {} (disabled)
87
+ "severity_labels": {},
78
88
  },
79
89
  # ========================================================================
80
90
  # AWS IAM Validation Checks (17 checks total)
@@ -0,0 +1,197 @@
1
+ """Label Manager for GitHub PR Labels based on Severity Findings.
2
+
3
+ This module manages GitHub PR labels based on IAM policy validation severity findings.
4
+ When validation finds issues with specific severities, it applies corresponding labels.
5
+ When those severities are not found, it removes the labels if present.
6
+ """
7
+
8
+ import logging
9
+ from typing import TYPE_CHECKING
10
+
11
+ if TYPE_CHECKING:
12
+ from iam_validator.core.models import PolicyValidationResult, ValidationReport
13
+ from iam_validator.integrations.github_integration import GitHubIntegration
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class LabelManager:
19
+ """Manages GitHub PR labels based on severity findings."""
20
+
21
+ def __init__(
22
+ self,
23
+ github: "GitHubIntegration",
24
+ severity_labels: dict[str, str | list[str]] | None = None,
25
+ ):
26
+ """Initialize label manager.
27
+
28
+ Args:
29
+ github: GitHubIntegration instance for API calls
30
+ severity_labels: Mapping of severity levels to label name(s)
31
+ Supports both single labels and lists of labels per severity.
32
+ Examples:
33
+ - Single label per severity:
34
+ {"error": "iam-validity-error", "critical": "security-critical"}
35
+ - Multiple labels per severity:
36
+ {"error": ["iam-error", "needs-fix"], "critical": ["security-critical", "needs-security-review"]}
37
+ - Mixed:
38
+ {"error": "iam-validity-error", "critical": ["security-critical", "needs-review"]}
39
+ """
40
+ self.github = github
41
+ self.severity_labels = severity_labels or {}
42
+
43
+ def is_enabled(self) -> bool:
44
+ """Check if label management is enabled.
45
+
46
+ Returns:
47
+ True if severity_labels is configured and GitHub is configured
48
+ """
49
+ return bool(self.severity_labels) and self.github.is_configured()
50
+
51
+ def _get_severities_in_results(self, results: list["PolicyValidationResult"]) -> set[str]:
52
+ """Extract all severity levels found in validation results.
53
+
54
+ Args:
55
+ results: List of PolicyValidationResult objects
56
+
57
+ Returns:
58
+ Set of severity levels found (e.g., {"error", "critical", "high"})
59
+ """
60
+ severities = set()
61
+ for result in results:
62
+ for issue in result.issues:
63
+ severities.add(issue.severity)
64
+ return severities
65
+
66
+ def _get_severities_in_report(self, report: "ValidationReport") -> set[str]:
67
+ """Extract all severity levels found in validation report.
68
+
69
+ Args:
70
+ report: ValidationReport object
71
+
72
+ Returns:
73
+ Set of severity levels found (e.g., {"error", "critical", "high"})
74
+ """
75
+ return self._get_severities_in_results(report.results)
76
+
77
+ def _determine_labels_to_apply(self, found_severities: set[str]) -> set[str]:
78
+ """Determine which labels should be applied based on found severities.
79
+
80
+ Args:
81
+ found_severities: Set of severity levels found in validation
82
+
83
+ Returns:
84
+ Set of label names to apply
85
+ """
86
+ labels_to_apply = set()
87
+ for severity, labels in self.severity_labels.items():
88
+ if severity in found_severities:
89
+ # Support both single labels and lists of labels
90
+ if isinstance(labels, list):
91
+ labels_to_apply.update(labels)
92
+ else:
93
+ labels_to_apply.add(labels)
94
+ return labels_to_apply
95
+
96
+ def _determine_labels_to_remove(self, found_severities: set[str]) -> set[str]:
97
+ """Determine which labels should be removed based on missing severities.
98
+
99
+ Args:
100
+ found_severities: Set of severity levels found in validation
101
+
102
+ Returns:
103
+ Set of label names to remove
104
+ """
105
+ labels_to_remove = set()
106
+ for severity, labels in self.severity_labels.items():
107
+ if severity not in found_severities:
108
+ # Support both single labels and lists of labels
109
+ if isinstance(labels, list):
110
+ labels_to_remove.update(labels)
111
+ else:
112
+ labels_to_remove.add(labels)
113
+ return labels_to_remove
114
+
115
+ async def manage_labels_from_results(
116
+ self, results: list["PolicyValidationResult"]
117
+ ) -> tuple[bool, int, int]:
118
+ """Manage PR labels based on validation results.
119
+
120
+ This method will:
121
+ 1. Determine which severity levels are present in the results
122
+ 2. Add labels for severities that are found
123
+ 3. Remove labels for severities that are not found
124
+
125
+ Args:
126
+ results: List of PolicyValidationResult objects
127
+
128
+ Returns:
129
+ Tuple of (success, labels_added, labels_removed)
130
+ """
131
+ if not self.is_enabled():
132
+ logger.debug("Label management not enabled (no severity_labels configured)")
133
+ return (True, 0, 0)
134
+
135
+ # Get all severities found in results
136
+ found_severities = self._get_severities_in_results(results)
137
+ logger.debug(f"Found severities in results: {found_severities}")
138
+
139
+ # Determine which labels to apply/remove
140
+ labels_to_apply = self._determine_labels_to_apply(found_severities)
141
+ labels_to_remove = self._determine_labels_to_remove(found_severities)
142
+
143
+ logger.debug(f"Labels to apply: {labels_to_apply}")
144
+ logger.debug(f"Labels to remove: {labels_to_remove}")
145
+
146
+ # Get current labels on PR
147
+ current_labels = set(await self.github.get_labels())
148
+ logger.debug(f"Current PR labels: {current_labels}")
149
+
150
+ # Filter: only add labels that aren't already present
151
+ labels_to_add = labels_to_apply - current_labels
152
+
153
+ # Filter: only remove labels that are currently present
154
+ labels_to_actually_remove = labels_to_remove & current_labels
155
+
156
+ success = True
157
+ added_count = 0
158
+ removed_count = 0
159
+
160
+ # Add new labels
161
+ if labels_to_add:
162
+ logger.info(f"Adding labels to PR: {labels_to_add}")
163
+ if await self.github.add_labels(list(labels_to_add)):
164
+ added_count = len(labels_to_add)
165
+ else:
166
+ logger.error("Failed to add labels to PR")
167
+ success = False
168
+
169
+ # Remove old labels
170
+ for label in labels_to_actually_remove:
171
+ logger.info(f"Removing label from PR: {label}")
172
+ if await self.github.remove_label(label):
173
+ removed_count += 1
174
+ else:
175
+ logger.error(f"Failed to remove label: {label}")
176
+ success = False
177
+
178
+ if added_count > 0 or removed_count > 0:
179
+ logger.info(f"Label management complete: added {added_count}, removed {removed_count}")
180
+ else:
181
+ logger.debug("No label changes needed")
182
+
183
+ return (success, added_count, removed_count)
184
+
185
+ async def manage_labels_from_report(self, report: "ValidationReport") -> tuple[bool, int, int]:
186
+ """Manage PR labels based on validation report.
187
+
188
+ This is a convenience method that extracts results from the report
189
+ and calls manage_labels_from_results().
190
+
191
+ Args:
192
+ report: ValidationReport object
193
+
194
+ Returns:
195
+ Tuple of (success, labels_added, labels_removed)
196
+ """
197
+ return await self.manage_labels_from_results(report.results)
@@ -13,7 +13,9 @@ from iam_validator.core.constants import (
13
13
  REVIEW_IDENTIFIER,
14
14
  SUMMARY_IDENTIFIER,
15
15
  )
16
+ from iam_validator.core.label_manager import LabelManager
16
17
  from iam_validator.core.models import ValidationIssue, ValidationReport
18
+ from iam_validator.core.report import ReportGenerator
17
19
  from iam_validator.integrations.github_integration import GitHubIntegration, ReviewEvent
18
20
 
19
21
  logger = logging.getLogger(__name__)
@@ -32,6 +34,7 @@ class PRCommenter:
32
34
  github: GitHubIntegration | None = None,
33
35
  cleanup_old_comments: bool = True,
34
36
  fail_on_severities: list[str] | None = None,
37
+ severity_labels: dict[str, str | list[str]] | None = None,
35
38
  ):
36
39
  """Initialize PR commenter.
37
40
 
@@ -40,16 +43,24 @@ class PRCommenter:
40
43
  cleanup_old_comments: Whether to clean up old bot comments before posting new ones
41
44
  fail_on_severities: List of severity levels that should trigger REQUEST_CHANGES
42
45
  (e.g., ["error", "critical", "high"])
46
+ severity_labels: Mapping of severity levels to label name(s) for automatic label management
47
+ Supports both single labels and lists of labels per severity.
48
+ Examples:
49
+ - Single: {"error": "iam-validity-error", "critical": "security-critical"}
50
+ - Multiple: {"error": ["iam-error", "needs-fix"], "critical": ["security-critical", "needs-review"]}
51
+ - Mixed: {"error": "iam-validity-error", "critical": ["security-critical", "needs-review"]}
43
52
  """
44
53
  self.github = github
45
54
  self.cleanup_old_comments = cleanup_old_comments
46
55
  self.fail_on_severities = fail_on_severities or ["error", "critical"]
56
+ self.severity_labels = severity_labels or {}
47
57
 
48
58
  async def post_findings_to_pr(
49
59
  self,
50
60
  report: ValidationReport,
51
61
  create_review: bool = True,
52
62
  add_summary_comment: bool = True,
63
+ manage_labels: bool = True,
53
64
  ) -> bool:
54
65
  """Post validation findings to a PR.
55
66
 
@@ -57,6 +68,7 @@ class PRCommenter:
57
68
  report: Validation report with findings
58
69
  create_review: Whether to create a PR review with line comments
59
70
  add_summary_comment: Whether to add a summary comment
71
+ manage_labels: Whether to manage PR labels based on severity findings
60
72
 
61
73
  Returns:
62
74
  True if successful, False otherwise
@@ -81,8 +93,6 @@ class PRCommenter:
81
93
 
82
94
  # Post summary comment (potentially as multiple parts)
83
95
  if add_summary_comment:
84
- from iam_validator.core.report import ReportGenerator
85
-
86
96
  generator = ReportGenerator()
87
97
  comment_parts = generator.generate_github_comment_parts(report)
88
98
 
@@ -104,6 +114,18 @@ class PRCommenter:
104
114
  logger.error("Failed to post review comments")
105
115
  success = False
106
116
 
117
+ # Manage PR labels based on severity findings
118
+ if manage_labels and self.severity_labels:
119
+ label_manager = LabelManager(self.github, self.severity_labels)
120
+ label_success, added, removed = await label_manager.manage_labels_from_report(report)
121
+
122
+ if not label_success:
123
+ logger.error("Failed to manage PR labels")
124
+ success = False
125
+ else:
126
+ if added > 0 or removed > 0:
127
+ logger.info(f"Label management: added {added}, removed {removed}")
128
+
107
129
  return success
108
130
 
109
131
  async def _post_review_comments(self, report: ValidationReport) -> bool:
@@ -288,7 +310,7 @@ class PRCommenter:
288
310
 
289
311
  return mapping
290
312
 
291
- except Exception as e:
313
+ except Exception as e: # pylint: disable=broad-exception-caught
292
314
  logger.warning(f"Could not parse {policy_file} for line mapping: {e}")
293
315
  return {}
294
316
 
@@ -369,7 +391,7 @@ class PRCommenter:
369
391
 
370
392
  return None
371
393
 
372
- except Exception as e:
394
+ except Exception as e: # pylint: disable=broad-exception-caught
373
395
  logger.debug(f"Could not search {policy_file}: {e}")
374
396
  return None
375
397
 
@@ -398,15 +420,20 @@ async def post_report_to_pr(
398
420
 
399
421
  report = ValidationReport.model_validate(report_data)
400
422
 
401
- # Load config to get fail_on_severity setting
423
+ # Load config to get fail_on_severity and severity_labels settings
402
424
  from iam_validator.core.config.config_loader import ConfigLoader
403
425
 
404
426
  config = ConfigLoader.load_config(config_path)
405
427
  fail_on_severities = config.get_setting("fail_on_severity", ["error", "critical"])
428
+ severity_labels = config.get_setting("severity_labels", {})
406
429
 
407
430
  # Post to PR
408
431
  async with GitHubIntegration() as github:
409
- commenter = PRCommenter(github, fail_on_severities=fail_on_severities)
432
+ commenter = PRCommenter(
433
+ github,
434
+ fail_on_severities=fail_on_severities,
435
+ severity_labels=severity_labels,
436
+ )
410
437
  return await commenter.post_findings_to_pr(
411
438
  report,
412
439
  create_review=create_review,
@@ -419,6 +446,6 @@ async def post_report_to_pr(
419
446
  except json.JSONDecodeError as e:
420
447
  logger.error(f"Invalid JSON in report file: {e}")
421
448
  return False
422
- except Exception as e:
449
+ except Exception as e: # pylint: disable=broad-exception-caught
423
450
  logger.error(f"Failed to post report to PR: {e}")
424
451
  return False