mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-03-21 18:58:04 +00:00
chore: add provider-uid flag for iac provider (#10233)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
This commit is contained in:
committed by
GitHub
parent
8f3e69f571
commit
012fd84cb0
@@ -38,6 +38,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
- OpenStack block storage service with 7 security checks [(#10120)](https://github.com/prowler-cloud/prowler/pull/10120)
|
||||
- OpenStack compute service with 7 security checks [(#9944)](https://github.com/prowler-cloud/prowler/pull/9944)
|
||||
- OpenStack image service with 6 security checks [(#10096)](https://github.com/prowler-cloud/prowler/pull/10096)
|
||||
- IaC `--provider-uid` flag to specify the provider UID for the IaC provider [(#10233)](https://github.com/prowler-cloud/prowler/pull/10233)
|
||||
|
||||
### 🔄 Changed
|
||||
|
||||
|
||||
@@ -221,7 +221,8 @@ Detailed documentation at https://docs.prowler.com
|
||||
action="store_true",
|
||||
help=(
|
||||
"Send OCSF output to Prowler Cloud ingestion endpoint. "
|
||||
"Requires PROWLER_API_KEY environment variable."
|
||||
"Requires PROWLER_API_KEY environment variable. "
|
||||
"For the IaC provider, --provider-uid is also required."
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -331,8 +331,9 @@ class Finding(BaseModel):
|
||||
|
||||
elif provider.type == "iac":
|
||||
output_data["auth_method"] = provider.auth_method
|
||||
output_data["account_uid"] = "iac"
|
||||
output_data["account_name"] = "iac"
|
||||
provider_uid = getattr(provider, "provider_uid", None)
|
||||
output_data["account_uid"] = provider_uid if provider_uid else "iac"
|
||||
output_data["account_name"] = provider_uid if provider_uid else "iac"
|
||||
output_data["resource_name"] = getattr(
|
||||
check_output, "resource_name", ""
|
||||
)
|
||||
|
||||
@@ -273,6 +273,7 @@ class Provider(ABC):
|
||||
github_username=arguments.github_username,
|
||||
personal_access_token=arguments.personal_access_token,
|
||||
oauth_app_token=arguments.oauth_app_token,
|
||||
provider_uid=arguments.provider_uid,
|
||||
)
|
||||
elif "llm" in provider_class_name.lower():
|
||||
provider_class(
|
||||
|
||||
@@ -38,6 +38,7 @@ class IacProvider(Provider):
|
||||
github_username: str = None,
|
||||
personal_access_token: str = None,
|
||||
oauth_app_token: str = None,
|
||||
provider_uid: str = None,
|
||||
):
|
||||
logger.info("Instantiating IAC Provider...")
|
||||
|
||||
@@ -47,6 +48,7 @@ class IacProvider(Provider):
|
||||
self.exclude_path = exclude_path
|
||||
self.region = "branch"
|
||||
self.audited_account = "local-iac"
|
||||
self._provider_uid = provider_uid
|
||||
self._session = None
|
||||
self._identity = "prowler"
|
||||
self._auth_method = "No auth"
|
||||
@@ -146,6 +148,10 @@ class IacProvider(Provider):
|
||||
def fixer_config(self):
|
||||
return self._fixer_config
|
||||
|
||||
@property
|
||||
def provider_uid(self):
|
||||
return self._provider_uid
|
||||
|
||||
def __del__(self):
|
||||
"""Cleanup temporary directory when provider is destroyed"""
|
||||
self.cleanup()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import re
|
||||
|
||||
SCANNERS_CHOICES = [
|
||||
"vuln",
|
||||
"misconfig",
|
||||
@@ -68,6 +70,12 @@ def init_parser(self):
|
||||
default=None,
|
||||
help="GitHub OAuth app token for authenticated repository cloning. If not provided, will use GITHUB_OAUTH_APP_TOKEN env var.",
|
||||
)
|
||||
iac_scan_subparser.add_argument(
|
||||
"--provider-uid",
|
||||
dest="provider_uid",
|
||||
default=None,
|
||||
help="Unique identifier for the IaC provider. Required when using --export-ocsf.",
|
||||
)
|
||||
|
||||
|
||||
def validate_arguments(arguments):
|
||||
@@ -80,4 +88,19 @@ def validate_arguments(arguments):
|
||||
False,
|
||||
"--scan-path (-P) and --scan-repository-url (-R) are mutually exclusive. Please specify only one.",
|
||||
)
|
||||
export_ocsf = getattr(arguments, "export_ocsf", False)
|
||||
provider_uid = getattr(arguments, "provider_uid", None)
|
||||
if export_ocsf and not provider_uid:
|
||||
return (
|
||||
False,
|
||||
"--provider-uid is required when using --export-ocsf with the IAC provider.",
|
||||
)
|
||||
if provider_uid and not re.match(
|
||||
r"^(https?://|git@|ssh://)[^\s/]+[^\s]*\.git$|^(https?://)[^\s/]+[^\s]*$",
|
||||
provider_uid,
|
||||
):
|
||||
return (
|
||||
False,
|
||||
"--provider-uid must be a valid repository URL (e.g., https://github.com/user/repo or https://github.com/user/repo.git).",
|
||||
)
|
||||
return (True, "")
|
||||
|
||||
@@ -689,6 +689,7 @@ class TestFinding:
|
||||
provider.type = "iac"
|
||||
provider.scan_repository_url = "https://github.com/user/repo"
|
||||
provider.auth_method = "No auth"
|
||||
provider.provider_uid = None
|
||||
|
||||
# Mock check result
|
||||
check_output = MagicMock()
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import types
|
||||
|
||||
from prowler.providers.iac.lib.arguments import arguments as iac_arguments
|
||||
|
||||
Args = types.SimpleNamespace
|
||||
|
||||
|
||||
def test_validate_arguments_mutual_exclusion():
|
||||
from prowler.providers.iac.lib.arguments import arguments as iac_arguments
|
||||
|
||||
Args = types.SimpleNamespace
|
||||
|
||||
# Only scan_path (default)
|
||||
args = Args(scan_path=".", scan_repository_url=None)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
@@ -31,3 +31,90 @@ def test_validate_arguments_mutual_exclusion():
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert valid
|
||||
assert msg == ""
|
||||
|
||||
|
||||
def test_validate_arguments_export_ocsf_requires_provider_uid():
|
||||
# --export-ocsf without provider_uid should fail
|
||||
args = Args(
|
||||
scan_path=".",
|
||||
scan_repository_url=None,
|
||||
export_ocsf=True,
|
||||
provider_uid=None,
|
||||
)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert not valid
|
||||
assert "--provider-uid is required" in msg
|
||||
|
||||
|
||||
def test_validate_arguments_export_ocsf_with_provider_uid_passes():
|
||||
# --export-ocsf with valid provider_uid should pass
|
||||
args = Args(
|
||||
scan_path=".",
|
||||
scan_repository_url=None,
|
||||
export_ocsf=True,
|
||||
provider_uid="https://github.com/user/repo.git",
|
||||
)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert valid
|
||||
assert msg == ""
|
||||
|
||||
|
||||
def test_validate_arguments_no_export_ocsf_without_provider_uid_passes():
|
||||
# No --export-ocsf, no provider_uid — should pass
|
||||
args = Args(
|
||||
scan_path=".",
|
||||
scan_repository_url=None,
|
||||
export_ocsf=False,
|
||||
provider_uid=None,
|
||||
)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert valid
|
||||
assert msg == ""
|
||||
|
||||
# No export_ocsf attr at all — should pass
|
||||
args = Args(scan_path=".", scan_repository_url=None)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert valid
|
||||
assert msg == ""
|
||||
|
||||
|
||||
def test_validate_arguments_provider_uid_must_be_valid_url():
|
||||
# Invalid provider_uid should fail
|
||||
args = Args(
|
||||
scan_path=".",
|
||||
scan_repository_url=None,
|
||||
provider_uid="not-a-url",
|
||||
)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert not valid
|
||||
assert "valid repository URL" in msg
|
||||
|
||||
# HTTPS URL without .git should pass
|
||||
args = Args(
|
||||
scan_path=".",
|
||||
scan_repository_url=None,
|
||||
provider_uid="https://github.com/user/repo",
|
||||
)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert valid
|
||||
assert msg == ""
|
||||
|
||||
# HTTPS URL with .git should pass
|
||||
args = Args(
|
||||
scan_path=".",
|
||||
scan_repository_url=None,
|
||||
provider_uid="https://github.com/user/repo.git",
|
||||
)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert valid
|
||||
assert msg == ""
|
||||
|
||||
# SSH URL should pass
|
||||
args = Args(
|
||||
scan_path=".",
|
||||
scan_repository_url=None,
|
||||
provider_uid="git@github.com:user/repo.git",
|
||||
)
|
||||
valid, msg = iac_arguments.validate_arguments(args)
|
||||
assert valid
|
||||
assert msg == ""
|
||||
|
||||
Reference in New Issue
Block a user