+
+
+???+ note "User creation and default tenant behavior"
+
+ When creating a new user, the behavior depends on whether an invitation is provided:
+
+ - **Without an invitation**:
+
+ - A new tenant is automatically created.
+ - The new user is assigned to this tenant.
+ - A set of **RBAC admin permissions** is generated and assigned to the user for the newly-created tenant.
+
+ - **With an invitation**: The user is added to the specified tenant with the permissions defined in the invitation.
+
+ This mechanism ensures that the first user in a newly created tenant has administrative permissions within that tenant.
+
+## Log In
+
+Access Prowler App by logging in with **email and password**.
+
+
+
+## Add Cloud Provider
+
+Configure a cloud provider for scanning:
+
+1. Navigate to `Settings > Cloud Providers` and click `Add Account`.
+2. Select the cloud provider.
+3. Enter the provider's identifier (Optional: Add an alias):
+ - **AWS**: Account ID
+ - **GCP**: Project ID
+ - **Azure**: Subscription ID
+ - **Kubernetes**: Cluster ID
+ - **M365**: Domain ID
+4. Follow the guided instructions to add and authenticate your credentials.
+
+## Start a Scan
+
+Once credentials are successfully added and validated, Prowler initiates a scan of your cloud environment.
+
+Click `Go to Scans` to monitor progress.
+
+## View Results
+
+Review findings during scan execution in the following sections:
+
+- **Overview** – Provides a high-level summary of your scans.
+
+
+- **Compliance** – Displays compliance insights based on security frameworks.
+
+
+> For detailed usage instructions, refer to the [Prowler App Guide](../tutorials/prowler-app.md).
+
+???+ note
+ Prowler will automatically scan all configured providers every **24 hours**, ensuring your cloud environment stays continuously monitored.
diff --git a/docs/basic-usage/prowler-cli.md b/docs/basic-usage/prowler-cli.md
new file mode 100644
index 0000000000..0c093968b4
--- /dev/null
+++ b/docs/basic-usage/prowler-cli.md
@@ -0,0 +1,257 @@
+## Running Prowler
+
+Running Prowler requires specifying the provider (e.g `aws`, `gcp`, `azure`, `m365`, `github` or `kubernetes`):
+
+???+ note
+ If no provider is specified, AWS is used by default for backward compatibility with Prowler v2.
+
+```console
+prowler
-
-
-???+ note "User creation and default tenant behavior"
-
- When creating a new user, the behavior depends on whether an invitation is provided:
-
- - **Without an invitation**:
-
- - A new tenant is automatically created.
- - The new user is assigned to this tenant.
- - A set of **RBAC admin permissions** is generated and assigned to the user for the newly-created tenant.
-
- - **With an invitation**: The user is added to the specified tenant with the permissions defined in the invitation.
-
- This mechanism ensures that the first user in a newly created tenant has administrative permissions within that tenant.
-
-#### Log In
-
-Log in using your **email and password** to access the Prowler App.
-
-
-
-#### Add a Cloud Provider
-
-To configure a cloud provider for scanning:
-
-1. Navigate to `Settings > Cloud Providers` and click `Add Account`.
-2. Select the cloud provider you wish to scan (**AWS, GCP, Azure, Kubernetes**).
-3. Enter the provider's identifier (Optional: Add an alias):
- - **AWS**: Account ID
- - **GCP**: Project ID
- - **Azure**: Subscription ID
- - **Kubernetes**: Cluster ID
- - **M36**: Domain ID
-4. Follow the guided instructions to add and authenticate your credentials.
-
-#### Start a Scan
-
-Once credentials are successfully added and validated, Prowler initiates a scan of your cloud environment.
-
-Click `Go to Scans` to monitor progress.
-
-#### View Results
-
-While the scan is running, you can review findings in the following sections:
-
-- **Overview** – Provides a high-level summary of your scans.
-
-
-- **Compliance** – Displays compliance insights based on security frameworks.
-
-
-> For detailed usage instructions, refer to the [Prowler App Guide](tutorials/prowler-app.md).
-
-???+ note
- Prowler will automatically scan all configured providers every **24 hours**, ensuring your cloud environment stays continuously monitored.
-
-### Prowler CLI
-
-#### Running Prowler
-
-To run Prowler, you will need to specify the provider (e.g `aws`, `gcp`, `azure`, `m365`, `github` or `kubernetes`):
-
-???+ note
- If no provider is specified, AWS is used by default for backward compatibility with Prowler v2.
-
-```console
-prowler
diff --git a/mkdocs.yml b/mkdocs.yml
index d40600452d..68aa34bcc6 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -46,8 +46,19 @@ repo_name: prowler-cloud/prowler
nav:
- Getting Started:
- - Overview: index.md
- - Requirements: getting-started/requirements.md
+ - Overview:
+ - What is Prowler?: index.md
+ - Products:
+ - Prowler App: products/prowler-app.md
+ - Prowler CLI: products/prowler-cli.md
+ - Prowler Cloud 🔗: https://cloud.prowler.com
+ - Prowler Hub 🔗: https://hub.prowler.com
+ - Installation:
+ - Prowler App: installation/prowler-app.md
+ - Prowler CLI: installation/prowler-cli.md
+ - Basic Usage:
+ - Prowler App: basic-usage/prowler-app.md
+ - Prowler CLI: basic-usage/prowler-cli.md
- Tutorials:
- Prowler App:
- Getting Started: tutorials/prowler-app.md
@@ -57,6 +68,7 @@ nav:
- Mute findings: tutorials/prowler-app-mute-findings.md
- Amazon S3 Integration: tutorials/prowler-app-s3-integration.md
- Lighthouse: tutorials/prowler-app-lighthouse.md
+ - Bulk Provider Provisioning: tutorials/bulk-provider-provisioning.md
- CLI:
- Miscellaneous: tutorials/misc.md
- Reporting: tutorials/reporting.md
@@ -111,12 +123,13 @@ nav:
- Authentication: tutorials/microsoft365/authentication.md
- Use of PowerShell: tutorials/microsoft365/use-of-powershell.md
- GitHub:
- - Authentication: tutorials/github/authentication.md
- Getting Started: tutorials/github/getting-started-github.md
+ - Authentication: tutorials/github/authentication.md
- IaC:
- Getting Started: tutorials/iac/getting-started-iac.md
+ - Authentication: tutorials/iac/authentication.md
- Developer Guide:
- - General Concepts:
+ - Concepts:
- Introduction: developer-guide/introduction.md
- Providers: developer-guide/provider.md
- Services: developer-guide/services.md
@@ -125,7 +138,7 @@ nav:
- Integrations: developer-guide/integrations.md
- Compliance: developer-guide/security-compliance-framework.md
- Lighthouse: developer-guide/lighthouse.md
- - Provider Specific Details:
+ - Providers:
- AWS: developer-guide/aws-details.md
- Azure: developer-guide/azure-details.md
- Google Cloud: developer-guide/gcp-details.md
@@ -142,8 +155,8 @@ nav:
- Security: security.md
- Contact Us: contact.md
- Troubleshooting: troubleshooting.md
- - About: about.md
- - Prowler Cloud: https://prowler.com
+ - About 🔗: https://prowler.com/about#team
+ - Release Notes 🔗: https://github.com/prowler-cloud/prowler/releases
# Customization
extra:
diff --git a/poetry.lock b/poetry.lock
index 55f31ad3da..ab1e7d5e4c 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -2060,14 +2060,14 @@ files = [
[[package]]
name = "h2"
-version = "4.2.0"
+version = "4.3.0"
description = "Pure-Python HTTP/2 protocol implementation"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
- {file = "h2-4.2.0-py3-none-any.whl", hash = "sha256:479a53ad425bb29af087f3458a61d30780bc818e4ebcf01f0b536ba916462ed0"},
- {file = "h2-4.2.0.tar.gz", hash = "sha256:c8a52129695e88b1a0578d8d2cc6842bbd79128ac685463b887ee278126ad01f"},
+ {file = "h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd"},
+ {file = "h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1"},
]
[package.dependencies]
@@ -2352,6 +2352,8 @@ python-versions = "*"
groups = ["dev"]
files = [
{file = "jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"},
+ {file = "jsonpath_ng-1.7.0-py2-none-any.whl", hash = "sha256:898c93fc173f0c336784a3fa63d7434297544b7198124a68f9a3ef9597b0ae6e"},
+ {file = "jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6"},
]
[package.dependencies]
@@ -5839,4 +5841,4 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.1"
python-versions = ">3.9.1,<3.13"
-content-hash = "a0635a7bb99427a5169b126b429d603079fc24c39ce6759a648fdffe74e50d6c"
+content-hash = "fdd2cbdb6913d0dd8d05030ee41c0d36d3954e473783d43b730ec163e697ec15"
diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md
index a93d5a0e8a..94cb8ccc05 100644
--- a/prowler/CHANGELOG.md
+++ b/prowler/CHANGELOG.md
@@ -9,14 +9,21 @@ All notable changes to the **Prowler SDK** are documented in this file.
- `vm_sufficient_daily_backup_retention_period` check for Azure provider [(#8200)](https://github.com/prowler-cloud/prowler/pull/8200)
- `vm_jit_access_enabled` check for Azure provider [(#8202)](https://github.com/prowler-cloud/prowler/pull/8202)
- Bedrock AgentCore privilege escalation combination for AWS provider [(#8526)](https://github.com/prowler-cloud/prowler/pull/8526)
+- Add User Email and APP name/installations information in GitHub provider [(#8501)](https://github.com/prowler-cloud/prowler/pull/8501)
- Remove standalone iam:PassRole from privesc detection and add missing patterns [(#8530)](https://github.com/prowler-cloud/prowler/pull/8530)
+- Support session/profile/role/static credentials in Security Hub integration [(#8539)](https://github.com/prowler-cloud/prowler/pull/8539)
- `eks_cluster_deletion_protection_enabled` check for AWS provider [(#8536)](https://github.com/prowler-cloud/prowler/pull/8536)
+- ECS privilege escalation patterns (StartTask and RunTask) for AWS provider [(#8541)](https://github.com/prowler-cloud/prowler/pull/8541)
+- Resource Explorer enumeration v2 API actions in `cloudtrail_threat_detection_enumeration` check [(#8557)](https://github.com/prowler-cloud/prowler/pull/8557)
+
### Changed
- Refine kisa isms-p compliance mapping [(#8479)](https://github.com/prowler-cloud/prowler/pull/8479)
- Update AWS Neptune service metadata to new format [(#8494)](https://github.com/prowler-cloud/prowler/pull/8494)
+- Improve AWS Security Hub region check using multiple threads [(#8365)](https://github.com/prowler-cloud/prowler/pull/8365)
### Fixed
+- Resource metadata error in `s3_bucket_shadow_resource_vulnerability` check [(#8572)](https://github.com/prowler-cloud/prowler/pull/8572)
---
@@ -25,6 +32,9 @@ All notable changes to the **Prowler SDK** are documented in this file.
### Fixed
- AWS resource-arn filtering [(#8533)](https://github.com/prowler-cloud/prowler/pull/8533)
- GitHub App authentication for GitHub provider [(#8529)](https://github.com/prowler-cloud/prowler/pull/8529)
+- List all accessible organizations in GitHub provider [(#8535)](https://github.com/prowler-cloud/prowler/pull/8535)
+- Only evaluate enabled accounts in `entra_users_mfa_capable` check [(#8544)](https://github.com/prowler-cloud/prowler/pull/8544)
+- GitHub Personal Access Token authentication fails without `user:email` scope [(#8580)](https://github.com/prowler-cloud/prowler/pull/8580)
---
@@ -61,6 +71,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- GitHub repository and organization scoping support with `--repository/respositories` and `--organization/organizations` flags [(#8329)](https://github.com/prowler-cloud/prowler/pull/8329)
- GCP provider retry configuration [(#8412)](https://github.com/prowler-cloud/prowler/pull/8412)
- `s3_bucket_shadow_resource_vulnerability` check for AWS provider [(#8398)](https://github.com/prowler-cloud/prowler/pull/8398)
+- Use `trivy` as engine for IaC provider [(#8466)](https://github.com/prowler-cloud/prowler/pull/8466)
### Changed
- Handle some AWS errors as warnings instead of errors [(#8347)](https://github.com/prowler-cloud/prowler/pull/8347)
diff --git a/prowler/lib/check/checks_loader.py b/prowler/lib/check/checks_loader.py
index 3c7e065fc0..c03034b0e4 100644
--- a/prowler/lib/check/checks_loader.py
+++ b/prowler/lib/check/checks_loader.py
@@ -20,7 +20,7 @@ def load_checks_to_execute(
) -> set:
"""Generate the list of checks to execute based on the cloud provider and the input arguments given"""
try:
- # Bypass check loading for IAC provider since it uses Checkov directly
+ # Bypass check loading for IAC provider since it uses Trivy directly
if provider == "iac":
return set()
diff --git a/prowler/lib/check/models.py b/prowler/lib/check/models.py
index 1c2dd44533..de38162cbc 100644
--- a/prowler/lib/check/models.py
+++ b/prowler/lib/check/models.py
@@ -166,11 +166,11 @@ class CheckMetadata(BaseModel):
return service_name
@validator("CheckID", pre=True, always=True)
- def valid_check_id(cls, check_id):
+ def valid_check_id(cls, check_id, values):
if not check_id:
raise ValueError("CheckID must be a non-empty string")
- if check_id:
+ if check_id and values.get("Provider") != "iac":
if "-" in check_id:
raise ValueError(
f"CheckID {check_id} contains a hyphen, which is not allowed"
@@ -648,25 +648,34 @@ class CheckReportM365(Check_Report):
@dataclass
class CheckReportIAC(Check_Report):
- """Contains the IAC Check's finding information using Checkov."""
+ """Contains the IAC Check's finding information using Trivy."""
resource_name: str
- resource_path: str
resource_line_range: str
- def __init__(self, metadata: dict = {}, finding: dict = {}) -> None:
+ def __init__(
+ self, metadata: dict = {}, finding: dict = {}, file_path: str = ""
+ ) -> None:
"""
- Initialize the IAC Check's finding information from a Checkov failed_check dict.
+ Initialize the IAC Check's finding information from a Trivy misconfiguration dict.
Args:
metadata (Dict): Optional check metadata (can be None).
- failed_check (dict): A single failed_check result from Checkov's JSON output.
+ finding (dict): A single misconfiguration result from Trivy's JSON output.
"""
super().__init__(metadata, finding)
- self.resource_name = getattr(finding, "resource", "")
- self.resource_path = getattr(finding, "file_path", "")
- self.resource_line_range = getattr(finding, "file_line_range", "")
+ self.resource = finding
+ self.resource_name = file_path
+ self.resource_line_range = (
+ (
+ str(finding.get("CauseMetadata", {}).get("StartLine", ""))
+ + ":"
+ + str(finding.get("CauseMetadata", {}).get("EndLine", ""))
+ )
+ if finding.get("CauseMetadata", {}).get("StartLine", "")
+ else ""
+ )
@dataclass
diff --git a/prowler/lib/check/utils.py b/prowler/lib/check/utils.py
index bf8854600d..cab19486d5 100644
--- a/prowler/lib/check/utils.py
+++ b/prowler/lib/check/utils.py
@@ -14,7 +14,7 @@ def recover_checks_from_provider(
Returns a list of tuples with the following format (check_name, check_path)
"""
try:
- # Bypass check loading for IAC provider since it uses Checkov directly
+ # Bypass check loading for IAC provider since it uses Trivy directly
if provider == "iac":
return []
@@ -63,7 +63,7 @@ def recover_checks_from_service(service_list: list, provider: str) -> set:
Returns a set of checks from the given services
"""
try:
- # Bypass check loading for IAC provider since it uses Checkov directly
+ # Bypass check loading for IAC provider since it uses Trivy directly
if provider == "iac":
return set()
diff --git a/prowler/lib/outputs/finding.py b/prowler/lib/outputs/finding.py
index a3ba6271dd..f686554a88 100644
--- a/prowler/lib/outputs/finding.py
+++ b/prowler/lib/outputs/finding.py
@@ -19,6 +19,7 @@ from prowler.lib.outputs.compliance.compliance import get_check_compliance
from prowler.lib.outputs.utils import unroll_tags
from prowler.lib.utils.utils import dict_to_lowercase, get_nested_attribute
from prowler.providers.common.provider import Provider
+from prowler.providers.github.models import GithubAppIdentityInfo, GithubIdentityInfo
class Finding(BaseModel):
@@ -250,15 +251,16 @@ class Finding(BaseModel):
output_data["resource_name"] = check_output.resource_name
output_data["resource_uid"] = check_output.resource_id
- if hasattr(provider.identity, "account_name"):
+ if isinstance(provider.identity, GithubIdentityInfo):
# GithubIdentityInfo (Personal Access Token, OAuth)
output_data["account_name"] = provider.identity.account_name
output_data["account_uid"] = provider.identity.account_id
- elif hasattr(provider.identity, "app_id"):
+ output_data["account_email"] = provider.identity.account_email
+ elif isinstance(provider.identity, GithubAppIdentityInfo):
# GithubAppIdentityInfo (GitHub App)
- # TODO: Get Github App name
- output_data["account_name"] = f"app-{provider.identity.app_id}"
+ output_data["account_name"] = provider.identity.app_name
output_data["account_uid"] = provider.identity.app_id
+ output_data["installations"] = provider.identity.installations
output_data["region"] = check_output.owner
@@ -295,9 +297,9 @@ class Finding(BaseModel):
output_data["auth_method"] = provider.auth_method
output_data["account_uid"] = "iac"
output_data["account_name"] = "iac"
- output_data["resource_name"] = check_output.resource["resource"]
- output_data["resource_uid"] = check_output.resource["resource"]
- output_data["region"] = check_output.resource_path
+ output_data["resource_name"] = check_output.resource_name
+ output_data["resource_uid"] = check_output.resource_name
+ output_data["region"] = check_output.resource_line_range
output_data["resource_line_range"] = check_output.resource_line_range
output_data["framework"] = check_output.check_metadata.ServiceName
diff --git a/prowler/lib/outputs/html/html.py b/prowler/lib/outputs/html/html.py
index 7b4fb87601..4e05fe0e8a 100644
--- a/prowler/lib/outputs/html/html.py
+++ b/prowler/lib/outputs/html/html.py
@@ -41,7 +41,7 @@ class HTML(Output):
+ Configure AWS Security Hub integration to automatically send your + security findings for centralized monitoring and compliance. +
+ +- Output directory:{" "} - {integration.attributes.configuration - .output_directory || - integration.attributes.configuration.path || - "/"} -
-- Export security findings to Amazon S3 buckets. -
-+ Send security findings to AWS Security Hub. +
++ Configure and manage your AWS Security Hub integrations to + automatically send security findings for centralized monitoring. +
++ {integrations.length === 0 + ? "Not configured yet" + : `${integrations.length} integration${integrations.length !== 1 ? "s" : ""} configured`} +
++ Last updated:{" "} + {format( + new Date(integration.attributes.updated_at), + "yyyy/MM/dd", + )} +
+ )} ++ {subtitle} +
+ )} +{subtitle}
+A read-only IAM role must be manually created - {type === "s3-integration" ? " or updated" : ""}. + {type === "integrations" ? " or updated" : ""}.