11from typing import List
22
3- from prowler .lib .check .models import Check , CheckReportGithub
3+ from prowler .lib .check .models import Check , CheckReportGithub , Severity
44from prowler .providers .github .services .organization .organization_client import (
55 organization_client ,
66)
@@ -15,8 +15,19 @@ def _join_human_readable(items: List[str]) -> str:
1515 return ", " .join (items [:- 1 ]) + f" and { items [- 1 ]} "
1616
1717
18+ PUBLIC_CREATION_TYPES = {"all" , "public" }
19+ NON_PUBLIC_CREATION_TYPES = {"private" , "internal" }
20+ PUBLIC_DISABLED_CREATION_TYPES = NON_PUBLIC_CREATION_TYPES | {"none" }
21+ KNOWN_CREATION_TYPES = PUBLIC_CREATION_TYPES | PUBLIC_DISABLED_CREATION_TYPES
22+
23+
1824class organization_repository_creation_limited (Check ):
19- """Check if repository creation is limited to trusted organization members."""
25+ """Check if repository creation is limited to trusted organization members.
26+
27+ FAIL severity scales with the visibility members can create: high when public
28+ repository creation is (or may be) allowed, low when it is provably limited to
29+ private/internal repositories.
30+ """
2031
2132 def execute (self ) -> List [CheckReportGithub ]:
2233 findings = []
@@ -48,12 +59,19 @@ def execute(self) -> List[CheckReportGithub]:
4859 org , "members_allowed_repository_creation_type" , None
4960 )
5061
62+ normalized_type = creation_type .lower () if creation_type else ""
63+
5164 type_flags = []
5265 enabled_types = []
5366
5467 if global_creation is not None :
5568 if global_creation :
56- enabled_types .append ("repositories of any type" )
69+ public_known_disabled = (
70+ public_creation is False
71+ or normalized_type in PUBLIC_DISABLED_CREATION_TYPES
72+ )
73+ if not public_known_disabled :
74+ enabled_types .append ("repositories of any type" )
5775 else :
5876 type_flags .append (False )
5977
@@ -70,7 +88,6 @@ def execute(self) -> List[CheckReportGithub]:
7088 enabled_types .append (label )
7189
7290 if creation_type :
73- normalized_type = creation_type .lower ()
7491 if normalized_type == "none" :
7592 type_flags .append (False )
7693 else :
@@ -97,7 +114,28 @@ def execute(self) -> List[CheckReportGithub]:
97114 unique_enabled = list (dict .fromkeys (enabled_types ))
98115 allowed_desc = _join_human_readable (unique_enabled )
99116 if allowed_desc :
100- report .status_extended = f"Organization { org .name } allows members to create { allowed_desc } ."
117+ public_allowed = (
118+ public_creation is True
119+ or normalized_type in PUBLIC_CREATION_TYPES
120+ )
121+ non_public_allowed = (
122+ private_creation is True
123+ or internal_creation is True
124+ or normalized_type in NON_PUBLIC_CREATION_TYPES
125+ )
126+ public_known = (
127+ public_creation is not None
128+ or normalized_type in KNOWN_CREATION_TYPES
129+ )
130+
131+ if not public_allowed and non_public_allowed and public_known :
132+ report .check_metadata .Severity = Severity .low
133+ report .status_extended = (
134+ f"Organization { org .name } allows members to create { allowed_desc } . "
135+ "Public repository creation is disabled."
136+ )
137+ else :
138+ report .status_extended = f"Organization { org .name } allows members to create { allowed_desc } ."
101139 else :
102140 report .status_extended = f"Organization { org .name } does not have enough data to confirm repository creation restrictions."
103141
0 commit comments