Date: Wed, 15 Jul 2026 12:28:50 +0200
Subject: [PATCH 19/22] docs: new product family (#11984)
---
README.md | 78 +++-
docs/AGENTS.md | 65 +++-
docs/README.md | 4 +-
docs/developer-guide/documentation.mdx | 4 +-
docs/developer-guide/end2end-testing.mdx | 16 +-
.../developer-guide/environment-variables.mdx | 20 +-
docs/developer-guide/introduction.mdx | 2 +-
.../lighthouse-architecture.mdx | 6 +-
docs/developer-guide/llm-details.mdx | 2 +-
docs/developer-guide/mcp-server.mdx | 8 +-
docs/developer-guide/prowler-studio.mdx | 2 +-
.../security-compliance-framework.mdx | 8 +-
docs/docs.json | 351 ++++++++++--------
.../basic-usage/prowler-app.mdx | 6 +-
.../basic-usage/prowler-mcp-tools.mdx | 8 +-
.../basic-usage/prowler-mcp.mdx | 6 +-
.../installation/prowler-app.mdx | 18 +-
docs/getting-started/products/index.mdx | 48 +++
docs/getting-started/products/prowler-app.mdx | 46 ++-
.../products/prowler-claude-code-plugin.mdx | 1 +
docs/getting-started/products/prowler-cli.mdx | 4 +-
.../products/prowler-cloud-lighthouse.mdx | 4 +-
docs/getting-started/products/prowler-mcp.mdx | 31 +-
docs/getting-started/products/prowler-sdk.mdx | 11 +
docs/images/icons/cloud-bold.svg | 1 +
.../products/prowler-app-architecture.mmd | 4 +-
docs/introduction.mdx | 37 +-
docs/scripts/generate_provider_cards.py | 2 +-
docs/security/index.mdx | 2 +-
docs/security/networking.mdx | 12 +
docs/snippets/applies-to.mdx | 14 +
docs/snippets/subscription-banner.mdx | 4 +-
docs/style.css | 57 +++
docs/support.mdx | 16 +-
docs/troubleshooting.mdx | 16 +-
docs/user-guide/cli/tutorials/dashboard.mdx | 6 +-
.../compliance/tutorials/compliance.mdx | 14 +-
.../tutorials/cross-provider-compliance.mdx | 3 +-
.../cookbooks/powerbi-cis-benchmarks.mdx | 8 +-
.../getting-started-alibabacloud.mdx | 2 +-
.../providers/aws/authentication.mdx | 10 +-
.../providers/aws/getting-started-aws.mdx | 8 +-
.../providers/aws/organizations.mdx | 2 +-
.../providers/aws/regions-and-partitions.mdx | 2 +-
.../providers/azure/authentication.mdx | 6 +-
.../providers/azure/getting-started-azure.mdx | 8 +-
.../providers/azure/subscriptions.mdx | 2 +-
.../cloudflare/getting-started-cloudflare.mdx | 2 +-
.../providers/gcp/authentication.mdx | 2 +-
.../providers/gcp/getting-started-gcp.mdx | 4 +-
.../providers/github/authentication.mdx | 4 +-
.../github/getting-started-github.mdx | 10 +-
.../getting-started-googleworkspace.mdx | 2 +-
.../providers/iac/getting-started-iac.mdx | 8 +-
.../providers/image/getting-started-image.mdx | 2 +-
.../kubernetes/getting-started-k8s.mdx | 8 +-
.../microsoft365/getting-started-m365.mdx | 2 +-
.../getting-started-mongodbatlas.mdx | 8 +-
.../providers/oci/getting-started-oci.mdx | 6 +-
.../providers/okta/authentication.mdx | 2 +-
.../providers/okta/getting-started-okta.mdx | 2 +-
.../vercel/getting-started-vercel.mdx | 2 +-
.../aws-organizations-bulk-provisioning.mdx | 18 +-
.../tutorials/bulk-provider-provisioning.mdx | 14 +-
docs/user-guide/tutorials/prowler-alerts.mdx | 1 +
.../tutorials/prowler-app-api-keys.mdx | 17 +-
.../tutorials/prowler-app-attack-paths.mdx | 5 +-
.../tutorials/prowler-app-finding-groups.mdx | 6 +-
.../tutorials/prowler-app-findings-triage.mdx | 3 +-
.../prowler-app-jira-integration.mdx | 14 +-
.../prowler-app-lighthouse-multi-llm.mdx | 1 +
.../tutorials/prowler-app-lighthouse.mdx | 2 +-
.../tutorials/prowler-app-multi-tenant.mdx | 8 +-
.../tutorials/prowler-app-mute-findings.mdx | 17 +-
.../user-guide/tutorials/prowler-app-rbac.mdx | 6 +-
.../tutorials/prowler-app-s3-integration.mdx | 12 +-
.../prowler-app-scan-configuration.mdx | 1 +
.../prowler-app-security-hub-integration.mdx | 14 +-
.../tutorials/prowler-app-simple-mutelist.mdx | 5 +-
.../tutorials/prowler-app-social-login.mdx | 6 +-
.../tutorials/prowler-app-sso-entra.mdx | 10 +-
.../prowler-app-sso-google-workspace.mdx | 58 +--
docs/user-guide/tutorials/prowler-app-sso.mdx | 56 +--
docs/user-guide/tutorials/prowler-app.mdx | 11 +-
.../prowler-cloud-aws-organizations.mdx | 6 +-
.../prowler-cloud-azure-management-groups.mdx | 11 +
.../prowler-cloud-gcp-organizations.mdx | 11 +
.../prowler-cloud-lighthouse-multi-llm.mdx | 1 +
.../tutorials/prowler-cloud-public-ips.mdx | 29 --
.../tutorials/prowler-import-findings.mdx | 3 +-
.../tutorials/prowler-scan-scheduling.mdx | 11 +-
91 files changed, 900 insertions(+), 506 deletions(-)
create mode 100644 docs/getting-started/products/index.mdx
create mode 100644 docs/getting-started/products/prowler-sdk.mdx
create mode 100644 docs/images/icons/cloud-bold.svg
create mode 100644 docs/snippets/applies-to.mdx
create mode 100644 docs/user-guide/tutorials/prowler-cloud-azure-management-groups.mdx
create mode 100644 docs/user-guide/tutorials/prowler-cloud-gcp-organizations.mdx
delete mode 100644 docs/user-guide/tutorials/prowler-cloud-public-ips.mdx
diff --git a/README.md b/README.md
index 3744cd0256..c58d903c08 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
- Prowler is the Open Cloud Security Platform trusted by thousands to automate security and compliance in any cloud environment. With hundreds of ready-to-use checks and compliance frameworks, Prowler delivers real-time, customizable monitoring and seamless integrations, making cloud security simple, scalable, and cost-effective for organizations of any size.
+ Prowler is the Open Cloud Security Platform trusted by thousands to automate security and compliance in any cloud environment. With thousands of ready-to-use checks and compliance frameworks, Prowler delivers real-time, customizable monitoring and seamless integrations, making cloud security simple, scalable, and cost-effective for organizations of any size.
Secure ANY cloud at AI Speed at prowler.com
@@ -41,7 +41,7 @@
# Description
-**Prowler** is the world’s most widely used _Open-Source Cloud Security Platform_ that automates security and compliance across **any cloud environment**. With hundreds of ready-to-use security checks, remediation guidance, and compliance frameworks, Prowler is built to _“Secure ANY Cloud at AI Speed”_. Prowler delivers **AI-driven**, **customizable**, and **easy-to-use** assessments, dashboards, reports, and integrations, making cloud security **simple**, **scalable**, and **cost-effective** for organizations of any size.
+**Prowler** is the world’s most widely used _Open-Source Cloud Security Platform_ that automates security and compliance across **any cloud environment**. With thousands of ready-to-use security checks, remediation guidance, and compliance frameworks, Prowler is built to _“Secure ANY Cloud at AI Speed”_. Prowler delivers **AI-driven**, **customizable**, and **easy-to-use** assessments, dashboards, reports, and integrations, making cloud security **simple**, **scalable**, and **cost-effective** for organizations of any size.
Prowler includes hundreds of built-in controls to ensure compliance with standards and frameworks, including:
@@ -54,16 +54,16 @@ Prowler includes hundreds of built-in controls to ensure compliance with standar
- **National Security Standards:** ENS (Spanish National Security Scheme) and KISA ISMS-P (Korean)
- **Custom Security Frameworks:** Tailored to your needs
-## Prowler App / Prowler Cloud
+## Prowler Cloud & Prowler Local Server
-Prowler App / [Prowler Cloud](https://cloud.prowler.com/) is a web-based application that simplifies running Prowler across your cloud provider accounts. It provides a user-friendly interface to visualize the results and streamline your security assessments.
+[Prowler Cloud](https://cloud.prowler.com/) and Prowler Local Server, its self-hosted open-source version, are web applications that simplify running Prowler across your cloud provider accounts. They provide a user-friendly interface to visualize the results and streamline your security assessments.
-
+


->For more details, refer to the [Prowler App Documentation](https://docs.prowler.com/projects/prowler-open-source/en/latest/#prowler-app-installation)
+>For more details, refer to the [Prowler Local Server documentation](https://docs.prowler.com/getting-started/installation/prowler-app)
## Prowler CLI
@@ -73,12 +73,12 @@ prowler

-## Prowler Dashboard
+## Prowler Local Dashboard
```console
prowler dashboard
```
-
+
## Attack Paths
@@ -121,7 +121,7 @@ Every AWS provider scan will enqueue an Attack Paths ingestion job automatically
> For the most accurate and up-to-date information about checks, services, frameworks, and categories, visit [**Prowler Hub**](https://hub.prowler.com).
-| Provider | Checks | Services | [Compliance Frameworks](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/compliance/) | [Categories](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/misc/#categories) | Support | Interface |
+| Provider | Checks | Services | [Compliance Frameworks](https://docs.prowler.com/user-guide/compliance/tutorials/compliance) | [Categories](https://docs.prowler.com/user-guide/cli/tutorials/misc#categories) | Support | Interface |
|---|---|---|---|---|---|---|
| AWS | 615 | 86 | 47 | 19 | Official | UI, API, CLI |
| Azure | 190 | 22 | 21 | 16 | Official | UI, API, CLI |
@@ -160,11 +160,11 @@ Every AWS provider scan will enqueue an Attack Paths ingestion job automatically
# 💻 Installation
-## Prowler App
+## Prowler Local Server
-Prowler App offers flexible installation methods tailored to various environments:
+Prowler Local Server offers flexible installation methods tailored to various environments:
-> For detailed instructions on using Prowler App, refer to the [Prowler App Usage Guide](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/prowler-app/).
+> For detailed instructions on using Prowler Local Server, refer to the [usage guide](https://docs.prowler.com/user-guide/tutorials/prowler-app).
### Docker Compose
@@ -197,7 +197,7 @@ docker compose up -d
> [!WARNING]
> 🔒 For a secure setup, the API auto-generates a unique key pair, `DJANGO_TOKEN_SIGNING_KEY` and `DJANGO_TOKEN_VERIFYING_KEY`, and stores it in `~/.config/prowler-api` (non-container) or the bound Docker volume in `_data/api` (container). Never commit or reuse static/default keys. To rotate keys, delete the stored key files and restart the API.
-Once configured, access the Prowler App at http://localhost:3000. Sign up using your email and password to get started.
+Once configured, access Prowler Local Server at http://localhost:3000. Sign up using your email and password to get started.
### Common Issues with Docker Pull Installation
@@ -269,7 +269,7 @@ pnpm run build
pnpm start
```
-> Once configured, access the Prowler App at http://localhost:3000. Sign up using your email and password to get started.
+> Once configured, access Prowler Local Server at http://localhost:3000. Sign up using your email and password to get started.
#### Pre-commit Hooks Setup
@@ -287,7 +287,7 @@ Prowler CLI is available as a project in [PyPI](https://pypi.org/project/prowler
pip install prowler
prowler -v
```
->For further guidance, refer to [https://docs.prowler.com](https://docs.prowler.com/projects/prowler-open-source/en/latest/#prowler-cli-installation)
+>For further guidance, refer to [https://docs.prowler.com](https://docs.prowler.com/getting-started/installation/prowler-cli)
### Containers
@@ -307,7 +307,7 @@ The container images are available here:
- Prowler CLI:
- [DockerHub](https://hub.docker.com/r/prowlercloud/prowler/tags)
- [AWS Public ECR](https://gallery.ecr.aws/prowler-cloud/prowler)
-- Prowler App:
+- Prowler Local Server:
- [DockerHub - Prowler UI](https://hub.docker.com/r/prowlercloud/prowler-ui/tags)
- [DockerHub - Prowler API](https://hub.docker.com/r/prowlercloud/prowler-api/tags)
@@ -357,17 +357,55 @@ Full configuration, per-provider authentication, and SARIF examples: [Prowler Gi
# ✏️ High level architecture
-## Prowler App
-**Prowler App** is composed of four key components:
+## Prowler Local Server
+**Prowler Local Server** is composed of four key components:
- **Prowler UI**: A web-based interface, built with Next.js, providing a user-friendly experience for executing Prowler scans and visualizing results.
- **Prowler API**: A backend service, developed with Django REST Framework, responsible for running Prowler scans and storing the generated results.
- **Prowler SDK**: A Python SDK designed to extend the functionality of the Prowler CLI for advanced capabilities.
- **Prowler MCP Server**: A Model Context Protocol server that provides AI tools for Lighthouse, the AI-powered security assistant. This is a critical dependency for Lighthouse functionality.
-
+```mermaid
+flowchart TB
+ user([User / Security Team])
+ cli([Prowler CLI])
-
+ subgraph APP["Prowler Local Server"]
+ ui["Prowler UI
(Next.js)"]
+ api["Prowler API
(Django REST Framework)"]
+ worker["API Worker
(Celery)"]
+ beat["API Scheduler
(Celery Beat)"]
+ mcp["Prowler MCP Server
(Lighthouse AI tools)"]
+ end
+
+ sdk["Prowler SDK
(Python)"]
+
+ subgraph DATA["Data Layer"]
+ pg[("PostgreSQL")]
+ valkey[("Valkey / Redis")]
+ neo4j[("Neo4j")]
+ end
+
+ providers["Providers"]
+
+ user --> ui
+ user --> cli
+ ui -->|REST| api
+ ui -->|MCP HTTP| mcp
+ mcp -->|REST| api
+ api --> pg
+ api --> valkey
+ beat -->|enqueue jobs| valkey
+ valkey -->|dispatch| worker
+ worker --> pg
+ worker -->|Attack Paths| neo4j
+ worker -->|invokes| sdk
+ cli --> sdk
+
+ sdk --> providers
+```
+
+
## Prowler CLI
diff --git a/docs/AGENTS.md b/docs/AGENTS.md
index 8278a7f88a..45bd3f04fa 100644
--- a/docs/AGENTS.md
+++ b/docs/AGENTS.md
@@ -78,11 +78,25 @@ b. National security is of the utmost concern nowadays.
Prowler Features are considered proper nouns. They are to be referenced without articles in all pieces of writing.
-This is a list of Prowler Features:
+Prowler ships two product families. Use these names exactly; the former names Prowler App (now Prowler Local Server) and Prowler Enterprise (now Prowler Private Cloud) must not appear in new writing. The only allowed former-name notes are on the Prowler Product Families page (`getting-started/products/index.mdx`) and in the site-wide banner, which document the mapping.
+
+Prowler Products:
+
+* **Prowler Cloud**
+* **Prowler Private Cloud** (formerly Prowler Enterprise)
+* **Prowler Hub**
+* **Prowler Lighthouse AI**
+* **Prowler MCP**
+
+Open Source projects:
-* **Prowler App**
* **Prowler CLI**
+* **Prowler Local Server** (formerly Prowler App)
+* **Prowler Local Dashboard** (the Prowler CLI dashboard)
* **Prowler SDK**
+
+Other Prowler Features:
+
* **Built-in Compliance Checks**
* **Multi-cloud Security Scanning**
* **Autonomous Cloud Security Analyst (AI)**
@@ -97,8 +111,6 @@ This is a list of Prowler Features:
* **AI-Generated Detections & Remediations**
* **Prowler Studio**
* **Custom Security Policies**
-* **Prowler Cloud**
-* **Prowler Registry**
* **Open Source & Full APIs**
---
@@ -137,10 +149,10 @@ Explicit use of second-person pronouns (you) and possessives (your) should be mi
### Example of Improvement Through Avoiding Second Person Pronouns
**Original:**
-Prowler App can be installed in different ways, depending on your environment:
+Prowler Local Server can be installed in different ways, depending on your environment:
**Improved Version:**
-Prowler App offers flexible installation methods tailored to various environments:
+Prowler Local Server offers flexible installation methods tailored to various environments:
---
@@ -262,7 +274,7 @@ There are several options for punctuating bullet points. Regardless of the style
* **No punctuation (minimalistic):** This strategy is suitable when no verbs are involved and is best used to highlight products or features in isolation. For example:
- Prowler App is composed of three key components:
+ Prowler Local Server is composed of three key components:
* Prowler UI
* Prowler API
* Prowler SDK
@@ -271,7 +283,7 @@ There are several options for punctuating bullet points. Regardless of the style
* **Periods for full sentences:** This approach works best when each bullet point forms a full sentence or includes verbs. For example:
- Prowler App is composed of three key components:
+ Prowler Local Server is composed of three key components:
* Prowler UI, a web-based interface, built with Next.js, providing a user-friendly experience for executing Prowler scans and visualizing results.
* Prowler API, a backend service, developed with Django REST Framework, responsible for running Prowler scans and storing the generated results.
* Prowler SDK, a Python SDK designed to extend the functionality of the Prowler CLI for advanced capabilities.
@@ -539,6 +551,43 @@ Tag-Based Scanning allows filtering resources by AWS tags during security assess
---
+## AppliesTo Banner for Product Scope
+
+The AppliesTo component states which products a guide covers and links to the product families page. It is located at `docs/snippets/applies-to.mdx`.
+
+### When to Use the AppliesTo Banner
+
+Use it on web UI tutorial pages that apply to more than one product (for example, a guide written for Prowler Cloud whose steps also work on Prowler Local Server). Do not combine it with the SubscriptionBanner: pages carrying the SubscriptionBanner already state their availability.
+
+### How to Use the AppliesTo Banner
+
+```mdx
+import { AppliesTo } from "/snippets/applies-to.mdx"
+
+
+```
+
+The default covers Prowler Cloud, Prowler Private Cloud, and Prowler Local Server. Pass the `products` prop to narrow the scope:
+
+```mdx
+
+```
+
+Place it on its own line below the Version Badge when one is present, otherwise directly after the imports.
+
+### Cloud Marker for Subscription Content
+
+The custom green cloud glyph (`docs/images/icons/cloud-bold.svg`) marks content that requires a Prowler Cloud or Prowler Private Cloud subscription. It renders as a trailing `::after` element through the "Cloud marker" rules in `docs/style.css`, so sidebar labels stay left-aligned.
+
+* Pages: add a `li[id=""] a span::after` selector to the Cloud marker rule in `docs/style.css` for every page whose content is subscription-gated. The `li` id equals the page URL path. Pages where only one section is gated (for example the Support page, where only the Support Desk carries the SubscriptionBanner) get no marker.
+* Navigation groups: add a selector only when every page in the group is subscription-gated. One sanctioned exception: the Prowler MCP group is marked because the hosted server at `mcp.prowler.com` includes tools for Prowler Cloud-specific features, and its overview page explains the free local alternative. Nested groups render as `li[data-title=""]` with a button toggle, so use `li[data-title=""] > button span:first-child::after`. Top-level groups render as `h3` headings without `data-title`, which means name collisions with top-level groups resolve themselves; a gated top-level group (always expanded) is selected through its sibling list with `:has()`, like the Security tab group. Do not use `:has()` on child links of nested groups: collapsed groups do not render their children.
+
+Do not use the `icon` field for this marker (icons render before the label and misalign the sidebar), and do not use `"tag"` on navigation groups (group-level tags crash `mint broken-links` with a stack overflow, verified with mint 4.2.689). The SVG stroke uses the fixed brand green `#10B981` on purpose: it must be visible on both themes without `currentColor` support.
+
+The marker meaning is explained on the Prowler Product Families page at `getting-started/products/index.mdx`: keep that note in place.
+
+---
+
## Avoid Assumptions Regarding Audience’s Expertise
### Understand Your Audience’s Expertise
diff --git a/docs/README.md b/docs/README.md
index 595f79bc5a..7934972c9b 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -5,7 +5,7 @@ This repository contains the Prowler Open Source documentation powered by [Mintl
## Documentation Structure
- **Getting Started**: Overview, installation, and basic usage guides
-- **User Guide**: Comprehensive guides for Prowler App, CLI, providers, and compliance
+- **User Guide**: Comprehensive guides for Prowler Cloud, Prowler Local Server, Prowler CLI, providers, and compliance
- **Developer Guide**: Technical documentation for developers contributing to Prowler
## Local Development
@@ -13,7 +13,7 @@ This repository contains the Prowler Open Source documentation powered by [Mintl
Install a reviewed version of the [Mintlify CLI](https://www.npmjs.com/package/mint) to preview documentation changes locally:
```bash
-npm install --global mint@4.2.560
+npm install --global mint@4.2.689
```
Run the following command at the root of your documentation (where `mint.json` is located):
diff --git a/docs/developer-guide/documentation.mdx b/docs/developer-guide/documentation.mdx
index d0fb808af2..fd045a1751 100644
--- a/docs/developer-guide/documentation.mdx
+++ b/docs/developer-guide/documentation.mdx
@@ -8,9 +8,9 @@ Prowler documentation is built using [Mintlify](https://www.mintlify.com/docs),
The Prowler documentation is organized into several sections. The main ones are:
-- **Getting Started**: Provides an overview of the Prowler platform and its different solutions, including Prowler Cloud/App, Prowler CLI, Prowler MCP Server, Prowler Hub, and Prowler Lighthouse AI. This section helps new users understand which Prowler solution best fits their needs and includes product comparisons.
+- **Getting Started**: Provides an overview of the Prowler platform and its two product families, Prowler Products (Prowler Cloud, Prowler Hub, Prowler MCP, Prowler Lighthouse AI) and Open Source (Prowler CLI, Prowler Local Server). This section helps new users understand which Prowler solution best fits their needs and includes product comparisons.
-- **Guides**: Contains practical tutorials and how-to guides organized by product (Prowler Cloud/App, CLI) and provider (AWS, Azure, GCP, Kubernetes, Microsoft 365, GitHub, etc.). This section covers authentication, integrations, compliance, and advanced usage scenarios.
+- **Guides**: Contains practical tutorials and how-to guides organized by product (Prowler Cloud, CLI) and provider (AWS, Azure, GCP, Kubernetes, Microsoft 365, GitHub, etc.). This section covers authentication, integrations, compliance, and advanced usage scenarios.
- **Developer Guide**: Documentation for contributors looking to extend Prowler functionality. This includes guides on creating providers, services, checks, output formats, integrations, and compliance frameworks. Provider-specific implementation details and testing strategies are also covered here.
diff --git a/docs/developer-guide/end2end-testing.mdx b/docs/developer-guide/end2end-testing.mdx
index 9013a32245..df99de6fee 100644
--- a/docs/developer-guide/end2end-testing.mdx
+++ b/docs/developer-guide/end2end-testing.mdx
@@ -1,12 +1,12 @@
---
-title: 'End-2-End Tests for Prowler App'
+title: 'End-2-End Tests for Prowler Local Server'
---
-End-to-end (E2E) tests validate complete user flows in Prowler App (UI + API). These tests are implemented with [Playwright](https://playwright.dev/) under the `ui/tests` folder and are designed to run against a Prowler App environment.
+End-to-end (E2E) tests validate complete user flows in Prowler Local Server (UI + API). These tests are implemented with [Playwright](https://playwright.dev/) under the `ui/tests` folder and are designed to run against a Prowler Local Server environment.
## General Recommendations
-When adding or maintaining E2E tests for Prowler App, follow these guidelines:
+When adding or maintaining E2E tests for Prowler Local Server, follow these guidelines:
1. **Test real user journeys**
Focus on full workflows (for example, sign-up → login → add provider → launch scan) instead of low-level UI details already covered by unit or integration tests.
@@ -19,8 +19,8 @@ When adding or maintaining E2E tests for Prowler App, follow these guidelines:
3. **Use a Page Model (Page Object Model)**
- Encapsulate selectors and common actions in page classes instead of repeating them in each test.
- Leverage and extend the existing Playwright page models in `ui/tests`—such as `ProvidersPage`, `ScansPage`, and others—which are all based on the shared `BasePage`.
- - Page models for Prowler App pages should be placed in their respective entity folders (for example, `ui/tests/providers/providers-page.ts`).
- - Page models for external pages (not part of Prowler App) should be grouped in the `external` folder (for example, `ui/tests/external/github-page.ts`).
+ - Page models for Prowler Local Server pages should be placed in their respective entity folders (for example, `ui/tests/providers/providers-page.ts`).
+ - Page models for external pages (not part of Prowler Local Server) should be grouped in the `external` folder (for example, `ui/tests/external/github-page.ts`).
- This approach improves readability, reduces duplication, and makes refactors safer.
4. **Reuse authentication states (StorageState)**
@@ -193,7 +193,7 @@ When adding or maintaining E2E tests for Prowler App, follow these guidelines:
## Running Prowler Tests
-E2E tests for Prowler App run from the `ui` project using Playwright. The Playwright configuration lives in `ui/playwright.config.ts` and defines:
+E2E tests for Prowler Local Server run from the `ui` project using Playwright. The Playwright configuration lives in `ui/playwright.config.ts` and defines:
- `testDir: "./tests"` – location of E2E test files (relative to the `ui` project root, so `ui/tests`).
- `webServer` – how to start the Next.js development server and connect to Prowler API.
@@ -225,7 +225,7 @@ Before running E2E tests:
- Start Prowler API so it is reachable on that URL (for example, via `docker-compose-dev.yml` or the development orchestration used locally).
- If a different API URL is required, set `UI_API_BASE_URL` accordingly before running the tests.
-- **Ensure Prowler App UI is available**
+- **Ensure Prowler Local Server UI is available**
- Playwright automatically starts the Next.js server through the `webServer` block in `playwright.config.ts` (`pnpm run dev` by default).
- If the UI is already running on `http://localhost:3000`, Playwright will reuse the existing server when `reuseExistingServer` is `true`.
@@ -246,7 +246,7 @@ Before running E2E tests:
### Executing Tests
-To execute E2E tests for Prowler App:
+To execute E2E tests for Prowler Local Server:
1. **Run the full E2E suite (headless)**
diff --git a/docs/developer-guide/environment-variables.mdx b/docs/developer-guide/environment-variables.mdx
index 33e3567251..913444d84b 100644
--- a/docs/developer-guide/environment-variables.mdx
+++ b/docs/developer-guide/environment-variables.mdx
@@ -2,7 +2,7 @@
title: 'Environment Variable Naming Convention'
---
-Prowler is a monorepo composed of several runtime components — Prowler App (the web user interface), Prowler API (the backend), Prowler SDK, and Prowler MCP Server (Model Context Protocol) — that frequently share a single `.env` file. To keep that shared configuration unambiguous, each component namespaces its environment variables with a component-specific prefix.
+Prowler is a monorepo composed of several runtime components — Prowler Local Server (the web user interface), Prowler API (the backend), Prowler SDK, and Prowler MCP Server (Model Context Protocol) — that frequently share a single `.env` file. To keep that shared configuration unambiguous, each component namespaces its environment variables with a component-specific prefix.
## Component Prefixes
@@ -10,7 +10,7 @@ Each component owns a dedicated prefix for the environment variables it reads:
| Component | Prefix | Status |
|-----------|--------|--------|
-| Prowler App (web UI) | `UI_` | Adopted |
+| Prowler Local Server (web UI) | `UI_` | Adopted |
| Prowler API (backend) | `API_` | Planned |
| Prowler SDK | `SDK_` | Planned |
| Prowler MCP Server | `MCP_` | Planned |
@@ -21,11 +21,11 @@ Component prefixes solve three concrete problems in a shared configuration file:
- **Collisions in a shared `.env`:** Several components historically read identically named variables. The API base URL, for example, is consumed by more than one component, so a single unprefixed name is ambiguous. A component prefix removes that ambiguity.
- **Explicit ownership:** A prefix states, at a glance, which component consumes a variable.
-- **Reduced accidental exposure:** For Prowler App, scoping browser-facing configuration under one intentional prefix prevents server-only values from leaking into the client bundle.
+- **Reduced accidental exposure:** For Prowler Local Server, scoping browser-facing configuration under one intentional prefix prevents server-only values from leaking into the client bundle.
-## Prowler App
+## Prowler Local Server
-Prowler App has adopted the `UI_` prefix. Its public configuration is resolved from the container environment at runtime rather than inlined at build time, so a single pre-built image serves any deployment. For the operational details on changing these values without rebuilding the image, see [Troubleshooting](/troubleshooting).
+Prowler Local Server has adopted the `UI_` prefix. Its public configuration is resolved from the container environment at runtime rather than inlined at build time, so a single pre-built image serves any deployment. For the operational details on changing these values without rebuilding the image, see [Troubleshooting](/troubleshooting).
The former build-time variables map to the new runtime variables as follows:
@@ -37,11 +37,11 @@ The former build-time variables map to the new runtime variables as follows:
| `NEXT_PUBLIC_SENTRY_DSN`, `SENTRY_DSN` | `UI_SENTRY_DSN` |
| `NEXT_PUBLIC_SENTRY_ENVIRONMENT`, `SENTRY_ENVIRONMENT` | `UI_SENTRY_ENVIRONMENT` |
-The build-time-only Sentry variables used for source-map upload — `SENTRY_ORG`, `SENTRY_PROJECT`, `SENTRY_AUTH_TOKEN`, and `SENTRY_RELEASE` — keep their names, as they are not part of the App's runtime configuration.
+The build-time-only Sentry variables used for source-map upload — `SENTRY_ORG`, `SENTRY_PROJECT`, `SENTRY_AUTH_TOKEN`, and `SENTRY_RELEASE` — keep their names, as they are not part of Prowler Local Server's runtime configuration.
## Enabling Third-Party Integrations
-Prowler App gates each optional third-party integration behind an explicit enable flag. When an integration is configured through its new `UI_*` variables, it loads only when its flag is set to the exact string `"true"`; any other value, including unset, leaves it off. This default-off behavior keeps a deployment free of third-party egress unless it opts in. Deployments still using the deprecated legacy variable names keep loading without the flag, for backward compatibility (see [Deprecated Names](#deprecated-names)).
+Prowler Local Server gates each optional third-party integration behind an explicit enable flag. When an integration is configured through its new `UI_*` variables, it loads only when its flag is set to the exact string `"true"`; any other value, including unset, leaves it off. This default-off behavior keeps a deployment free of third-party egress unless it opts in. Deployments still using the deprecated legacy variable names keep loading without the flag, for backward compatibility (see [Deprecated Names](#deprecated-names)).
| Integration | Enable flag | Required configuration when enabled |
|-------------|-------------|-------------------------------------|
@@ -49,9 +49,9 @@ Prowler App gates each optional third-party integration behind an explicit enabl
| Google Tag Manager | `UI_GOOGLE_TAG_MANAGER_ENABLED` | `UI_GOOGLE_TAG_MANAGER_ID` |
| PostHog (product analytics) | `UI_POSTHOG_ENABLED` | `UI_POSTHOG_KEY` and `UI_POSTHOG_HOST` |
-When an integration is enabled but its required configuration is missing, Prowler App fails fast at server startup with a clear error, so a misconfigured container never starts silently. A new `UI_*` value set while its enable flag is not `"true"` is ignored, and the server logs a one-time startup warning noting that the integration will not load. Legacy names follow the backward-compatible rule described in [Deprecated Names](#deprecated-names).
+When an integration is enabled but its required configuration is missing, Prowler Local Server fails fast at server startup with a clear error, so a misconfigured container never starts silently. A new `UI_*` value set while its enable flag is not `"true"` is ignored, and the server logs a one-time startup warning noting that the integration will not load. Legacy names follow the backward-compatible rule described in [Deprecated Names](#deprecated-names).
-PostHog support is currently limited to configuration validation: Prowler App reads and validates the PostHog variables but does not yet load a PostHog client.
+PostHog support is currently limited to configuration validation: Prowler Local Server reads and validates the PostHog variables but does not yet load a PostHog client.
Configuring an integration through the new `UI_*` variables now requires its enable flag. A deployment that adopted `UI_SENTRY_DSN` or `UI_GOOGLE_TAG_MANAGER_ID` must also set `UI_SENTRY_ENABLED=true` or `UI_GOOGLE_TAG_MANAGER_ENABLED=true` to keep the integration active. Deployments still using the legacy names (`NEXT_PUBLIC_*`, or `POSTHOG_KEY` and `POSTHOG_HOST`) keep working without the flag.
@@ -67,5 +67,5 @@ Prowler API, Prowler SDK, and Prowler MCP Server have not yet adopted the conven
## Deprecated Names
-- **Prowler App:** The bare server-side `SENTRY_DSN` and `SENTRY_ENVIRONMENT` are no longer read; the server and edge runtimes now read `UI_SENTRY_DSN` and `UI_SENTRY_ENVIRONMENT`. The former `NEXT_PUBLIC_*` names — and, for PostHog, the unprefixed `POSTHOG_KEY` and `POSTHOG_HOST` — are deprecated but stay backward compatible: they are read at runtime regardless of the enable flag, so an existing deployment keeps its integration active without opting in. The new `UI_*` names, by contrast, load only when the matching enable flag is set to `"true"`. These legacy names will be removed in a future release, so migrate to the `UI_*` runtime variables — and set the enable flag — on the running container.
+- **Prowler Local Server:** The bare server-side `SENTRY_DSN` and `SENTRY_ENVIRONMENT` are no longer read; the server and edge runtimes now read `UI_SENTRY_DSN` and `UI_SENTRY_ENVIRONMENT`. The former `NEXT_PUBLIC_*` names — and, for PostHog, the unprefixed `POSTHOG_KEY` and `POSTHOG_HOST` — are deprecated but stay backward compatible: they are read at runtime regardless of the enable flag, so an existing deployment keeps its integration active without opting in. The new `UI_*` names, by contrast, load only when the matching enable flag is set to `"true"`. These legacy names will be removed in a future release, so migrate to the `UI_*` runtime variables — and set the enable flag — on the running container.
- **Prowler API, Prowler SDK, and Prowler MCP Server:** The current, unprefixed variable names are deprecated. They continue to work today and will be removed once the prefixed convention is adopted for each component, as described in [Upcoming Breaking Change](#upcoming-breaking-change).
diff --git a/docs/developer-guide/introduction.mdx b/docs/developer-guide/introduction.mdx
index 1d434912ef..08c38ee17c 100644
--- a/docs/developer-guide/introduction.mdx
+++ b/docs/developer-guide/introduction.mdx
@@ -240,7 +240,7 @@ prowler/
├── README.md # Project overview and getting started
├── Makefile # Common development commands
├── Dockerfile # SDK Docker container
-├── docker-compose.yml # Prowler App Docker compose
+├── docker-compose.yml # Prowler Local Server Docker compose
└── ... # Other supporting files
```
diff --git a/docs/developer-guide/lighthouse-architecture.mdx b/docs/developer-guide/lighthouse-architecture.mdx
index e8acc6278c..631e0e7ae4 100644
--- a/docs/developer-guide/lighthouse-architecture.mdx
+++ b/docs/developer-guide/lighthouse-architecture.mdx
@@ -141,7 +141,7 @@ Key constants:
- `RECONNECT_INTERVAL_MS`: 5 minutes before retry after failure
```typescript
-// Authentication injection for Prowler App tools
+// Authentication injection for prowler_app tools
private handleBeforeToolCall = ({ name, args }) => {
// Only inject auth for prowler_app_* tools (user-specific data)
if (!name.startsWith("prowler_app_")) {
@@ -307,13 +307,13 @@ MCP tools are organized into three namespaces based on authentication requiremen
| Namespace | Auth Required | Description |
|-----------|---------------|-------------|
-| `prowler_app_*` | Yes (JWT) | Prowler Cloud/App tools for findings, providers, scans, resources |
+| `prowler_app_*` | Yes (JWT) | Prowler Cloud and Prowler Local Server tools for findings, providers, scans, resources |
| `prowler_hub_*` | No | Security checks catalog, compliance frameworks |
| `prowler_docs_*` | No | Documentation search and retrieval |
### Authentication Flow
-1. User authenticates with Prowler App, receiving a JWT token
+1. User authenticates with Prowler Local Server, receiving a JWT token
2. Token is stored in session and propagated via `authContextStorage`
3. MCP client injects `Authorization: Bearer ` header for `prowler_app_*` calls
4. MCP Server validates token and applies RLS filtering
diff --git a/docs/developer-guide/llm-details.mdx b/docs/developer-guide/llm-details.mdx
index 3647552c0f..3dc0f2653d 100644
--- a/docs/developer-guide/llm-details.mdx
+++ b/docs/developer-guide/llm-details.mdx
@@ -101,4 +101,4 @@ The LLM provider seamlessly integrates with Prowler's existing infrastructure:
- **Output Formats**: Supports all Prowler output formats (JSON, CSV, HTML, etc.)
- **Compliance Frameworks**: Integrates with Prowler's compliance reporting
- **Fixer Integration**: Supports automated remediation recommendations
-- **Dashboard Integration**: Compatible with Prowler App for centralized management
+- **Dashboard Integration**: Compatible with Prowler Cloud and Prowler Local Server for centralized management
diff --git a/docs/developer-guide/mcp-server.mdx b/docs/developer-guide/mcp-server.mdx
index 4174f0f730..1b9c49a18b 100644
--- a/docs/developer-guide/mcp-server.mdx
+++ b/docs/developer-guide/mcp-server.mdx
@@ -20,8 +20,8 @@ The server follows a modular architecture with three independent sub-servers:
| Sub-Server | Auth Required | Description |
|------------|---------------|-------------|
-| Prowler App | Yes | Full access to Prowler Cloud and Self-Managed features |
-| Prowler Hub | No | Security checks catalog with **over 1000 checks**, fixers, and **70+ compliance frameworks** |
+| `prowler_app` | Yes | Full access to Prowler Cloud and Prowler Local Server features |
+| Prowler Hub | No | Security checks catalog with **over 2,000 checks**, fixers, and **70+ compliance frameworks** |
| Prowler Documentation | No | Full-text search and retrieval of official documentation |
@@ -53,9 +53,9 @@ mcp_server/prowler_mcp_server/
The MCP Server uses two patterns for tool registration:
1. **Direct Decorators** (Prowler Hub/Docs): Tools are registered using `@mcp.tool()` decorators
-2. **Auto-Discovery** (Prowler App): All public methods of `BaseTool` subclasses are auto-registered
+2. **Auto-Discovery** (`prowler_app`): All public methods of `BaseTool` subclasses are auto-registered
-## Adding Tools to Prowler App
+## Adding Tools to the `prowler_app` Sub-Server
### Step 1: Create the Tool Class
diff --git a/docs/developer-guide/prowler-studio.mdx b/docs/developer-guide/prowler-studio.mdx
index a4a2a609b5..b89eea7175 100644
--- a/docs/developer-guide/prowler-studio.mdx
+++ b/docs/developer-guide/prowler-studio.mdx
@@ -5,7 +5,7 @@ title: 'Prowler Studio'
**Prowler Studio is an AI workflow that ensures Claude Code follows Prowler's skills, guardrails, and best practices when creating new security checks.** What lands in the resulting pull request is consistent, tested, and ready for human review — not half-correct boilerplate that needs to be rewritten.
-**Contributor Tool**: Prowler Studio is a workflow for advanced contributors adding new Prowler security checks. It is not part of Prowler Cloud, Prowler App, or Prowler CLI.
+**Contributor Tool**: Prowler Studio is a workflow for advanced contributors adding new Prowler security checks. It is not part of Prowler Cloud, Prowler Local Server, or Prowler CLI.
diff --git a/docs/developer-guide/security-compliance-framework.mdx b/docs/developer-guide/security-compliance-framework.mdx
index d80588dd24..2eeabebe2a 100644
--- a/docs/developer-guide/security-compliance-framework.mdx
+++ b/docs/developer-guide/security-compliance-framework.mdx
@@ -266,7 +266,7 @@ Every legacy compliance file is a JSON document with the following top-level key
| Field | Type | Required | Description |
|---|---|---|---|
| `Framework` | string | Yes | Canonical framework identifier, for example `CIS`, `NIST-800-53-Revision-5`, `ENS`, `CCC`. |
-| `Name` | string | Yes | Human-readable framework name displayed by Prowler App. |
+| `Name` | string | Yes | Human-readable framework name displayed by Prowler Cloud and Prowler Local Server. |
| `Version` | string | Yes (recommended) | Framework version, e.g. `2.0`. See [Version Handling](#version-handling). |
| `Provider` | string | Yes | Upper-cased provider identifier: `AWS`, `AZURE`, `GCP`, `KUBERNETES`, `M365`, `GITHUB`, `GOOGLEWORKSPACE`, and so on. |
| `Description` | string | Yes | Short description of the framework's scope and purpose. |
@@ -535,7 +535,7 @@ Each entry in the list is a single constraint with the following fields:
### How guardrails are evaluated
-All evaluation lives in one shared module, `prowler/lib/check/compliance_config_eval.py`, consumed by every compliance output (CSV, OCSF, and the CLI tables) and reused by the Prowler App backend so the rule is defined exactly once.
+All evaluation lives in one shared module, `prowler/lib/check/compliance_config_eval.py`, consumed by every compliance output (CSV, OCSF, and the CLI tables) and reused by the Prowler API backend so the rule is defined exactly once.
1. The applied configuration is the scan-global `audit_config` (the same mapping for every resource and region), resolved via `get_scan_audit_config()`.
2. For each requirement that declares constraints, `evaluate_config_constraints()` walks the list and returns `(is_compliant, reason)`. The requirement is compliant when **every** explicitly-set key satisfies its constraint.
@@ -736,9 +736,9 @@ Open the generated CSV and confirm:
- Every requirement has at least one row per scanned resource (when there are findings).
- Attribute values such as `Requirements_Attributes_Section` reflect the JSON content.
-### 5. Verify the framework in Prowler App
+### 5. Verify the Framework in Prowler Local Server
-Launch Prowler App locally (`docker compose up` from the repository root) and run a scan with the new compliance framework. Confirm the compliance page renders the requirements, sections, and status widgets correctly.
+Launch Prowler Local Server (`docker compose up` from the repository root) and run a scan with the new compliance framework. Confirm the compliance page renders the requirements, sections, and status widgets correctly.
## Testing
diff --git a/docs/docs.json b/docs/docs.json
index 4284f53a2a..211cb9c4d3 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -38,61 +38,73 @@
{
"group": "Welcome",
"pages": [
- "introduction"
+ "introduction",
+ "getting-started/products/index"
]
},
{
- "group": "Prowler Cloud",
+ "group": "Prowler Products",
"pages": [
- "getting-started/products/prowler-cloud",
- "getting-started/products/prowler-cloud-pricing",
- "getting-started/products/prowler-cloud-aws-marketplace",
- "getting-started/goto/prowler-cloud",
- "getting-started/goto/prowler-api-reference"
+ {
+ "group": "Prowler Cloud",
+ "pages": [
+ "getting-started/products/prowler-cloud",
+ "getting-started/products/prowler-cloud-pricing",
+ "getting-started/products/prowler-cloud-aws-marketplace",
+ "getting-started/goto/prowler-cloud",
+ "getting-started/goto/prowler-api-reference"
+ ]
+ },
+ {
+ "group": "Prowler Lighthouse AI",
+ "pages": [
+ "getting-started/products/prowler-cloud-lighthouse"
+ ]
+ },
+ {
+ "group": "Prowler Hub",
+ "pages": [
+ "getting-started/products/prowler-hub",
+ "getting-started/goto/prowler-hub"
+ ]
+ },
+ {
+ "group": "Prowler MCP",
+ "pages": [
+ "getting-started/products/prowler-mcp",
+ "getting-started/installation/prowler-mcp",
+ "getting-started/basic-usage/prowler-mcp",
+ "getting-started/basic-usage/prowler-mcp-tools"
+ ]
+ },
+ {
+ "group": "Prowler for AI Agents",
+ "pages": [
+ "getting-started/products/prowler-claude-code-plugin"
+ ]
+ }
]
},
{
- "group": "Prowler CLI",
+ "group": "Open Source",
"pages": [
- "getting-started/products/prowler-cli",
- "getting-started/installation/prowler-cli",
- "getting-started/basic-usage/prowler-cli"
- ]
- },
- {
- "group": "Prowler App",
- "pages": [
- "getting-started/products/prowler-app",
- "getting-started/installation/prowler-app",
- "getting-started/basic-usage/prowler-app"
- ]
- },
- {
- "group": "Prowler Lighthouse AI",
- "pages": [
- "getting-started/products/prowler-cloud-lighthouse"
- ]
- },
- {
- "group": "Prowler for Claude Code",
- "pages": [
- "getting-started/products/prowler-claude-code-plugin"
- ]
- },
- {
- "group": "Prowler MCP Server",
- "pages": [
- "getting-started/products/prowler-mcp",
- "getting-started/installation/prowler-mcp",
- "getting-started/basic-usage/prowler-mcp",
- "getting-started/basic-usage/prowler-mcp-tools"
- ]
- },
- {
- "group": "Prowler Hub",
- "pages": [
- "getting-started/products/prowler-hub",
- "getting-started/goto/prowler-hub"
+ {
+ "group": "Prowler CLI",
+ "pages": [
+ "getting-started/products/prowler-cli",
+ "getting-started/installation/prowler-cli",
+ "getting-started/basic-usage/prowler-cli"
+ ]
+ },
+ {
+ "group": "Prowler Local Server",
+ "pages": [
+ "getting-started/products/prowler-app",
+ "getting-started/installation/prowler-app",
+ "getting-started/basic-usage/prowler-app"
+ ]
+ },
+ "getting-started/products/prowler-sdk"
]
},
{
@@ -111,36 +123,36 @@
"tab": "Guides",
"groups": [
{
- "group": "Prowler Cloud/App",
+ "group": "Prowler Cloud",
"pages": [
"user-guide/tutorials/prowler-app",
{
- "group": "Authentication",
+ "group": "Authentication & Access",
"pages": [
+ "user-guide/tutorials/prowler-app-api-keys",
+ "user-guide/tutorials/prowler-app-multi-tenant",
+ "user-guide/tutorials/prowler-app-sso",
"user-guide/tutorials/prowler-app-social-login",
- "user-guide/tutorials/prowler-app-sso"
+ "user-guide/tutorials/prowler-app-rbac"
]
},
- "user-guide/tutorials/prowler-app-rbac",
- "user-guide/tutorials/prowler-app-multi-tenant",
- "user-guide/tutorials/prowler-app-api-keys",
- "user-guide/tutorials/prowler-import-findings",
- "user-guide/tutorials/prowler-scan-scheduling",
- "user-guide/tutorials/prowler-alerts",
- "user-guide/tutorials/prowler-app-scan-configuration",
- "user-guide/tutorials/prowler-app-findings-triage",
- "user-guide/compliance/tutorials/cross-provider-compliance",
{
- "group": "Mutelist",
- "expanded": true,
+ "group": "Compliance",
"pages": [
- "user-guide/tutorials/prowler-app-simple-mutelist",
- "user-guide/tutorials/prowler-app-mute-findings"
+ "user-guide/compliance/tutorials/cross-provider-compliance"
+ ]
+ },
+ {
+ "group": "Findings",
+ "pages": [
+ "user-guide/tutorials/prowler-alerts",
+ "user-guide/tutorials/prowler-app-attack-paths",
+ "user-guide/tutorials/prowler-app-finding-groups",
+ "user-guide/tutorials/prowler-app-findings-triage"
]
},
{
"group": "Integrations",
- "expanded": true,
"pages": [
"user-guide/tutorials/prowler-app-s3-integration",
"user-guide/tutorials/prowler-app-security-hub-integration",
@@ -148,40 +160,64 @@
]
},
{
- "group": "AWS Organizations",
- "expanded": true,
+ "group": "Mutelist",
"pages": [
- "user-guide/tutorials/prowler-cloud-aws-organizations"
+ "user-guide/tutorials/prowler-app-mute-findings",
+ "user-guide/tutorials/prowler-app-simple-mutelist"
]
},
{
- "group": "Lighthouse AI (Prowler Cloud)",
+ "group": "Providers",
+ "pages": [
+ "user-guide/tutorials/prowler-cloud-aws-organizations",
+ "user-guide/tutorials/prowler-cloud-azure-management-groups",
+ "user-guide/tutorials/prowler-cloud-gcp-organizations"
+ ]
+ },
+ {
+ "group": "Scans",
+ "pages": [
+ "user-guide/tutorials/prowler-app-scan-configuration",
+ "user-guide/tutorials/prowler-import-findings",
+ "user-guide/tutorials/prowler-scan-scheduling"
+ ]
+ },
+ {
+ "group": "Tutorials",
+ "pages": [
+ "user-guide/tutorials/aws-organizations-bulk-provisioning",
+ "user-guide/tutorials/bulk-provider-provisioning",
+ "user-guide/tutorials/prowler-app-sso-entra",
+ "user-guide/tutorials/prowler-app-sso-google-workspace"
+ ]
+ }
+ ]
+ },
+ {
+ "group": "Prowler Lighthouse AI",
+ "pages": [
+ {
+ "group": "Prowler Cloud",
"pages": [
"user-guide/tutorials/prowler-cloud-lighthouse-multi-llm"
]
},
{
- "group": "Lighthouse AI (Open Source)",
+ "group": "Prowler Local Server",
"pages": [
"getting-started/products/prowler-lighthouse-ai",
"user-guide/tutorials/prowler-app-lighthouse",
"user-guide/tutorials/prowler-app-lighthouse-multi-llm"
]
- },
- "user-guide/tutorials/prowler-app-attack-paths",
- "user-guide/tutorials/prowler-app-finding-groups",
- "user-guide/tutorials/prowler-cloud-public-ips",
- {
- "group": "Tutorials",
- "pages": [
- "user-guide/tutorials/prowler-app-sso-entra",
- "user-guide/tutorials/prowler-app-sso-google-workspace",
- "user-guide/tutorials/bulk-provider-provisioning",
- "user-guide/tutorials/aws-organizations-bulk-provisioning"
- ]
}
]
},
+ {
+ "group": "Prowler for AI Agents",
+ "pages": [
+ "getting-started/products/prowler-claude-code-plugin"
+ ]
+ },
{
"group": "CI/CD",
"pages": [
@@ -223,6 +259,13 @@
{
"group": "Providers",
"pages": [
+ {
+ "group": "Alibaba Cloud",
+ "pages": [
+ "user-guide/providers/alibabacloud/getting-started-alibabacloud",
+ "user-guide/providers/alibabacloud/authentication"
+ ]
+ },
{
"group": "AWS",
"pages": [
@@ -250,6 +293,27 @@
"user-guide/providers/azure/create-prowler-service-principal"
]
},
+ {
+ "group": "Cloudflare",
+ "pages": [
+ "user-guide/providers/cloudflare/getting-started-cloudflare",
+ "user-guide/providers/cloudflare/authentication"
+ ]
+ },
+ {
+ "group": "E2E Networks",
+ "pages": [
+ "user-guide/providers/e2enetworks/getting-started-e2enetworks",
+ "user-guide/providers/e2enetworks/authentication"
+ ]
+ },
+ {
+ "group": "GitHub",
+ "pages": [
+ "user-guide/providers/github/getting-started-github",
+ "user-guide/providers/github/authentication"
+ ]
+ },
{
"group": "Google Cloud",
"pages": [
@@ -261,10 +325,24 @@
]
},
{
- "group": "Alibaba Cloud",
+ "group": "Google Workspace",
"pages": [
- "user-guide/providers/alibabacloud/getting-started-alibabacloud",
- "user-guide/providers/alibabacloud/authentication"
+ "user-guide/providers/googleworkspace/getting-started-googleworkspace",
+ "user-guide/providers/googleworkspace/authentication"
+ ]
+ },
+ {
+ "group": "IaC",
+ "pages": [
+ "user-guide/providers/iac/getting-started-iac",
+ "user-guide/providers/iac/authentication"
+ ]
+ },
+ {
+ "group": "Image",
+ "pages": [
+ "user-guide/providers/image/getting-started-image",
+ "user-guide/providers/image/authentication"
]
},
{
@@ -274,6 +352,19 @@
"user-guide/providers/kubernetes/misc"
]
},
+ {
+ "group": "Linode",
+ "pages": [
+ "user-guide/providers/linode/getting-started-linode",
+ "user-guide/providers/linode/authentication"
+ ]
+ },
+ {
+ "group": "LLM",
+ "pages": [
+ "user-guide/providers/llm/getting-started-llm"
+ ]
+ },
{
"group": "Microsoft 365",
"pages": [
@@ -282,27 +373,6 @@
"user-guide/providers/microsoft365/use-of-powershell"
]
},
- {
- "group": "Google Workspace",
- "pages": [
- "user-guide/providers/googleworkspace/getting-started-googleworkspace",
- "user-guide/providers/googleworkspace/authentication"
- ]
- },
- {
- "group": "GitHub",
- "pages": [
- "user-guide/providers/github/getting-started-github",
- "user-guide/providers/github/authentication"
- ]
- },
- {
- "group": "IaC",
- "pages": [
- "user-guide/providers/iac/getting-started-iac",
- "user-guide/providers/iac/authentication"
- ]
- },
{
"group": "MongoDB Atlas",
"pages": [
@@ -311,30 +381,11 @@
]
},
{
- "group": "Cloudflare",
+ "group": "Okta",
"pages": [
- "user-guide/providers/cloudflare/getting-started-cloudflare",
- "user-guide/providers/cloudflare/authentication"
- ]
- },
- {
- "group": "Image",
- "pages": [
- "user-guide/providers/image/getting-started-image",
- "user-guide/providers/image/authentication"
- ]
- },
- {
- "group": "LLM",
- "pages": [
- "user-guide/providers/llm/getting-started-llm"
- ]
- },
- {
- "group": "Oracle Cloud Infrastructure",
- "pages": [
- "user-guide/providers/oci/getting-started-oci",
- "user-guide/providers/oci/authentication"
+ "user-guide/providers/okta/getting-started-okta",
+ "user-guide/providers/okta/authentication",
+ "user-guide/providers/okta/retry-configuration"
]
},
{
@@ -344,6 +395,13 @@
"user-guide/providers/openstack/authentication"
]
},
+ {
+ "group": "Oracle Cloud Infrastructure",
+ "pages": [
+ "user-guide/providers/oci/getting-started-oci",
+ "user-guide/providers/oci/authentication"
+ ]
+ },
{
"group": "Scaleway",
"pages": [
@@ -364,28 +422,6 @@
"user-guide/providers/vercel/getting-started-vercel",
"user-guide/providers/vercel/authentication"
]
- },
- {
- "group": "Okta",
- "pages": [
- "user-guide/providers/okta/getting-started-okta",
- "user-guide/providers/okta/authentication",
- "user-guide/providers/okta/retry-configuration"
- ]
- },
- {
- "group": "Linode",
- "pages": [
- "user-guide/providers/linode/getting-started-linode",
- "user-guide/providers/linode/authentication"
- ]
- },
- {
- "group": "E2E Networks",
- "pages": [
- "user-guide/providers/e2enetworks/getting-started-e2enetworks",
- "user-guide/providers/e2enetworks/authentication"
- ]
}
]
},
@@ -503,10 +539,6 @@
"tab": "Changelog",
"icon": "github",
"href": "https://github.com/prowler-cloud/prowler/releases"
- },
- {
- "tab": "Public Roadmap",
- "href": "https://roadmap.prowler.com/"
}
],
"global": {
@@ -542,6 +574,13 @@
}
]
},
+ "banner": {
+ "content": "Prowler App is now Prowler Local Server, and Prowler Enterprise is now Prowler Private Cloud. See [Prowler product families](/getting-started/products).",
+ "dismissible": false
+ },
+ "markdown": {
+ "instructions": "Prowler product naming: Prowler App is now Prowler Local Server, and Prowler Enterprise is now Prowler Private Cloud. Always use the current names when answering. The full product reference is at /getting-started/products: Open Source projects are Prowler CLI, Prowler Local Server, Prowler Local Dashboard, and Prowler SDK; Prowler Products are Prowler Cloud, Prowler Private Cloud, Prowler Hub, Prowler Lighthouse AI, and Prowler MCP."
+ },
"analytics": {
"ga4": {
"measurementId": "G-KBKV70W5Y2"
@@ -622,6 +661,10 @@
{
"source": "/user-guide/tutorials/prowler-app-alerts",
"destination": "/user-guide/tutorials/prowler-alerts"
+ },
+ {
+ "source": "/user-guide/tutorials/prowler-cloud-public-ips",
+ "destination": "/security/networking"
}
]
}
diff --git a/docs/getting-started/basic-usage/prowler-app.mdx b/docs/getting-started/basic-usage/prowler-app.mdx
index bc39353dcc..0f4cf80a91 100644
--- a/docs/getting-started/basic-usage/prowler-app.mdx
+++ b/docs/getting-started/basic-usage/prowler-app.mdx
@@ -2,7 +2,7 @@
title: 'Basic Usage'
---
-## Access Prowler App
+## Access Prowler Local Server
After [installation](/getting-started/installation/prowler-app), navigate to [http://localhost:3000](http://localhost:3000) and sign up with email and password.
@@ -28,7 +28,7 @@ This mechanism ensures that the first user in a newly created tenant has adminis
## Log In
-Access Prowler App by logging in with **email and password**.
+Access Prowler Local Server by logging in with **email and password**.
@@ -62,7 +62,7 @@ Review findings during scan execution in the following sections:
- **Compliance** – Displays compliance insights based on security frameworks.
-> For detailed usage instructions, refer to the [Prowler App Guide](/user-guide/tutorials/prowler-app).
+> For detailed usage instructions, refer to the [Prowler Cloud guide](/user-guide/tutorials/prowler-app), which also applies to Prowler Local Server.
Prowler will automatically scan all configured providers every **24 hours**, ensuring your cloud environment stays continuously monitored.
diff --git a/docs/getting-started/basic-usage/prowler-mcp-tools.mdx b/docs/getting-started/basic-usage/prowler-mcp-tools.mdx
index ec11680dd5..d225617f0e 100644
--- a/docs/getting-started/basic-usage/prowler-mcp-tools.mdx
+++ b/docs/getting-started/basic-usage/prowler-mcp-tools.mdx
@@ -10,7 +10,7 @@ Complete reference guide for all tools available in the Prowler MCP Server. Tool
|----------|------------|------------------------|
| Prowler Hub | 10 tools | No |
| Prowler Documentation | 2 tools | No |
-| Prowler Cloud/App | 32 tools | Yes |
+| Prowler Cloud & Prowler Local Server | 32 tools | Yes |
## Tool Naming Convention
@@ -20,9 +20,9 @@ All tools follow a consistent naming pattern with prefixes:
- `prowler_docs_*` - Prowler documentation search and retrieval
- `prowler_app_*` - Prowler Cloud and App (Self-Managed) management tools
-## Prowler Cloud/App Tools
+## Prowler Cloud and Prowler Local Server Tools
-Manage Prowler Cloud or Prowler App (Self-Managed) features. **Requires authentication.**
+Manage Prowler Cloud or Prowler Local Server features. **Requires authentication.**
These tools require a valid API key. See the [Configuration Guide](/getting-started/basic-usage/prowler-mcp) for authentication setup.
@@ -145,7 +145,7 @@ Search and access official Prowler documentation. **No authentication required.*
- Use natural language to interact with the tools through your AI assistant
- Tools can be combined for complex workflows
- Filter options are available on most list tools
-- Authentication is only required for Prowler Cloud/App tools
+- Authentication is only required for Prowler Cloud and Prowler Local Server tools
## Additional Resources
diff --git a/docs/getting-started/basic-usage/prowler-mcp.mdx b/docs/getting-started/basic-usage/prowler-mcp.mdx
index 2c32dbdbfc..a06f54375e 100644
--- a/docs/getting-started/basic-usage/prowler-mcp.mdx
+++ b/docs/getting-started/basic-usage/prowler-mcp.mdx
@@ -7,10 +7,10 @@ Configure your MCP client to connect to Prowler MCP Server.
## Step 1: Get Your API Key
-**Authentication is optional**: Prowler Hub and Prowler Documentation features work without authentication. An API key is only required for Prowler Cloud and Prowler App (Self-Managed) features.
+**Authentication is optional**: Prowler Hub and Prowler Documentation features work without authentication. An API key is only required for Prowler Cloud and Prowler Local Server features.
-To use Prowler Cloud or Prowler App (Self-Managed) features. To get the API key, please refer to the [API Keys](/user-guide/tutorials/prowler-app-api-keys) guide.
+To use Prowler Cloud or Prowler Local Server features. To get the API key, please refer to the [API Keys](/user-guide/tutorials/prowler-app-api-keys) guide.
Keep the API key secure. Never share it publicly or commit it to version control.
@@ -205,7 +205,7 @@ Restart your MCP client and start asking questions:
## Authentication Methods
-Prowler MCP Server supports two authentication methods to connect to Prowler Cloud or Prowler App (Self-Managed):
+Prowler MCP Server supports two authentication methods to connect to Prowler Cloud or Prowler Local Server:
### API Key (Recommended)
diff --git a/docs/getting-started/installation/prowler-app.mdx b/docs/getting-started/installation/prowler-app.mdx
index fe5281c140..20a45a405a 100644
--- a/docs/getting-started/installation/prowler-app.mdx
+++ b/docs/getting-started/installation/prowler-app.mdx
@@ -4,9 +4,9 @@ title: "Installation"
### Installation
-Prowler App offers flexible installation methods tailored to various environments.
+Prowler Local Server offers flexible installation methods tailored to various environments.
-Refer to the [Prowler App Tutorial](/user-guide/tutorials/prowler-app) for detailed usage instructions.
+Refer to the [Prowler Cloud guide](/user-guide/tutorials/prowler-app) for detailed usage instructions.
Prowler configuration is based on `.env` files. Every version of Prowler can have differences on that file, so, please, use the file that corresponds with that version or repository branch or tag.
@@ -109,17 +109,17 @@ Refer to the [Prowler App Tutorial](/user-guide/tutorials/prowler-app) for detai
pnpm start
```
- > Enjoy Prowler App at http://localhost:3000 by signing up with your email and password.
+ > Enjoy Prowler Local Server at http://localhost:3000 by signing up with your email and password.
- Google and GitHub authentication is only available in [Prowler Cloud](https://prowler.com).
+ Google and GitHub authentication works out of the box in [Prowler Cloud](https://prowler.com). In Prowler Local Server it requires OAuth credentials: see [Social Login Configuration](/user-guide/tutorials/prowler-app-social-login).
-### Updating Prowler App
+### Updating Prowler Local Server
-Upgrade Prowler App installation using one of two options:
+Upgrade Prowler Local Server installation using one of two options:
#### Option 1: Updating the Environment File
@@ -133,7 +133,7 @@ PROWLER_API_VERSION="5.33.0"
```
- You can find the latest versions of Prowler App in the [Releases Github section](https://github.com/prowler-cloud/prowler/releases) or in the [Container Versions](#container-versions) section of this documentation.
+ You can find the latest versions of Prowler Local Server in the [Releases Github section](https://github.com/prowler-cloud/prowler/releases) or in the [Container Versions](#container-versions) section of this documentation.
@@ -172,7 +172,7 @@ docker compose up -d
### Container Versions
-The available versions of Prowler App are the following:
+The available versions of Prowler Local Server are the following:
- `latest`: in sync with `master` branch (please note that it is not a stable version)
- `v4-latest`: in sync with `v4` branch (please note that it is not a stable version)
@@ -184,6 +184,6 @@ The available versions of Prowler App are the following:
The container images are available here:
-- Prowler App:
+- Prowler Local Server:
- [DockerHub - Prowler UI](https://hub.docker.com/r/prowlercloud/prowler-ui/tags)
- [DockerHub - Prowler API](https://hub.docker.com/r/prowlercloud/prowler-api/tags)
diff --git a/docs/getting-started/products/index.mdx b/docs/getting-started/products/index.mdx
new file mode 100644
index 0000000000..54ee8f3a23
--- /dev/null
+++ b/docs/getting-started/products/index.mdx
@@ -0,0 +1,48 @@
+---
+title: 'Prowler Product Families'
+description: 'Official names for Prowler Open Source projects and Prowler Products, including former product names.'
+boost: 2
+---
+
+Prowler ships two product families: Prowler Products, operated or licensed by the Prowler team, and Open Source projects, free to run and extend. This page is the reference for every official name. If a page or blog post uses a former name, the [Former Names](#former-names) table maps it to the current one.
+
+## Prowler Products
+
+| Name | Description |
+|------|-------------|
+| [Prowler Cloud](/getting-started/products/prowler-cloud) | Managed cloud security platform operated by the Prowler team. See [pricing](https://prowler.com/pricing). |
+| Prowler Private Cloud | Prowler Cloud deployed in your own environment. Formerly Prowler Enterprise. See [pricing](https://prowler.com/pricing). |
+| [Prowler Hub](https://hub.prowler.com) | Free public library of versioned checks, cloud service artifacts, and compliance frameworks. |
+| [Prowler Lighthouse AI](/getting-started/products/prowler-cloud-lighthouse) | AI security analyst capabilities within Prowler Cloud and Prowler Private Cloud. |
+| [Prowler MCP](/getting-started/products/prowler-mcp) | MCP server that connects AI assistants and agents to Prowler, including IDE plugins such as [Prowler for Claude Code](/getting-started/products/prowler-claude-code-plugin). |
+
+{/* Unreleased products. Uncomment these rows in the Prowler Products table when announced:
+| Prowler Registry | Distribution service for Prowler content such as checks and compliance frameworks. Free and paid tiers. |
+| Prowler Local Registry | Prowler Registry running in your own environment. Paid. |
+*/}
+
+
+Throughout this documentation, the green cloud icon in the sidebar marks sections and pages for capabilities that require a Prowler Cloud or Prowler Private Cloud [subscription](https://prowler.com/pricing).
+
+
+Products without a documentation page here are available through the Prowler team. [Contact us](https://prowler.com/contact) for details.
+
+## Open Source Projects
+
+| Name | Description |
+|------|-------------|
+| [Prowler CLI](/getting-started/products/prowler-cli) | Command line tool to run security scans across all supported providers. |
+| [Prowler Local Server](/getting-started/products/prowler-app) | Self-hosted web application and API to run scans, visualize findings, and manage cloud providers. Formerly Prowler App. |
+| [Prowler Local Dashboard](/user-guide/cli/tutorials/dashboard) | Local web dashboard to visualize scan results from Prowler CLI CSV outputs. Shipped with Prowler CLI. |
+| [Prowler SDK](/getting-started/products/prowler-sdk) | Python library that powers Prowler CLI and Prowler Local Server. Part of the [prowler repository](https://github.com/prowler-cloud/prowler). |
+
+## Former Names
+
+| Former name | Current name |
+|-------------|--------------|
+| Prowler App | [Prowler Local Server](/getting-started/products/prowler-app) |
+| Prowler Enterprise | Prowler Private Cloud |
+
+## Prowler for MSPs and MSSPs
+
+Prowler partners with managed service providers (MSPs) and managed security service providers (MSSPs) that operate Prowler for their customers. Visit [partners.prowler.com](https://partners.prowler.com) to become a partner.
diff --git a/docs/getting-started/products/prowler-app.mdx b/docs/getting-started/products/prowler-app.mdx
index 2df6015d06..76af591ba0 100644
--- a/docs/getting-started/products/prowler-app.mdx
+++ b/docs/getting-started/products/prowler-app.mdx
@@ -2,16 +2,16 @@
title: 'Overview'
---
-Prowler App is a web application that simplifies running Prowler. It provides:
+Prowler Local Server is a self-hosted web application that simplifies running Prowler. It provides:
- **User-friendly interface** for configuring and executing scans
- Dashboard to **view results** and manage **security findings**
-
+
## Components
-Prowler App consists of four main components:
+Prowler Local Server consists of four main components:
- **Prowler UI**: User-friendly web interface for running Prowler and viewing results, powered by Next.js
- **Prowler API**: Backend API that executes Prowler scans and stores results, built with Django REST Framework
@@ -26,4 +26,42 @@ Supporting infrastructure includes:
- **Valkey**: In-memory database serving as message broker for Celery workers
- **Neo4j**: Graph database used by the Attack Paths feature to combine cloud inventory with Prowler findings (currently populated by AWS scans)
-
+```mermaid
+flowchart TB
+ user([User / Security Team])
+ cli([Prowler CLI])
+
+ subgraph APP["Prowler Local Server"]
+ ui["Prowler UI
(Next.js)"]
+ api["Prowler API
(Django REST Framework)"]
+ worker["API Worker
(Celery)"]
+ beat["API Scheduler
(Celery Beat)"]
+ mcp["Prowler MCP Server
(Lighthouse AI tools)"]
+ end
+
+ sdk["Prowler SDK
(Python)"]
+
+ subgraph DATA["Data Layer"]
+ pg[("PostgreSQL")]
+ valkey[("Valkey / Redis")]
+ neo4j[("Neo4j")]
+ end
+
+ providers["Providers"]
+
+ user --> ui
+ user --> cli
+ ui -->|REST| api
+ ui -->|MCP HTTP| mcp
+ mcp -->|REST| api
+ api --> pg
+ api --> valkey
+ beat -->|enqueue jobs| valkey
+ valkey -->|dispatch| worker
+ worker --> pg
+ worker -->|Attack Paths| neo4j
+ worker -->|invokes| sdk
+ cli --> sdk
+
+ sdk --> providers
+```
diff --git a/docs/getting-started/products/prowler-claude-code-plugin.mdx b/docs/getting-started/products/prowler-claude-code-plugin.mdx
index e3c11ec810..99c92a1488 100644
--- a/docs/getting-started/products/prowler-claude-code-plugin.mdx
+++ b/docs/getting-started/products/prowler-claude-code-plugin.mdx
@@ -1,5 +1,6 @@
---
title: 'Prowler for Claude Code'
+sidebarTitle: 'Claude Code'
---
End-to-end cloud security and compliance from inside [Claude Code](https://www.claude.com/product/claude-code), powered by the [Prowler MCP server](/getting-started/products/prowler-mcp). The plugin lets Claude walk a Prowler Cloud-connected account through a compliance assessment and remediate findings until the chosen security or industry framework is compliant.
diff --git a/docs/getting-started/products/prowler-cli.mdx b/docs/getting-started/products/prowler-cli.mdx
index ac4f37c291..fa75e0456e 100644
--- a/docs/getting-started/products/prowler-cli.mdx
+++ b/docs/getting-started/products/prowler-cli.mdx
@@ -9,12 +9,12 @@ prowler
```

-## Prowler Dashboard
+## Prowler Local Dashboard
```console
prowler dashboard
```
-
+
Prowler includes hundreds of security controls aligned with widely recognized industry frameworks and standards, including:
diff --git a/docs/getting-started/products/prowler-cloud-lighthouse.mdx b/docs/getting-started/products/prowler-cloud-lighthouse.mdx
index 740ba969a9..04bfd58224 100644
--- a/docs/getting-started/products/prowler-cloud-lighthouse.mdx
+++ b/docs/getting-started/products/prowler-cloud-lighthouse.mdx
@@ -75,10 +75,10 @@ No. Lighthouse AI has read-only access to security data and no tools to modify r
## Looking for the Open Source Version?
-Lighthouse AI is also available in the self-hosted, open-source Prowler App. For its capabilities, FAQs, and limitations, see the open-source documentation.
+Lighthouse AI is also available in the open-source Prowler Local Server. For its capabilities, FAQs, and limitations, see the open-source documentation.
- Capabilities, FAQs, and limitations for Lighthouse AI in the open-source Prowler App
+ Capabilities, FAQs, and limitations for Lighthouse AI in the open-source Prowler Local Server
## Getting Help
diff --git a/docs/getting-started/products/prowler-mcp.mdx b/docs/getting-started/products/prowler-mcp.mdx
index 762b088326..b35ac3d611 100644
--- a/docs/getting-started/products/prowler-mcp.mdx
+++ b/docs/getting-started/products/prowler-mcp.mdx
@@ -8,6 +8,10 @@ title: "Overview"
**Preview Feature**: This MCP server is currently under active development. Features and functionality may change. We welcome your feedback—please report any issues on [GitHub](https://github.com/prowler-cloud/prowler/issues) or join our [Slack community](https://goto.prowler.com/slack) to discuss and share your thoughts.
+
+Prowler MCP Server can run as a local instance, or as the hosted **Prowler MCP** at `https://mcp.prowler.com/mcp`. The hosted server also provides tools for Prowler Cloud-specific features such as [Alerts](/user-guide/tutorials/prowler-alerts), [Scan Scheduling](/user-guide/tutorials/prowler-scan-scheduling), and [Findings Triage](/user-guide/tutorials/prowler-app-findings-triage). See [Deployment Options](#deployment-options).
+
+
## What is the Model Context Protocol?
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard developed by Anthropic that enables AI assistants to securely connect to external data sources and tools. It functions as a universal adapter enabling AI assistants to interact with various services through a standardized interface.
@@ -16,9 +20,9 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open s
The Prowler MCP Server provides three main integration points:
-### 1. Prowler Cloud and Prowler App (Self-Managed)
+### 1. Prowler Cloud and Prowler Local Server
-Full access to Prowler Cloud platform and self-managed Prowler App for:
+Full access to Prowler Cloud and Prowler Local Server for:
- **Findings Analysis**: Query, filter, and analyze security findings across all your cloud environments
- **Provider Management**: Create, configure, and manage your configured Prowler providers (AWS, Azure, GCP, etc.)
- **Scan Orchestration**: Trigger on-demand scans and schedule recurring security assessments
@@ -29,7 +33,7 @@ Full access to Prowler Cloud platform and self-managed Prowler App for:
### 2. Prowler Hub
Access to Prowler's comprehensive security knowledge base:
-- **Security Checks Catalog**: Browse and search **over 1000 security checks** across multiple cloud providers.
+- **Security Checks Catalog**: Browse and search **over 2,000 security checks** across multiple cloud providers.
- **Check Implementation**: View the Python code that powers each security check.
- **Automated Fixers**: Access remediation scripts for common security issues.
- **Compliance Frameworks**: Explore mappings to **over 70 compliance standards and frameworks**.
@@ -49,7 +53,7 @@ The following diagram illustrates the Prowler MCP Server architecture and its in

The architecture shows how AI assistants connect through the MCP protocol to access Prowler's three main components:
-- Prowler Cloud/App for security operations
+- Prowler Cloud and Prowler Local Server for security operations
- Prowler Hub for security knowledge
- Prowler Documentation for guidance and reference.
@@ -136,15 +140,16 @@ Prowler MCP Server can be used in three ways:
- No installation required.
- Managed and maintained by Prowler team.
-- Authentication to Prowler Cloud or Prowler App (self-managed) via API key or JWT token.
+- Authentication to Prowler Cloud or Prowler Local Server via API key or JWT token.
+- Includes tools for Prowler Cloud-specific features such as Alerts, Scan Scheduling, and Findings Triage.
### 2. Local STDIO Mode
**Run the server locally on your machine**
-- Runs as a subprocess of your MCP client.
-- Possibility to connect to a self-hosted Prowler App (e.g. self-hosted Prowler App).
-- Authentication to Prowler Cloud or Prowler App (self-managed) via environment variables.
+- Runs as a subprocess of the MCP client.
+- Possibility to connect to Prowler Local Server.
+- Authentication to Prowler Cloud or Prowler Local Server via environment variables.
- Requires Python 3.12+ or Docker.
### 3. Self-Hosted HTTP Mode
@@ -152,8 +157,8 @@ Prowler MCP Server can be used in three ways:
**Deploy your own remote MCP server**
- Full control over deployment.
-- Possibility to connect to a self-hosted Prowler App (e.g. self-hosted Prowler App).
-- Authentication to Prowler App (self-managed) via API key or JWT token.
+- Possibility to connect to Prowler Local Server.
+- Authentication to Prowler Local Server via API key or JWT token.
- Requires Python 3.12+ or Docker.
## Requirements
@@ -161,17 +166,17 @@ Prowler MCP Server can be used in three ways:
Requirements vary based on deployment option:
**For Prowler Cloud MCP Server:**
-- Prowler Cloud account and API key (only for Prowler Cloud/App features)
+- Prowler Cloud account and API key (only for Prowler Cloud and Prowler Local Server features)
**For self-hosted STDIO/HTTP Mode:**
- Python 3.12+ or Docker
- Network access to:
- `https://hub.prowler.com` (for Prowler Hub)
- `https://docs.prowler.com` (for Prowler Documentation)
- - Prowler Cloud API or self-hosted Prowler App API (for Prowler Cloud/App features)
+ - Prowler Cloud API or Prowler Local Server API (for Prowler Cloud and Prowler Local Server features)
-**No Authentication Required**: Prowler Hub and Prowler Documentation features work without authentication in both deployment options. A Prowler API key is only required to access Prowler Cloud or Prowler App (Self-Managed) features.
+**No Authentication Required**: Prowler Hub and Prowler Documentation features work without authentication in both deployment options. A Prowler API key is only required to access Prowler Cloud or Prowler Local Server features.
## Next Steps
diff --git a/docs/getting-started/products/prowler-sdk.mdx b/docs/getting-started/products/prowler-sdk.mdx
new file mode 100644
index 0000000000..b19f576e12
--- /dev/null
+++ b/docs/getting-started/products/prowler-sdk.mdx
@@ -0,0 +1,11 @@
+---
+title: 'Prowler SDK'
+---
+
+Prowler SDK is the Python library that powers Prowler CLI and Prowler Local Server. It implements the providers, services, and security checks that every Prowler product runs.
+
+To use or extend Prowler SDK, start with the Developer Guide:
+
+
+ Providers, services, checks, and testing: everything needed to work with Prowler SDK.
+
diff --git a/docs/images/icons/cloud-bold.svg b/docs/images/icons/cloud-bold.svg
new file mode 100644
index 0000000000..623bb36c11
--- /dev/null
+++ b/docs/images/icons/cloud-bold.svg
@@ -0,0 +1 @@
+
diff --git a/docs/images/products/prowler-app-architecture.mmd b/docs/images/products/prowler-app-architecture.mmd
index 0c13d580c3..da99d0ab96 100644
--- a/docs/images/products/prowler-app-architecture.mmd
+++ b/docs/images/products/prowler-app-architecture.mmd
@@ -1,8 +1,10 @@
+%% Source of truth for the architecture diagram.
+%% Inlined as native mermaid blocks in the root README.md and in docs/getting-started/products/prowler-app.mdx: keep all copies in sync.
flowchart TB
user([User / Security Team])
cli([Prowler CLI])
- subgraph APP["Prowler App"]
+ subgraph APP["Prowler Local Server"]
ui["Prowler UI
(Next.js)"]
api["Prowler API
(Django REST Framework)"]
worker["API Worker
(Celery)"]
diff --git a/docs/introduction.mdx b/docs/introduction.mdx
index c31ec2c864..9307fa351a 100644
--- a/docs/introduction.mdx
+++ b/docs/introduction.mdx
@@ -1,21 +1,36 @@
# What is Prowler?
-**Prowler** is the world’s most widely used open-source cloud security platform that **automates security and compliance** across any cloud environment. With hundreds of ready-to-use security checks, remediation guidance, and compliance frameworks, Prowler delivers AI-driven, customizable, and easy-to-use monitoring and integrations, making cloud security simple, scalable, and cost-effective for organizations of any size.
+**Prowler** is the world’s most widely used open-source cloud security platform that **automates security and compliance** across any cloud environment. With thousands of ready-to-use security checks, remediation guidance, and compliance frameworks, Prowler delivers AI-driven, customizable, and easy-to-use monitoring and integrations, making cloud security simple, scalable, and cost-effective for organizations of any size.

+Prowler ships two product families: Prowler Products, operated or licensed by the Prowler team, and Open Source projects, free to run and extend. See [Prowler product families](/getting-started/products) for every official name, including former names.
+
+### Prowler Products
+
-
- Command Line Interface
-
-
- Web Application
-
-
- A managed service built on top of Prowler App.
+
+ Managed cloud security platform operated by the Prowler team.
- A public library of versioned checks, cloud service artifacts, and compliance frameworks.
+ Free public library of versioned checks, cloud service artifacts, and compliance frameworks.
+
+
+ MCP server that connects AI assistants and agents to Prowler.
+
+
+ Prowler Private Cloud, Prowler Lighthouse AI, and more.
+
+
+
+### Open Source
+
+
+
+ Command line tool to run security scans across all supported providers.
+
+
+ Self-hosted web application and API.
@@ -70,7 +85,7 @@ Prowler supports a wide range of providers organized by category:
| ------------------------------------------------------------------- | -------- | -------------------- | --------- |
| [Image](/user-guide/providers/image/getting-started-image) | Official | Container Images / Registries | CLI, API |
-### Custom Providers (Prowler Cloud Enterprise Only)
+### Custom Providers (Prowler Private Cloud Only)
| Provider | Support | Audit Scope/Entities | Interface |
| -------------------- | -------- | -------------------- | --------- |
diff --git a/docs/scripts/generate_provider_cards.py b/docs/scripts/generate_provider_cards.py
index 3b02574978..1b35755507 100644
--- a/docs/scripts/generate_provider_cards.py
+++ b/docs/scripts/generate_provider_cards.py
@@ -2,7 +2,7 @@
"""Generate docs/snippets/provider-cards.mdx from provider getting-started pages.
Scans docs/user-guide/providers//getting-started-*.mdx, keeps only the
-providers that Prowler App/Cloud actually supports (source of truth: the
+providers that Prowler Cloud and Prowler Local Server actually support (source of truth: the
`ProviderChoices` enum in api/src/backend/api/models.py — CLI-only providers
such as Linode/LLM/Scaleway/StackIT are excluded), reads the frontmatter
`title`, derives a display name, and emits a snippet exporting a
diff --git a/docs/security/index.mdx b/docs/security/index.mdx
index 30364d5b82..45b39d608b 100644
--- a/docs/security/index.mdx
+++ b/docs/security/index.mdx
@@ -27,7 +27,7 @@ All Prowler code goes through the same security pipeline, whether running on Pro
| **Updates** | Automatic | Manual |
-Self-Managed includes Prowler App and Prowler CLI. They can run anywhere — any cloud provider, any region, on-premises, or air-gapped environments. Full control over data residency and infrastructure decisions. See the [Prowler App Installation Guide](/getting-started/installation/prowler-app) to get started.
+Self-Managed includes Prowler Local Server and Prowler CLI. They can run anywhere — any cloud provider, any region, on-premises, or air-gapped environments. Full control over data residency and infrastructure decisions. See the [Prowler Local Server Installation Guide](/getting-started/installation/prowler-app) to get started.
---
diff --git a/docs/security/networking.mdx b/docs/security/networking.mdx
index 767e6ac4bf..eb00c9a840 100644
--- a/docs/security/networking.mdx
+++ b/docs/security/networking.mdx
@@ -16,6 +16,18 @@ Resolve the egress IP via DNS:
dig egress.prowler.com +short
```
+
+The egress IP address is stable, but it is recommended to periodically verify it remains current by querying `egress.prowler.com`.
+
+
+## Use Cases
+
+Allowlisting Prowler Cloud's egress IP address enables:
+
+- **Credential Usage Control**: Restrict where cloud provider credentials can be used from across AWS, Azure, GCP, and other providers
+- **Kubernetes Security**: Limit inbound HTTPS traffic to clusters by allowing only Prowler Cloud's IP address
+- **Compliance Requirements**: Meet security policies requiring allowlisting of external services
+
## Contact
For questions about networking, visit the [Support page](/support).
diff --git a/docs/snippets/applies-to.mdx b/docs/snippets/applies-to.mdx
new file mode 100644
index 0000000000..0ce22af78d
--- /dev/null
+++ b/docs/snippets/applies-to.mdx
@@ -0,0 +1,14 @@
+export const AppliesTo = ({ products = ["Prowler Cloud", "Prowler Private Cloud", "Prowler Local Server"] }) => {
+ return (
+
+ This guide applies to{" "}
+ {products.map((name, index) => (
+
+ {index > 0 && (index === products.length - 1 ? (products.length > 2 ? ", and " : " and ") : ", ")}
+ {name}
+
+ ))}
+ . See Prowler product families.
+
+ );
+};
diff --git a/docs/snippets/subscription-banner.mdx b/docs/snippets/subscription-banner.mdx
index 8313997c84..90d9b651b5 100644
--- a/docs/snippets/subscription-banner.mdx
+++ b/docs/snippets/subscription-banner.mdx
@@ -1,7 +1,7 @@
-export const SubscriptionBanner = ({ children }) => {
+export const SubscriptionBanner = ({ children, label = "feature" }) => {
return (
- This feature is available exclusively in Prowler Cloud and Prowler Enterprise with a subscription.
+ This {label} is available exclusively in Prowler Cloud and Prowler Private Cloud with a subscription.
{children}
);
diff --git a/docs/style.css b/docs/style.css
index 5c626fb06b..9585e7cdeb 100644
--- a/docs/style.css
+++ b/docs/style.css
@@ -66,3 +66,60 @@
color: #000000;
border: none;
}
+
+/* Cloud marker: subscription-gated sections and pages (Prowler Cloud / Prowler Private Cloud).
+ Rendered as a trailing ::after glyph so sidebar labels stay left-aligned.
+ Nested groups render as li[data-title] with a button toggle; top-level groups
+ render as h3 headings. Every ungated group that shares a name with a gated one
+ (Providers, Compliance, Prowler Cloud, Prowler Lighthouse AI) is top-level,
+ so plain li[data-title] selectors match only the gated nested groups, folded
+ or unfolded. The Security tab group is top-level (h3) and always expanded,
+ so it is selected through its sibling list content with :has().
+ Pages are selected by their li id, which equals the page URL. The strict
+ > div > div > span:first-child path targets the title span only, never the
+ nested spans of a tag pill such as Coming Soon.
+ Icon source: /images/icons/cloud-bold.svg. See AGENTS.md "Cloud Marker" convention. */
+li[data-title="Prowler Cloud"] > button span:first-child::after,
+li[data-title="Prowler Lighthouse AI"] > button span:first-child::after,
+li[data-title="Providers"] > button span:first-child::after,
+li[data-title="Compliance"] > button span:first-child::after,
+li[data-title="Scans"] > button span:first-child::after,
+li[data-title="Prowler MCP"] > button span:first-child::after,
+div:has(+ ul a[href="/security/encryption"]) h3 span::after,
+li[id="/user-guide/compliance/tutorials/cross-provider-compliance"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-alerts"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-app-findings-triage"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-app-scan-configuration"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-cloud-aws-organizations"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-cloud-azure-management-groups"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-cloud-gcp-organizations"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-cloud-lighthouse-multi-llm"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-import-findings"] a > div > div > span:first-child::after,
+li[id="/user-guide/tutorials/prowler-scan-scheduling"] a > div > div > span:first-child::after {
+ content: "";
+ display: inline-block;
+ width: 0.875rem;
+ height: 0.875rem;
+ margin-left: 0.375rem;
+ vertical-align: -0.125rem;
+ background: url("/images/icons/cloud-bold.svg") no-repeat center / contain;
+}
+/* Wider sidebar: +2rem over the theme default (18rem) so gated labels with the
+ cloud marker fit on one line. The content column offsets are coupled to the
+ sidebar width and must shift by the same amount, hence the two companion
+ overrides selected by their Tailwind arbitrary-value class substrings. */
+@media (min-width: 1024px) {
+ #sidebar {
+ width: 20rem !important;
+ }
+
+ div[class*="pl-[23.7rem]"] {
+ padding-left: 25.7rem !important;
+ }
+}
+
+@media (min-width: 1280px) {
+ div[class*="(100%-28rem)"] {
+ width: calc(100% - 30rem) !important;
+ }
+}
diff --git a/docs/support.mdx b/docs/support.mdx
index 6999d5efbf..07c9843e12 100644
--- a/docs/support.mdx
+++ b/docs/support.mdx
@@ -3,23 +3,25 @@ title: 'Support'
description: 'Get help with Prowler'
---
-## Lighthouse AI
+import { SubscriptionBanner } from "/snippets/subscription-banner.mdx"
-Lighthouse AI is a Cloud Security Analyst chatbot powered by [Prowler MCP](/getting-started/products/prowler-mcp), your 24/7 virtual cloud security analyst. It can:
+## Prowler Lighthouse AI
+
+Prowler Lighthouse AI is your 24/7 cloud security analyst chatbot, the agentic cloud defender. Powered by [Prowler MCP](/getting-started/products/prowler-mcp), it can:
- **Query your security data**: Findings, compliance status, resources, and remediation guidance
-- **Search Prowler Hub**: Over 1,000 security checks and 70+ compliance frameworks
+- **Search Prowler Hub**: Over 2,000 security checks and 70+ compliance frameworks
- **Access documentation**: Search and retrieve Prowler docs contextually
-Available in Prowler Cloud and Prowler App.
+Available in Prowler Cloud, Prowler Private Cloud, and Prowler Local Server.
-[Learn more about Lighthouse AI](/getting-started/products/prowler-lighthouse-ai)
+[Learn more about Prowler Lighthouse AI](/getting-started/products/prowler-cloud-lighthouse)
## Support Desk
-> Available to **Prowler Cloud** customers.
+
-For Prowler Cloud customers, submit support requests through our support desk. We'll route your request to the right team and respond via email.
+Submit support requests through our support desk. We'll route your request to the right team and respond via email.
Contact our support team
diff --git a/docs/troubleshooting.mdx b/docs/troubleshooting.mdx
index 3125d74ef5..9e0c849796 100644
--- a/docs/troubleshooting.mdx
+++ b/docs/troubleshooting.mdx
@@ -4,7 +4,9 @@ title: 'Troubleshooting'
import { VersionBadge } from "/snippets/version-badge.mdx"
-## Running `prowler` I get `[File: utils.py:15] [Module: utils] CRITICAL: path/redacted: OSError[13]`
+## Prowler CLI
+
+### Running `prowler` I get `[File: utils.py:15] [Module: utils] CRITICAL: path/redacted: OSError[13]`
That is an error related to file descriptors or opened files allowed by your operating system.
@@ -16,13 +18,15 @@ This error is also related with a lack of system requirements. To improve perfor
See section [Logging](/user-guide/cli/tutorials/logging) for further information or [contact us](/contact).
-## Common Issues with Docker Compose Installation
+## Prowler Local Server
+
+Common issues with the Docker Compose installation of Prowler Local Server.
### Problem adding AWS Provider using "Connect assuming IAM Role" in Docker
See [GitHub Issue #7745](https://github.com/prowler-cloud/prowler/issues/7745) for more details.
-When running Prowler App via Docker, you may encounter errors such as `Provider not set`, `AWS assume role error - Unable to locate credentials`, or `Provider has no secret` when trying to add an AWS Provider using the "Connect assuming IAM Role" option. This typically happens because the container does not have access to the necessary AWS credentials or profiles.
+When running Prowler Local Server via Docker, you may encounter errors such as `Provider not set`, `AWS assume role error - Unable to locate credentials`, or `Provider has no secret` when trying to add an AWS Provider using the "Connect assuming IAM Role" option. This typically happens because the container does not have access to the necessary AWS credentials or profiles.
**Workaround:**
@@ -53,7 +57,7 @@ AWS_PROFILE=prowler-profile
### Scans Complete but Reports Are Missing or Compliance Data Is Empty (`Too many open files` Error)
-When running Prowler App via Docker Compose, scans may complete successfully but reports are not available for download, compliance data shows as empty, or 404 errors appear when trying to access scan reports. Checking the `worker` container logs may reveal errors like `[Errno 24] Too many open files`.
+When running Prowler Local Server via Docker Compose, scans may complete successfully but reports are not available for download, compliance data shows as empty, or 404 errors appear when trying to access scan reports. Checking the `worker` container logs may reveal errors like `[Errno 24] Too many open files`.
This issue occurs because the default file descriptor limits in Docker containers are too low for Prowler's operations. The default `docker-compose.yml` already includes `ulimits` configuration with `nofile` set to `65536` for the `worker` and `worker-beat` services to prevent this issue.
@@ -87,7 +91,7 @@ docker compose up -d
-When Prowler App runs self-hosted on a machine or Kubernetes node with many CPUs,
+When Prowler Local Server runs on a machine or Kubernetes node with many CPUs,
the Celery worker may create one prefork process per detected CPU if concurrency
is not configured explicitly. Each process loads the SDK runtime and cloud
provider clients, so idle memory can be high and worker containers can be
@@ -196,7 +200,7 @@ A fix addressing this permission issue is being evaluated in [PR #9953](https://
### Scan Stuck in Executing State After Worker Crash
-When running Prowler App via Docker Compose, a scan may remain indefinitely in the `executing` state if the worker process crashes (for example, due to an Out of Memory condition) before it can update the scan status. Since it is not currently possible to cancel a scan in `executing` state through the UI, the workaround is to manually update the scan record in the database.
+When running Prowler Local Server via Docker Compose, a scan may remain indefinitely in the `executing` state if the worker process crashes (for example, due to an Out of Memory condition) before it can update the scan status. Since it is not currently possible to cancel a scan in `executing` state through the UI, the workaround is to manually update the scan record in the database.
**Root Cause:**
diff --git a/docs/user-guide/cli/tutorials/dashboard.mdx b/docs/user-guide/cli/tutorials/dashboard.mdx
index 0fe3c69fed..abb3872657 100644
--- a/docs/user-guide/cli/tutorials/dashboard.mdx
+++ b/docs/user-guide/cli/tutorials/dashboard.mdx
@@ -1,8 +1,8 @@
---
-title: "Dashboard"
+title: "Prowler Local Dashboard"
---
-Prowler allows you to run your own local dashboards using the csv outputs provided by Prowler
+Prowler Local Dashboard is a local web dashboard built from the CSV outputs produced by Prowler CLI. Launch it with:
```sh
prowler dashboard
@@ -12,7 +12,7 @@ prowler dashboard
You can expose the `dashboard` server in another address using the `HOST` environment variable.
-To run Prowler local dashboard with Docker, use:
+To run Prowler Local Dashboard with Docker, use:
```sh
docker run -v /your/local/dir/prowler-output:/home/prowler/output --env HOST=0.0.0.0 --publish 127.0.0.1:11666:11666 toniblyx/prowler:latest dashboard
diff --git a/docs/user-guide/compliance/tutorials/compliance.mdx b/docs/user-guide/compliance/tutorials/compliance.mdx
index e1ec152afb..9ee5df438d 100644
--- a/docs/user-guide/compliance/tutorials/compliance.mdx
+++ b/docs/user-guide/compliance/tutorials/compliance.mdx
@@ -1,9 +1,9 @@
---
title: 'Compliance'
-description: 'Run security checks against compliance frameworks, review posture across providers, and download CSV or PDF reports from Prowler Cloud, Prowler App, and Prowler CLI.'
+description: 'Run security checks against compliance frameworks, review posture across providers, and download CSV or PDF reports from Prowler Cloud and Prowler Local Server, or CSV reports from Prowler CLI.'
---
-Prowler maps every security check to one or more industry-standard compliance frameworks, so a single scan produces both technical findings and framework-aligned evidence. The same evaluation runs identically whether scans are launched from Prowler Cloud, Prowler App, or Prowler CLI.
+Prowler maps every security check to one or more industry-standard compliance frameworks, so a single scan produces both technical findings and framework-aligned evidence. The same evaluation runs identically whether scans are launched from Prowler Cloud, Prowler Local Server, or Prowler CLI.
Out of the box, Prowler covers frameworks such as CIS Benchmarks, NIST 800-53, NIST CSF, NIS2, ENS RD2022, ISO 27001, PCI-DSS, SOC 2, GDPR, HIPAA, AWS Well-Architected, BSI C5, CSA CCM, MITRE ATT&CK, KISA ISMS-P, FedRAMP, and Prowler ThreatScore. The full catalog is available at [Prowler Hub](https://hub.prowler.com/compliance).
@@ -20,15 +20,15 @@ For the unified compliance score methodology used across frameworks, see [Prowle
-## Prowler Cloud
+## Prowler Cloud and Prowler Local Server
-The Compliance section in Prowler Cloud and Prowler App centralizes compliance posture across every connected provider. It aggregates scan results, surfaces Prowler ThreatScore, and exposes detailed requirement-level evidence for each supported framework.
+The Compliance section in Prowler Cloud and Prowler Local Server centralizes compliance posture across every connected provider. It aggregates scan results, surfaces Prowler ThreatScore, and exposes detailed requirement-level evidence for each supported framework.
### Accessing the Compliance Section
To open the compliance overview, follow these steps:
-1. Sign in to Prowler Cloud at [cloud.prowler.com](https://cloud.prowler.com/sign-in) or to a self-hosted Prowler App instance.
+1. Sign in to Prowler Cloud at [cloud.prowler.com](https://cloud.prowler.com/sign-in) or to a Prowler Local Server instance.
2. Select **Compliance** from the left navigation.
The page lists every framework evaluated by the most recent completed scan of the selected provider.
@@ -169,7 +169,7 @@ Region filters disable the per-card download dropdown to avoid generating partia
#### Downloading the Full Scan Output
-To export every framework, finding, and resource at once, use the **Scan Jobs** section instead. The ZIP archive contains the CSV, JSON-OCSF, and HTML reports plus a `compliance/` subfolder with one CSV per framework. See [Prowler App — Getting Started](/user-guide/tutorials/prowler-app) for details.
+To export every framework, finding, and resource at once, use the **Scan Jobs** section instead. The ZIP archive contains the CSV, JSON-OCSF, and HTML reports plus a `compliance/` subfolder with one CSV per framework. See [Prowler Cloud — Getting Started](/user-guide/tutorials/prowler-app) for details.
### API Access
@@ -265,4 +265,4 @@ To request a new framework or contribute one, see [Creating a New Security Compl
* [Cross-Provider Compliance](/user-guide/compliance/tutorials/cross-provider-compliance)
* [Prowler ThreatScore Documentation](/user-guide/compliance/tutorials/threatscore)
* [Creating a New Security Compliance Framework in Prowler](/developer-guide/security-compliance-framework)
-* [Prowler App — Getting Started](/user-guide/tutorials/prowler-app)
+* [Prowler Cloud — Getting Started](/user-guide/tutorials/prowler-app)
diff --git a/docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx b/docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx
index 617a3680ed..b05fb6b5be 100644
--- a/docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx
+++ b/docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx
@@ -1,5 +1,6 @@
---
title: 'Cross-Provider Compliance'
+sidebarTitle: 'Cross-Provider Compliance'
description: 'Aggregate a single universal compliance framework across every connected provider in Prowler Cloud, review a consolidated roll-up and per-provider breakdown, and download a combined PDF report.'
---
@@ -205,4 +206,4 @@ The PDF detail section renders only **failed** requirements by default so the re
* [Compliance](/user-guide/compliance/tutorials/compliance)
* [Prowler ThreatScore Documentation](/user-guide/compliance/tutorials/threatscore)
* [Creating a New Security Compliance Framework in Prowler](/developer-guide/security-compliance-framework)
-* [Prowler App — Getting Started](/user-guide/tutorials/prowler-app)
+* [Prowler Cloud — Getting Started](/user-guide/tutorials/prowler-app)
diff --git a/docs/user-guide/cookbooks/powerbi-cis-benchmarks.mdx b/docs/user-guide/cookbooks/powerbi-cis-benchmarks.mdx
index 9b9e41ed93..15985aab28 100644
--- a/docs/user-guide/cookbooks/powerbi-cis-benchmarks.mdx
+++ b/docs/user-guide/cookbooks/powerbi-cis-benchmarks.mdx
@@ -14,7 +14,7 @@ The template and its source files live in the Prowler repository under [`contrib
The setup requires the following components:
* **Microsoft Power BI Desktop:** free download from Microsoft.
-* **Prowler compliance CSV exports:** produced by Prowler CLI or downloaded from Prowler Cloud or Prowler App.
+* **Prowler compliance CSV exports:** produced by Prowler CLI or downloaded from Prowler Cloud or Prowler Local Server.
* **Local directory:** holds the CSV exports that the template ingests at load time.
## Supported CIS Benchmarks
@@ -40,7 +40,7 @@ Download and install Microsoft Power BI Desktop from the official Microsoft site
### Step 2: Generate Compliance CSV Exports
-Compliance CSV exports can be generated through Prowler CLI or downloaded from Prowler Cloud and Prowler App.
+Compliance CSV exports can be generated through Prowler CLI or downloaded from Prowler Cloud and Prowler Local Server.
#### Option A: Prowler CLI
@@ -55,7 +55,7 @@ prowler kubernetes --compliance cis_1.12_kubernetes
The compliance CSV exports are written to `output/compliance/` by default.
-#### Option B: Prowler Cloud or Prowler App
+#### Option B: Prowler Cloud or Prowler Local Server
Open the Compliance section, select the desired CIS Benchmark, and download the CSV export.
@@ -160,7 +160,7 @@ A full walkthrough is available on YouTube:
- Review the Compliance workflow across Prowler Cloud, Prowler App, and Prowler CLI.
+ Review the Compliance workflow across Prowler Cloud, Prowler Local Server, and Prowler CLI.
Explore the built-in local dashboard for Prowler CSV exports.
diff --git a/docs/user-guide/providers/alibabacloud/getting-started-alibabacloud.mdx b/docs/user-guide/providers/alibabacloud/getting-started-alibabacloud.mdx
index 353515c605..ce9778a3b5 100644
--- a/docs/user-guide/providers/alibabacloud/getting-started-alibabacloud.mdx
+++ b/docs/user-guide/providers/alibabacloud/getting-started-alibabacloud.mdx
@@ -39,7 +39,7 @@ Before you begin, make sure you have:
### Step 2: Access Prowler Cloud
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Go to "Configuration" > "Providers"

diff --git a/docs/user-guide/providers/aws/authentication.mdx b/docs/user-guide/providers/aws/authentication.mdx
index 22deb6ab99..e3c20ca99d 100644
--- a/docs/user-guide/providers/aws/authentication.mdx
+++ b/docs/user-guide/providers/aws/authentication.mdx
@@ -7,9 +7,9 @@ Prowler requires AWS credentials to function properly. Authentication is availab
- Static Credentials
- Assumed Role
-When using **Assumed Role**, the Prowler UI exposes two credential sources for calling `sts:AssumeRole`. The labels differ between Prowler Cloud and self-hosted Prowler App, but both map to the same underlying credential types:
+When using **Assumed Role**, the Prowler UI exposes two credential sources for calling `sts:AssumeRole`. The labels differ between Prowler Cloud and Prowler Local Server, but both map to the same underlying credential types:
-- **AWS SDK Default** (shown as *"Prowler Cloud will assume your IAM role"* in Prowler Cloud and *"AWS SDK Default"* in self-hosted Prowler App): Prowler uses the credentials already available to the API and worker containers through the [AWS SDK default credential chain](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html). This is the default in Prowler Cloud and requires extra configuration in self-hosted Prowler App (see [Configuring AWS SDK Default for Self-Hosted Prowler App](#configuring-aws-sdk-default-for-self-hosted-prowler-app)).
+- **AWS SDK Default** (shown as *"Prowler Cloud will assume your IAM role"* in Prowler Cloud and *"AWS SDK Default"* in Prowler Local Server): Prowler uses the credentials already available to the API and worker containers through the [AWS SDK default credential chain](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html). This is the default in Prowler Cloud and requires extra configuration in Prowler Local Server (see [Configuring AWS SDK Default for Prowler Local Server](#configuring-aws-sdk-default-for-prowler-local-server)).
- **Access & Secret Key**: You paste an IAM user's `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and optionally `AWS_SESSION_TOKEN` into the form. Prowler uses those keys to call `sts:AssumeRole`.
## Required Permissions
@@ -81,9 +81,9 @@ This method grants permanent access and is the recommended setup for production
---
-## Configuring AWS SDK Default for Self-Hosted Prowler App
+## Configuring AWS SDK Default for Prowler Local Server
-When self-hosting Prowler App with Docker Compose, the API and worker containers do not have AWS credentials by default. Selecting **AWS SDK Default** without configuring those credentials produces:
+When running Prowler Local Server with Docker Compose, the API and worker containers do not have AWS credentials by default. Selecting **AWS SDK Default** without configuring those credentials produces:
```
AWSAssumeRoleError[1012]: AWS assume role error - An error occurred (InvalidClientTokenId) when calling the AssumeRole operation: The security token included in the request is invalid.
@@ -116,7 +116,7 @@ docker compose up -d --force-recreate api worker worker-beat
### Option 2: IAM Role (Host with Instance Metadata)
-If you run Prowler App on an EC2 instance, ECS task, or EKS pod with an attached IAM role that can assume the scan role, no extra configuration is needed — `boto3` resolves credentials through instance or task metadata automatically.
+If you run Prowler Local Server on an EC2 instance, ECS task, or EKS pod with an attached IAM role that can assume the scan role, no extra configuration is needed — `boto3` resolves credentials through instance or task metadata automatically.
### Trust Policy: Align `IAMPrincipal` With Your Identity
diff --git a/docs/user-guide/providers/aws/getting-started-aws.mdx b/docs/user-guide/providers/aws/getting-started-aws.mdx
index 847e7b6167..11516e88b3 100644
--- a/docs/user-guide/providers/aws/getting-started-aws.mdx
+++ b/docs/user-guide/providers/aws/getting-started-aws.mdx
@@ -18,7 +18,7 @@ title: 'Getting Started With AWS on Prowler'
### Step 2: Access Prowler Cloud
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Go to "Configuration" > "Providers"

@@ -75,13 +75,13 @@ For detailed instructions on how to create the role, see [Authentication > Assum

-9. Paste the ARN into the corresponding field in Prowler Cloud or Prowler App
+9. Paste the ARN into the corresponding field in Prowler Cloud or Prowler Local Server

10. Select the credential source Prowler should use to call `sts:AssumeRole`. The option label differs between deployments but both map to the same `aws-sdk-default` credential type:
- - **"Prowler Cloud will assume your IAM role"** (default in Prowler Cloud) / **"AWS SDK Default"** (in self-hosted Prowler App): Prowler uses the credentials available in the API and worker environment through the [AWS SDK default credential chain](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html). In self-hosted Prowler App, these containers have no AWS credentials by default — see [Configuring AWS SDK Default for Self-Hosted Prowler App](/user-guide/providers/aws/authentication#configuring-aws-sdk-default-for-self-hosted-prowler-app) before choosing this option, or the connection test will fail with `InvalidClientTokenId`.
+ - **"Prowler Cloud will assume your IAM role"** (default in Prowler Cloud) / **"AWS SDK Default"** (in Prowler Local Server): Prowler uses the credentials available in the API and worker environment through the [AWS SDK default credential chain](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html). In Prowler Local Server, these containers have no AWS credentials by default — see [Configuring AWS SDK Default for Prowler Local Server](/user-guide/providers/aws/authentication#configuring-aws-sdk-default-for-prowler-local-server) before choosing this option, or the connection test will fail with `InvalidClientTokenId`.
- **Access & Secret Key**: Paste an IAM user's `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` (and optional `AWS_SESSION_TOKEN`) into the form. The IAM principal must be allowed to assume the target role and must match the `IAMPrincipal` parameter of the scan role template (default: `role/prowler*`).
11. Click "Next", then "Launch Scan"
@@ -110,7 +110,7 @@ AWS accounts can also be configured using static credentials (not recommended fo
For detailed instructions on how to create the credentials, see [Authentication > Credentials](/user-guide/providers/aws/authentication#credentials).
-1. Complete the form in Prowler Cloud or Prowler App and click "Next"
+1. Complete the form in Prowler Cloud or Prowler Local Server and click "Next"

diff --git a/docs/user-guide/providers/aws/organizations.mdx b/docs/user-guide/providers/aws/organizations.mdx
index bbdedef50b..c0e9ae0e6b 100644
--- a/docs/user-guide/providers/aws/organizations.mdx
+++ b/docs/user-guide/providers/aws/organizations.mdx
@@ -5,7 +5,7 @@ title: 'AWS Organizations in Prowler'
**Using Prowler Cloud?** You can onboard your entire AWS Organization through the UI with automatic account discovery, OU-aware tree selection, and bulk connection testing — no scripts or YAML files required.
-See [AWS Organizations in Prowler Cloud](/user-guide/tutorials/prowler-cloud-aws-organizations) for the full walkthrough.
+See [AWS Organizations](/user-guide/tutorials/prowler-cloud-aws-organizations) in Prowler Cloud for the full walkthrough.
Prowler can integrate with AWS Organizations to manage the visibility and onboarding of accounts centrally.
diff --git a/docs/user-guide/providers/aws/regions-and-partitions.mdx b/docs/user-guide/providers/aws/regions-and-partitions.mdx
index 377612013e..8556ccc74e 100644
--- a/docs/user-guide/providers/aws/regions-and-partitions.mdx
+++ b/docs/user-guide/providers/aws/regions-and-partitions.mdx
@@ -64,7 +64,7 @@ When more than one source is set, precedence is:
3. `aws.disallowed_regions` in `config.yaml`
-For self-hosted App or API-triggered scans, set `PROWLER_AWS_DISALLOWED_REGIONS` in the runtime environment of the backend scan containers such as `api` and `worker`. The `ui` container does not enforce AWS region selection.
+For Prowler Local Server or API-triggered scans, set `PROWLER_AWS_DISALLOWED_REGIONS` in the runtime environment of the backend scan containers such as `api` and `worker`. The `ui` container does not enforce AWS region selection.
diff --git a/docs/user-guide/providers/azure/authentication.mdx b/docs/user-guide/providers/azure/authentication.mdx
index 08bc79d8ff..f41e9dd9b3 100644
--- a/docs/user-guide/providers/azure/authentication.mdx
+++ b/docs/user-guide/providers/azure/authentication.mdx
@@ -2,9 +2,9 @@
title: 'Azure Authentication in Prowler'
---
-Prowler for Azure supports multiple authentication types. Authentication methods vary between Prowler App and Prowler CLI:
+Prowler for Azure supports multiple authentication types. Authentication methods vary between Prowler Cloud and Prowler CLI:
-**Prowler App:**
+**Prowler Cloud:**
- [**Service Principal Application**](#service-principal-application-authentication-recommended)
@@ -218,7 +218,7 @@ The following security checks require the `ProwlerRole` permissions for executio
## Service Principal Application Authentication (Recommended)
-This method is required for Prowler App and recommended for Prowler CLI.
+This method is required for Prowler Cloud and recommended for Prowler CLI.
### Creating the Service Principal
For more information, see [Creating Prowler Service Principal](/user-guide/providers/azure/create-prowler-service-principal).
diff --git a/docs/user-guide/providers/azure/getting-started-azure.mdx b/docs/user-guide/providers/azure/getting-started-azure.mdx
index 96498c879f..034e8eacfe 100644
--- a/docs/user-guide/providers/azure/getting-started-azure.mdx
+++ b/docs/user-guide/providers/azure/getting-started-azure.mdx
@@ -16,7 +16,7 @@ Government cloud subscriptions (Azure Government) are not currently supported, b
### Prerequisites
-Before setting up Azure in Prowler App, you need to create a Service Principal with proper permissions.
+Before setting up Azure in Prowler Cloud, you need to create a Service Principal with proper permissions.
For detailed instructions on how to create the Service Principal and configure permissions, see [Authentication > Service Principal](/user-guide/providers/azure/authentication#service-principal-application-authentication-recommended).
@@ -34,7 +34,7 @@ For detailed instructions on how to create the Service Principal and configure p
### Step 2: Access Prowler Cloud
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Navigate to `Configuration` > `Providers`

@@ -53,14 +53,14 @@ For detailed instructions on how to create the Service Principal and configure p
### Step 3: Add Credentials to Prowler Cloud
-For Azure, Prowler App uses a service principal application to authenticate. For more information about the process of creating and adding permissions to a service principal refer to this [section](/user-guide/providers/azure/authentication). When you finish creating and adding the [Entra](/user-guide/providers/azure/create-prowler-service-principal#assigning-proper-permissions) and [Subscription](/user-guide/providers/azure/subscriptions) scope permissions to the service principal, enter the `Tenant ID`, `Client ID` and `Client Secret` of the service principal application.
+For Azure, Prowler Cloud uses a service principal application to authenticate. For more information about the process of creating and adding permissions to a service principal refer to this [section](/user-guide/providers/azure/authentication). When you finish creating and adding the [Entra](/user-guide/providers/azure/create-prowler-service-principal#assigning-proper-permissions) and [Subscription](/user-guide/providers/azure/subscriptions) scope permissions to the service principal, enter the `Tenant ID`, `Client ID` and `Client Secret` of the service principal application.
1. Go to your App Registration overview and copy the `Client ID` and `Tenant ID`

-2. Go to Prowler App and paste:
+2. Go to Prowler Cloud and paste:
- `Client ID`
- `Tenant ID`
diff --git a/docs/user-guide/providers/azure/subscriptions.mdx b/docs/user-guide/providers/azure/subscriptions.mdx
index 8fa6c73740..efd37c13e5 100644
--- a/docs/user-guide/providers/azure/subscriptions.mdx
+++ b/docs/user-guide/providers/azure/subscriptions.mdx
@@ -17,7 +17,7 @@ prowler azure --az-cli-auth --subscription-ids
-The multi-subscription feature is available only in the CLI. In Prowler App, each scan is limited to a single subscription.
+The multi-subscription feature is available only in the CLI. In Prowler Cloud, each scan is limited to a single subscription.
## Assigning Permissions for Subscription Scans
diff --git a/docs/user-guide/providers/cloudflare/getting-started-cloudflare.mdx b/docs/user-guide/providers/cloudflare/getting-started-cloudflare.mdx
index c4303b4d50..9af3dbe589 100644
--- a/docs/user-guide/providers/cloudflare/getting-started-cloudflare.mdx
+++ b/docs/user-guide/providers/cloudflare/getting-started-cloudflare.mdx
@@ -50,7 +50,7 @@ The Account ID is a 32-character hexadecimal string (e.g., `372e67954025e0ba6aaa
### Step 2: Open Prowler Cloud
-1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app).
+1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app).
2. Navigate to "Configuration" > "Providers".

diff --git a/docs/user-guide/providers/gcp/authentication.mdx b/docs/user-guide/providers/gcp/authentication.mdx
index 34faa145c0..ce01c1ba23 100644
--- a/docs/user-guide/providers/gcp/authentication.mdx
+++ b/docs/user-guide/providers/gcp/authentication.mdx
@@ -89,7 +89,7 @@ This method uses the Google Cloud CLI to authenticate and is suitable for develo

-8. Extract the following values for Prowler Cloud/App:
+8. Extract the following values for Prowler Cloud or Prowler Local Server:
- `client_id`
- `client_secret`
diff --git a/docs/user-guide/providers/gcp/getting-started-gcp.mdx b/docs/user-guide/providers/gcp/getting-started-gcp.mdx
index e16114e19a..f40542a151 100644
--- a/docs/user-guide/providers/gcp/getting-started-gcp.mdx
+++ b/docs/user-guide/providers/gcp/getting-started-gcp.mdx
@@ -13,7 +13,7 @@ title: 'Getting Started With GCP on Prowler'
### Step 2: Access Prowler Cloud
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Go to "Configuration" > "Providers"

@@ -66,7 +66,7 @@ For Google Cloud, first enter your `GCP Project ID` and then select the authenti
2. Once authenticated, get the `Client ID`, `Client Secret` and `Refresh Token` from `~/.config/gcloud/application_default_credentials`.
- 3. Paste the `Client ID`, `Client Secret` and `Refresh Token` into Prowler App.
+ 3. Paste the `Client ID`, `Client Secret` and `Refresh Token` into Prowler Cloud.
diff --git a/docs/user-guide/providers/github/authentication.mdx b/docs/user-guide/providers/github/authentication.mdx
index 03693e15b5..1546bf284a 100644
--- a/docs/user-guide/providers/github/authentication.mdx
+++ b/docs/user-guide/providers/github/authentication.mdx
@@ -271,7 +271,7 @@ Store the `.pem` private key securely. Anyone with this key can authenticate as
## Prowler Cloud Authentication
-For step-by-step setup instructions for Prowler Cloud, see the [Getting Started Guide](/user-guide/providers/github/getting-started-github#prowler-cloudapp).
+For step-by-step setup instructions for Prowler Cloud, see the [Getting Started Guide](/user-guide/providers/github/getting-started-github#prowler-cloud-and-prowler-local-server).
### Using Personal Access Token
@@ -301,7 +301,7 @@ For step-by-step setup instructions for Prowler Cloud, see the [Getting Started
3. Enter your GitHub App ID and upload the private key (`.pem` file).
-For complete step-by-step instructions, see the [Getting Started Guide](/user-guide/providers/github/getting-started-github#prowler-cloudapp).
+For complete step-by-step instructions, see the [Getting Started Guide](/user-guide/providers/github/getting-started-github#prowler-cloud-and-prowler-local-server).
---
diff --git a/docs/user-guide/providers/github/getting-started-github.mdx b/docs/user-guide/providers/github/getting-started-github.mdx
index 079f9a1d7b..09acdfe0c9 100644
--- a/docs/user-guide/providers/github/getting-started-github.mdx
+++ b/docs/user-guide/providers/github/getting-started-github.mdx
@@ -16,7 +16,7 @@ Prowler can scan either:
-
+
Web-based interface with centralized management
@@ -26,7 +26,7 @@ Prowler can scan either:
---
-## Prowler Cloud/App
+## Prowler Cloud and Prowler Local Server
@@ -34,7 +34,7 @@ Prowler can scan either:
### Prerequisites
-Before adding GitHub to Prowler Cloud/App, ensure you have:
+Before adding GitHub to Prowler Cloud or Prowler Local Server, ensure you have:
1. **GitHub Account Access**
- Personal GitHub account, OR
@@ -46,9 +46,9 @@ Before adding GitHub to Prowler Cloud/App, ensure you have:
- OAuth App Token
- GitHub App Credentials (Not Recommended - limited data access)
-### Step 1: Access Prowler Cloud/App
+### Step 1: Access Prowler Cloud or Prowler Local Server
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Go to **Configuration** → **Providers**

diff --git a/docs/user-guide/providers/googleworkspace/getting-started-googleworkspace.mdx b/docs/user-guide/providers/googleworkspace/getting-started-googleworkspace.mdx
index 8931c43ebd..01e6e89986 100644
--- a/docs/user-guide/providers/googleworkspace/getting-started-googleworkspace.mdx
+++ b/docs/user-guide/providers/googleworkspace/getting-started-googleworkspace.mdx
@@ -42,7 +42,7 @@ The Customer ID starts with the letter "C" followed by alphanumeric characters (
### Step 2: Open Prowler Cloud
-1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app).
+1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app).
2. Navigate to "Configuration" > "Providers".

diff --git a/docs/user-guide/providers/iac/getting-started-iac.mdx b/docs/user-guide/providers/iac/getting-started-iac.mdx
index d1e978dc75..9a941c633d 100644
--- a/docs/user-guide/providers/iac/getting-started-iac.mdx
+++ b/docs/user-guide/providers/iac/getting-started-iac.mdx
@@ -24,7 +24,7 @@ Prowler IaC provider scans the following Infrastructure as Code configurations f
## How It Works
-- Prowler App leverages [Trivy](https://trivy.dev/docs/latest/guide/coverage/iac/#scanner) to scan local directories (or specified paths) for supported IaC files, or scans remote repositories.
+- Prowler Cloud leverages [Trivy](https://trivy.dev/docs/latest/guide/coverage/iac/#scanner) to scan local directories (or specified paths) for supported IaC files, or scans remote repositories.
- No cloud credentials or authentication are required for local scans.
- For remote repository scans, authentication can be provided via [git URL](https://git-scm.com/docs/git-clone#_git_urls), CLI flags or environment variables.
- Check the [IaC Authentication](/user-guide/providers/iac/authentication) page for more details.
@@ -37,11 +37,11 @@ Prowler IaC provider scans the following Infrastructure as Code configurations f
### Supported Scanners
-Scanner selection is not configurable in Prowler App. Default scanners, misconfig and secret, run automatically during each scan.
+Scanner selection is not configurable in Prowler Cloud. Default scanners, misconfig and secret, run automatically during each scan.
-### Step 1: Access Prowler Cloud/App
+### Step 1: Access Prowler Cloud or Prowler Local Server
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Go to "Configuration" > "Providers"

diff --git a/docs/user-guide/providers/image/getting-started-image.mdx b/docs/user-guide/providers/image/getting-started-image.mdx
index b9c305d0ef..6382f10e5c 100644
--- a/docs/user-guide/providers/image/getting-started-image.mdx
+++ b/docs/user-guide/providers/image/getting-started-image.mdx
@@ -33,7 +33,7 @@ Prowler Cloud does not support scanner selection. The vulnerability, secret, and
### Step 1: Access Prowler Cloud
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Navigate to "Configuration" > "Providers"

diff --git a/docs/user-guide/providers/kubernetes/getting-started-k8s.mdx b/docs/user-guide/providers/kubernetes/getting-started-k8s.mdx
index 81d482146e..c62ec2b8a1 100644
--- a/docs/user-guide/providers/kubernetes/getting-started-k8s.mdx
+++ b/docs/user-guide/providers/kubernetes/getting-started-k8s.mdx
@@ -4,9 +4,9 @@ title: 'Getting Started with Kubernetes'
## Prowler Cloud
-### Step 1: Access Prowler Cloud/App
+### Step 1: Access Prowler Cloud or Prowler Local Server
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Go to "Configuration" > "Providers"

@@ -21,10 +21,10 @@ title: 'Getting Started with Kubernetes'
### Step 2: Configure Kubernetes Authentication
-For Kubernetes, Prowler App uses a `kubeconfig` file to authenticate. Paste the contents of your `kubeconfig` file into the `Kubeconfig content` field.
+For Kubernetes, Prowler Cloud uses a `kubeconfig` file to authenticate. Paste the contents of your `kubeconfig` file into the `Kubeconfig content` field.
-Kubeconfigs that use `users[].user.exec` authentication are not supported in Prowler Cloud/App. For security reasons, Prowler Cloud does not run commands declared by uploaded kubeconfigs. Use kubeconfig credentials that do not rely on `exec` authentication, such as the ServiceAccount token flow documented below.
+Kubeconfigs that use `users[].user.exec` authentication are not supported in Prowler Cloud or Prowler Local Server. For security reasons, Prowler Cloud does not run commands declared by uploaded kubeconfigs. Use kubeconfig credentials that do not rely on `exec` authentication, such as the ServiceAccount token flow documented below.
By default, the `kubeconfig` file is located at `~/.kube/config`.
diff --git a/docs/user-guide/providers/microsoft365/getting-started-m365.mdx b/docs/user-guide/providers/microsoft365/getting-started-m365.mdx
index a21b796b5c..fd791cbbca 100644
--- a/docs/user-guide/providers/microsoft365/getting-started-m365.mdx
+++ b/docs/user-guide/providers/microsoft365/getting-started-m365.mdx
@@ -41,7 +41,7 @@ Set up authentication for Microsoft 365 with the [Microsoft 365 Authentication](
### Step 2: Open Prowler Cloud
-1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app).
+1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app).
2. Navigate to "Configuration" > "Providers".

diff --git a/docs/user-guide/providers/mongodbatlas/getting-started-mongodbatlas.mdx b/docs/user-guide/providers/mongodbatlas/getting-started-mongodbatlas.mdx
index c68bfac9c2..2fb415a11b 100644
--- a/docs/user-guide/providers/mongodbatlas/getting-started-mongodbatlas.mdx
+++ b/docs/user-guide/providers/mongodbatlas/getting-started-mongodbatlas.mdx
@@ -15,12 +15,12 @@ Before you begin, make sure you have:
3. An **API Key pair** (public and private keys) with appropriate permissions:
- **Organization Read Only**: Provides read-only access to everything in the organization, including all projects in the organization. This permission is sufficient for most security checks.
- **Organization Owner**: Required to audit the [Auditing configuration](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/group/endpoint-auditing) for projects. Database auditing tracks database operations and security events, including authentication attempts, data definition language (DDL) changes, user and role modifications, and privilege grants. This configuration is essential for security monitoring, forensics, and compliance. Without **Organization Owner** permission, the `projects_auditing_enabled` check cannot retrieve the audit configuration status.
-4. Prowler App access (cloud or self-hosted) or the Prowler CLI (`pip install prowler`).
+4. Access to Prowler Cloud or Prowler Local Server, or Prowler CLI (`pip install prowler`).
For detailed instructions on creating API keys, see the [MongoDB Atlas authentication guide](./authentication.mdx).
-If **Require IP Access List for the Atlas Administration API** is enabled in your organization settings, you **must** add the IP address of the host running Prowler (or the public IP of Prowler Cloud) to the organization IP Access List or Atlas will reject every API call. You can manage this under **Settings → Organization Settings → Security**. See step 7 of the [authentication guide](./authentication.mdx) for detailed instructions, and refer to the [Prowler Cloud public IP list](../../tutorials/prowler-cloud-public-ips) when using Prowler Cloud.
+If **Require IP Access List for the Atlas Administration API** is enabled in the organization settings, add the IP address of the host running Prowler (or the public IP of Prowler Cloud) to the organization IP Access List or Atlas will reject every API call. Manage this under **Settings → Organization Settings → Security**. See step 7 of the [authentication guide](./authentication.mdx) for detailed instructions, and refer to the [Prowler Cloud egress IPs](/security/networking) when using Prowler Cloud.
@@ -53,7 +53,7 @@ If **Require IP Access List for the Atlas Administration API** is enabled in you
### Step 3: Test the connection and start scanning
-1. Click **Test connection** to ensure Prowler App can reach the Atlas API.
+1. Click **Test connection** to ensure Prowler Cloud can reach the Atlas API.
2. Save the credentials. The provider will appear in the list with its current connection status.
3. Launch a scan from the provider row or from the **Scans** page.

@@ -108,6 +108,6 @@ prowler mongodbatlas --atlas-project-id
- Combine flags (for example, `--checks` or `--services`) just like with other providers.
- Use `--output-modes` to export findings in JSON, CSV, ASFF, etc.
-- Rotate API keys regularly and update the stored credentials in Prowler App to maintain connectivity.
+- Rotate API keys regularly and update the stored credentials in Prowler Cloud to maintain connectivity.
For more examples (filters, outputs, scheduling), refer back to the [MongoDB Atlas documentation hub](./authentication.mdx) and the main Prowler CLI usage guide.
diff --git a/docs/user-guide/providers/oci/getting-started-oci.mdx b/docs/user-guide/providers/oci/getting-started-oci.mdx
index 1e4b63cdb7..2f610cd09c 100644
--- a/docs/user-guide/providers/oci/getting-started-oci.mdx
+++ b/docs/user-guide/providers/oci/getting-started-oci.mdx
@@ -6,7 +6,7 @@ Prowler supports security scanning of Oracle Cloud Infrastructure (OCI) environm
## Prowler Cloud
-The following steps apply to Prowler Cloud and the self-hosted Prowler App.
+The following steps apply to Prowler Cloud and Prowler Local Server.
### Step 1: Collect OCI Identifiers
1. Sign in to the [OCI Console](https://cloud.oracle.com/) and open **Tenancy Details** to copy the Tenancy OCID.
@@ -15,14 +15,14 @@ The following steps apply to Prowler Cloud and the self-hosted Prowler App.
4. Note the **Region** identifier to scan (for example, `us-ashburn-1`).
### Step 2: Access Prowler Cloud
-1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app).
+1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app).
2. Go to **Configuration** → **Providers** and click **Add Provider**.

3. Select **Oracle Cloud** and enter the **Tenancy OCID** and an optional alias, then choose **Next**.

### Step 3: Add OCI API Key Credentials
-Prowler App connects to OCI with API key credentials. Provide:
+Prowler Cloud connects to OCI with API key credentials. Provide:
- **User OCID** for the API key owner
- **Fingerprint** of the API key
diff --git a/docs/user-guide/providers/okta/authentication.mdx b/docs/user-guide/providers/okta/authentication.mdx
index 2e08cac8af..8f664160a2 100644
--- a/docs/user-guide/providers/okta/authentication.mdx
+++ b/docs/user-guide/providers/okta/authentication.mdx
@@ -20,7 +20,7 @@ Prowler authenticates to Okta as a **service application** using **OAuth 2.0 wit
| Method | Status | Use Case |
|---|---|---|
-| **OAuth 2.0 (private-key JWT)** | Supported | Production scans, CI/CD, Prowler App. |
+| **OAuth 2.0 (private-key JWT)** | Supported | Production scans, CI/CD, Prowler Cloud. |
The private-key JWT flow is the only supported authentication method in the initial release. The service application proves possession of a private key on every token request; Okta returns a short-lived access token, refreshed automatically by the SDK.
diff --git a/docs/user-guide/providers/okta/getting-started-okta.mdx b/docs/user-guide/providers/okta/getting-started-okta.mdx
index e04e0d4a13..dbe63807d7 100644
--- a/docs/user-guide/providers/okta/getting-started-okta.mdx
+++ b/docs/user-guide/providers/okta/getting-started-okta.mdx
@@ -30,7 +30,7 @@ Set up authentication for Okta with the [Okta Authentication](/user-guide/provid
### Step 1: Add the Provider
-1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app).
+1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app).
2. Navigate to "Configuration" > "Providers".

diff --git a/docs/user-guide/providers/vercel/getting-started-vercel.mdx b/docs/user-guide/providers/vercel/getting-started-vercel.mdx
index c39c5f1e6a..da02019b6f 100644
--- a/docs/user-guide/providers/vercel/getting-started-vercel.mdx
+++ b/docs/user-guide/providers/vercel/getting-started-vercel.mdx
@@ -28,7 +28,7 @@ Set up authentication for Vercel with the [Vercel Authentication](/user-guide/pr
### Step 1: Add the Provider
-1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app).
+1. Go to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app).
2. Navigate to "Configuration" > "Providers".

diff --git a/docs/user-guide/tutorials/aws-organizations-bulk-provisioning.mdx b/docs/user-guide/tutorials/aws-organizations-bulk-provisioning.mdx
index 88a084dd17..2e8b5eb62e 100644
--- a/docs/user-guide/tutorials/aws-organizations-bulk-provisioning.mdx
+++ b/docs/user-guide/tutorials/aws-organizations-bulk-provisioning.mdx
@@ -9,9 +9,9 @@ The tool, `aws_org_generator.py`, complements the [Bulk Provider Provisioning
**Native AWS Organizations support is now available in Prowler Cloud.** You can onboard all accounts via the UI wizard — with automatic discovery, hierarchical tree selection, connection testing, and bulk scan launch — without any scripts or YAML files.
-See [AWS Organizations in Prowler Cloud](/user-guide/tutorials/prowler-cloud-aws-organizations).
+See [AWS Organizations](/user-guide/tutorials/prowler-cloud-aws-organizations) in Prowler Cloud.
-The CLI-based tool below remains useful for self-hosted Prowler App and advanced automation scenarios.
+The CLI-based tool below remains useful for Prowler Local Server and advanced automation scenarios.
{/* TODO: Add screenshot of the tool in action */}
@@ -32,9 +32,9 @@ The AWS Organizations Bulk Provisioning tool simplifies multi-account onboarding
* Python 3.7 or higher
* AWS credentials with Organizations read access
* ProwlerRole (or custom role) deployed across all target accounts
-* Prowler API key (from Prowler Cloud or self-hosted Prowler App)
- * For self-hosted Prowler App, remember to [point to your API base URL](./bulk-provider-provisioning#custom-api-endpoints)
- * Learn how to create API keys: [Prowler App API Keys](../tutorials/prowler-app-api-keys)
+* Prowler API key (from Prowler Cloud or Prowler Local Server)
+ * For Prowler Local Server, remember to [point to your API base URL](./bulk-provider-provisioning#custom-api-endpoints)
+ * Learn how to create API keys: [Prowler Cloud API Keys](../tutorials/prowler-app-api-keys)
### Deploying ProwlerRole Across AWS Organizations
@@ -97,13 +97,13 @@ export PROWLER_API_KEY="pk_example-api-key"
To create an API key:
-1. Log in to Prowler Cloud or Prowler App
+1. Log in to Prowler Cloud or Prowler Local Server
2. Click **Profile** → **Account**
3. Click **Create API Key**
4. Provide a descriptive name and optionally set an expiration date
5. Copy the generated API key (it will only be shown once)
-For detailed instructions, see: [Prowler App API Keys](../tutorials/prowler-app-api-keys)
+For detailed instructions, see: [Prowler Cloud API Keys](../tutorials/prowler-app-api-keys)
## Basic Usage
@@ -324,7 +324,7 @@ python aws_org_generator.py \
- Provision all accounts to Prowler Cloud or Prowler App:
+ Provision all accounts to Prowler Cloud or Prowler Local Server:
```bash
# Set Prowler API key
@@ -487,7 +487,7 @@ grep "provider: aws" aws-org-accounts.yaml | wc -l
Learn how to bulk provision providers in Prowler.
-
+
Detailed instructions on how to use Prowler.
diff --git a/docs/user-guide/tutorials/bulk-provider-provisioning.mdx b/docs/user-guide/tutorials/bulk-provider-provisioning.mdx
index 3ad5d9c0d5..cc759b6f85 100644
--- a/docs/user-guide/tutorials/bulk-provider-provisioning.mdx
+++ b/docs/user-guide/tutorials/bulk-provider-provisioning.mdx
@@ -10,7 +10,7 @@ The tool is available in the Prowler repository at: [util/prowler-bulk-provision
## Overview
-The Bulk Provider Provisioning tool automates the creation of cloud providers in Prowler App or Prowler Cloud by:
+The Bulk Provider Provisioning tool automates the creation of cloud providers in Prowler Cloud or Prowler Local Server by:
* Reading provider configurations from YAML files
* Creating providers with appropriate authentication credentials
@@ -26,9 +26,9 @@ The Bulk Provider Provisioning tool automates the creation of cloud providers in
### Requirements
* Python 3.7 or higher
-* Prowler API key (from Prowler Cloud or self-hosted Prowler App)
- * For self-hosted Prowler App, remember to [point to your API base URL](#custom-api-endpoints)
- * Learn how to create API keys: [Prowler App API Keys](../tutorials/prowler-app-api-keys)
+* Prowler API key (from Prowler Cloud or Prowler Local Server)
+ * For Prowler Local Server, remember to [point to your API base URL](#custom-api-endpoints)
+ * Learn how to create API keys: [Prowler Cloud API Keys](../tutorials/prowler-app-api-keys)
* Authentication credentials for target cloud providers
### Installation
@@ -51,13 +51,13 @@ export PROWLER_API_KEY="pk_example-api-key"
To create an API key:
-1. Log in to Prowler Cloud or Prowler App
+1. Log in to Prowler Cloud or Prowler Local Server
2. Click **Profile** → **Account**
3. Click **Create API Key**
4. Provide a descriptive name and optionally set an expiration date
5. Copy the generated API key (it will only be shown once)
-For detailed instructions, see: [Prowler App API Keys](../tutorials/prowler-app-api-keys)
+For detailed instructions, see: [Prowler Cloud API Keys](../tutorials/prowler-app-api-keys)
## Configuration File Structure
@@ -261,7 +261,7 @@ python prowler_bulk_provisioning.py providers.yaml --concurrency 10
### Custom API Endpoints
-For self-hosted Prowler App installations:
+For Prowler Local Server installations:
```bash
python prowler_bulk_provisioning.py providers.yaml \
diff --git a/docs/user-guide/tutorials/prowler-alerts.mdx b/docs/user-guide/tutorials/prowler-alerts.mdx
index 9f01a77910..fc205b72be 100644
--- a/docs/user-guide/tutorials/prowler-alerts.mdx
+++ b/docs/user-guide/tutorials/prowler-alerts.mdx
@@ -1,5 +1,6 @@
---
title: 'Alerts'
+sidebarTitle: 'Alerts'
description: 'Create email alerts from Prowler Cloud findings to monitor relevant security changes after scans or in daily digests.'
---
diff --git a/docs/user-guide/tutorials/prowler-app-api-keys.mdx b/docs/user-guide/tutorials/prowler-app-api-keys.mdx
index 4e51e62bac..c7d5f86ec4 100644
--- a/docs/user-guide/tutorials/prowler-app-api-keys.mdx
+++ b/docs/user-guide/tutorials/prowler-app-api-keys.mdx
@@ -3,14 +3,17 @@ title: 'API Keys'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-API key authentication in Prowler App provides an alternative to JWT tokens and empowers automation, CI/CD pipelines, and third-party integrations. This guide explains how to create, manage, and safeguard API keys when working with the Prowler API.
+
+
+API key authentication in Prowler Cloud provides an alternative to JWT tokens and empowers automation, CI/CD pipelines, and third-party integrations. This guide explains how to create, manage, and safeguard API keys when working with the Prowler API.
## API Key Advantages
-- **Programmatic access:** Enables automated workflows and scripts to interact with Prowler App.
+- **Programmatic access:** Enables automated workflows and scripts to interact with Prowler Cloud.
- **Long-lived authentication:** Allows optional expiration dates, with a default of 1 year.
- **Granular control:** Supports multiple keys with distinct names and purposes.
- **Secure automation:** Simplifies safe integration into CI/CD pipelines and infrastructure-as-code tooling.
@@ -19,7 +22,7 @@ API key authentication in Prowler App provides an alternative to JWT tokens and
API keys provide a secure authentication mechanism for accessing the Prowler API:
-1. API keys are created through Prowler App with a user-defined name and optional expiration date.
+1. API keys are created through Prowler Cloud with a user-defined name and optional expiration date.
2. The full API key appears only once upon creation and cannot be retrieved later.
3. Each API key consists of a prefix (visible in the interface) and an encrypted secret portion.
4. Requests include the API key in the header as `Authorization: Api-Key `.
@@ -63,13 +66,13 @@ Creating, viewing, or managing API keys requires the **MANAGE_ACCOUNT** RBAC per
Without this permission, the API Keys section remains hidden. Access requests should be routed through the tenant administrator.
-For more information about RBAC permissions, refer to the [Prowler App RBAC documentation](/user-guide/tutorials/prowler-app-rbac).
+For more information about RBAC permissions, refer to the [Prowler Cloud RBAC documentation](/user-guide/tutorials/prowler-app-rbac).
## Creating API Keys
-Follow these steps to create an API key in Prowler App:
+Follow these steps to create an API key in Prowler Cloud:
-1. Navigate to **Profile** → **Account** in Prowler App.
+1. Navigate to **Profile** → **Account** in Prowler Cloud.
2. Select the **Create API Key** button.

@@ -206,7 +209,7 @@ When using API keys in CI/CD pipelines:
* Ensure the key has not been revoked by checking the Revoked column in the API Keys list.
* Confirm that the key has not expired by reviewing the expiration date.
* Confirm that the correct API key format is in use, including both prefix and secret portions.
-* Verify that the key prefix matches what is displayed in Prowler App.
+* Verify that the key prefix matches what is displayed in Prowler Cloud.
### API Key Not Working After Creation
diff --git a/docs/user-guide/tutorials/prowler-app-attack-paths.mdx b/docs/user-guide/tutorials/prowler-app-attack-paths.mdx
index b07aebcc4f..32df3c50ba 100644
--- a/docs/user-guide/tutorials/prowler-app-attack-paths.mdx
+++ b/docs/user-guide/tutorials/prowler-app-attack-paths.mdx
@@ -4,9 +4,12 @@ description: "Identify privilege escalation chains and security misconfiguration
---
import { VersionBadge } from "/snippets/version-badge.mdx";
+import { AppliesTo } from "/snippets/applies-to.mdx";
+
+
Attack Paths analyzes relationships between cloud resources, permissions, and security findings to detect how privileges can be escalated and how misconfigurations can be exploited by threat actors.
By mapping these relationships as a graph, Attack Paths reveals risks that individual security checks cannot detect on their own, such as an IAM role that can escalate its own permissions, or a chain of policies that grants unintended access to sensitive resources.
@@ -20,7 +23,7 @@ By mapping these relationships as a graph, Attack Paths reveals risks that indiv
The following prerequisites are required for Attack Paths:
-- **An AWS provider is configured** with valid credentials in Prowler App. For setup instructions, see [Getting Started with AWS](/user-guide/providers/aws/getting-started-aws).
+- **An AWS provider is configured** with valid credentials in Prowler Cloud. For setup instructions, see [Getting Started with AWS](/user-guide/providers/aws/getting-started-aws).
- **At least one scan has completed** on the configured AWS provider and produced graph data. Attack Paths scans run automatically alongside regular security scans, no separate configuration is required.
## How Attack Paths Scans Work
diff --git a/docs/user-guide/tutorials/prowler-app-finding-groups.mdx b/docs/user-guide/tutorials/prowler-app-finding-groups.mdx
index e1bf83a50f..c5234bb41f 100644
--- a/docs/user-guide/tutorials/prowler-app-finding-groups.mdx
+++ b/docs/user-guide/tutorials/prowler-app-finding-groups.mdx
@@ -1,12 +1,16 @@
---
title: 'Finding Groups'
+sidebarTitle: 'Groups'
description: 'Organize and triage security findings by check to reduce noise and prioritize remediation effectively.'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
+
+
Finding Groups transforms security findings triage by grouping them by check instead of displaying a flat list. This dramatically reduces noise and enables faster, more effective prioritization.
## Triage Challenges with Flat Finding Lists
@@ -112,7 +116,7 @@ This provides full context without leaving the drawer.
## Getting Started
-1. Navigate to the **Findings** section in Prowler Cloud/App.
+1. Navigate to the **Findings** section in Prowler Cloud.
2. Toggle to the **Grouped View** to see findings organized by check.
3. Select any group row to expand and see affected resources.
4. Select a resource to open the detail drawer with full context.
diff --git a/docs/user-guide/tutorials/prowler-app-findings-triage.mdx b/docs/user-guide/tutorials/prowler-app-findings-triage.mdx
index 68b1af5a32..bbceaef992 100644
--- a/docs/user-guide/tutorials/prowler-app-findings-triage.mdx
+++ b/docs/user-guide/tutorials/prowler-app-findings-triage.mdx
@@ -1,5 +1,6 @@
---
title: "Findings Triage"
+sidebarTitle: 'Triage'
description: "Track finding review status and team notes in Prowler Cloud."
---
@@ -113,7 +114,7 @@ Make sure the row is an individual finding row. Finding Groups rows do not show
### Changes cannot be saved
-Confirm that the user role has **Manage Scans** permission. Self-hosted Prowler App does not support Findings Triage writes.
+Confirm that the user role has **Manage Scans** permission. Prowler Local Server does not support Findings Triage writes.
### Resolved or Reopened is missing from the selector
diff --git a/docs/user-guide/tutorials/prowler-app-jira-integration.mdx b/docs/user-guide/tutorials/prowler-app-jira-integration.mdx
index 01779a6a96..83554ee8c0 100644
--- a/docs/user-guide/tutorials/prowler-app-jira-integration.mdx
+++ b/docs/user-guide/tutorials/prowler-app-jira-integration.mdx
@@ -1,13 +1,17 @@
---
title: "Jira Integration"
+sidebarTitle: 'Jira'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-Prowler App enables automatic export of security findings to Jira, providing seamless integration with Atlassian's work item tracking and project management platform. This comprehensive guide demonstrates how to configure and manage Jira integrations to streamline security incident management and enhance team collaboration across security workflows.
+
-Integrating Prowler App with Jira provides:
+Prowler Cloud enables automatic export of security findings to Jira, providing seamless integration with Atlassian's work item tracking and project management platform. This comprehensive guide demonstrates how to configure and manage Jira integrations to streamline security incident management and enhance team collaboration across security workflows.
+
+Integrating Prowler Cloud with Jira provides:
* **Streamlined management:** Convert security findings directly into actionable Jira work items
* **Enhanced team collaboration:** Leverage existing project management workflows for security remediation
@@ -22,9 +26,9 @@ When enabled and configured:
## Configuration
-To configure Jira integration in Prowler App:
+To configure Jira integration in Prowler Cloud:
-1. Navigate to **Integrations** in the Prowler App interface
+1. Navigate to **Integrations** in Prowler Cloud
2. Locate the **Jira** card and click **Manage**, then select **Add integration**

@@ -50,7 +54,7 @@ Once configured successfully, the integration is ready to send findings to Jira.
To manually send individual findings to Jira:
-1. Navigate to the **Findings** section in Prowler App
+1. Navigate to the **Findings** section in Prowler Cloud
2. Select one finding you want to export
3. Click the action button on the table row and select **Send to Jira**
4. Select the Jira integration and project
diff --git a/docs/user-guide/tutorials/prowler-app-lighthouse-multi-llm.mdx b/docs/user-guide/tutorials/prowler-app-lighthouse-multi-llm.mdx
index b1cb918de7..eee7564bcb 100644
--- a/docs/user-guide/tutorials/prowler-app-lighthouse-multi-llm.mdx
+++ b/docs/user-guide/tutorials/prowler-app-lighthouse-multi-llm.mdx
@@ -1,5 +1,6 @@
---
title: 'Using Multiple LLM Providers with Lighthouse'
+sidebarTitle: 'Multiple LLM Providers'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
diff --git a/docs/user-guide/tutorials/prowler-app-lighthouse.mdx b/docs/user-guide/tutorials/prowler-app-lighthouse.mdx
index 0930be8aa8..5b4a0f5847 100644
--- a/docs/user-guide/tutorials/prowler-app-lighthouse.mdx
+++ b/docs/user-guide/tutorials/prowler-app-lighthouse.mdx
@@ -19,7 +19,7 @@ Behind the scenes, Lighthouse AI works as follows:
- The agent accesses Prowler data through [Prowler MCP](https://docs.prowler.com/getting-started/products/prowler-mcp), which exposes tools from multiple sources, including:
- Prowler Hub
- Prowler Docs
- - Prowler App
+ - Prowler Local Server
- Instead of calling every tool directly, the agent uses two meta-tools:
- `describe_tool` to retrieve a tool schema and parameter requirements.
- `execute_tool` to run the selected tool with the required input.
diff --git a/docs/user-guide/tutorials/prowler-app-multi-tenant.mdx b/docs/user-guide/tutorials/prowler-app-multi-tenant.mdx
index b353bc85c5..8de9365fe9 100644
--- a/docs/user-guide/tutorials/prowler-app-multi-tenant.mdx
+++ b/docs/user-guide/tutorials/prowler-app-multi-tenant.mdx
@@ -1,12 +1,16 @@
---
title: 'Managing Organizations (Multi-Tenant)'
+sidebarTitle: 'Organizations'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-Prowler App supports multi-tenancy through **Organizations**, allowing users to belong to multiple isolated environments within a single account. Each organization maintains its own providers, scans, findings, and user memberships, ensuring complete data separation between teams or business units.
+
+
+Prowler Cloud supports multi-tenancy through **Organizations**, allowing users to belong to multiple isolated environments within a single account. Each organization maintains its own providers, scans, findings, and user memberships, ensuring complete data separation between teams or business units.
## Key Concepts
@@ -128,7 +132,7 @@ When invited to join an organization, the invited user receives a link to accept
1. Open the invitation link.
-2. If already authenticated, the invitation is accepted automatically and the user is redirected to Prowler App.
+2. If already authenticated, the invitation is accepted automatically and the user is redirected to Prowler Cloud.
3. If not authenticated, choose **I have an account -- Sign in**, authenticate with existing credentials, and the invitation is accepted upon sign-in.
diff --git a/docs/user-guide/tutorials/prowler-app-mute-findings.mdx b/docs/user-guide/tutorials/prowler-app-mute-findings.mdx
index 82623b54cf..c2ada47e9c 100644
--- a/docs/user-guide/tutorials/prowler-app-mute-findings.mdx
+++ b/docs/user-guide/tutorials/prowler-app-mute-findings.mdx
@@ -1,11 +1,14 @@
---
-title: 'Advanced Mutelist (YAML)'
+title: 'Advanced Mutelist'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-Prowler App allows users to mute specific findings to focus on the most critical security issues. This guide demonstrates how to use the Advanced Mutelist feature with YAML configuration for complex, pattern-based muting rules.
+
+
+Prowler Cloud allows users to mute specific findings to focus on the most critical security issues. This guide demonstrates how to use the Advanced Mutelist feature with YAML configuration for complex, pattern-based muting rules.
For muting individual findings without YAML configuration, use [Simple Mutelist](/user-guide/tutorials/prowler-app-simple-mutelist) to mute findings directly from the Findings table.
@@ -31,8 +34,8 @@ Advanced Mutelist requires the **Manage Account** permission. See [RBAC Administ
Before muting findings, ensure:
-- Valid access to Prowler App with appropriate permissions
-- A provider added to the Prowler App
+- Valid access to Prowler Cloud with appropriate permissions
+- A provider added to Prowler Cloud
- Understanding of the security implications of muting specific findings
@@ -43,7 +46,7 @@ Muting findings does not resolve underlying security issues. Review each finding
To configure Advanced Mutelist:
-1. Log into Prowler App
+1. Log into Prowler Cloud
2. Navigate to the Providers page

3. Connect a provider to enable Mutelist configuration
@@ -423,7 +426,7 @@ Mutelist:
### Priority: Advanced vs. Simple Mutelist
-When both Advanced Mutelist (YAML) and [Simple Mutelist](/user-guide/tutorials/prowler-app-simple-mutelist) rules match the same finding, the **Advanced Mutelist takes higher priority**. The finding will be muted with the reason "Muted by mutelist". If a finding is not matched by the Advanced Mutelist but matches a Simple Mutelist rule, the Simple rule's custom justification is used instead.
+When both Advanced Mutelist and [Simple Mutelist](/user-guide/tutorials/prowler-app-simple-mutelist) rules match the same finding, the **Advanced Mutelist takes higher priority**. The finding will be muted with the reason "Muted by mutelist". If a finding is not matched by the Advanced Mutelist but matches a Simple Mutelist rule, the Simple rule's custom justification is used instead.
### Best Practices
@@ -436,7 +439,7 @@ When both Advanced Mutelist (YAML) and [Simple Mutelist](/user-guide/tutorials/p
### Validation
-Prowler App validates your mutelist configuration and will display errors for:
+Prowler Cloud validates the mutelist configuration and will display errors for:
- Invalid YAML syntax
- Missing required fields
diff --git a/docs/user-guide/tutorials/prowler-app-rbac.mdx b/docs/user-guide/tutorials/prowler-app-rbac.mdx
index 0cd22f20e7..4533e0423c 100644
--- a/docs/user-guide/tutorials/prowler-app-rbac.mdx
+++ b/docs/user-guide/tutorials/prowler-app-rbac.mdx
@@ -1,12 +1,16 @@
---
title: 'Managing Users and Role-Based Access Control (RBAC)'
+sidebarTitle: 'Users & RBAC'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-**Prowler App** supports multiple users within a single tenant, enabling seamless collaboration by allowing team members to easily share insights and manage security findings.
+
+
+**Prowler Cloud** supports multiple users within a single tenant, enabling seamless collaboration by allowing team members to easily share insights and manage security findings.
[Roles](#roles) help you control user permissions, determining what actions each user can perform and the data they can access within Prowler. By default, each account includes an immutable **admin** role, ensuring that your account always retains administrative access.
diff --git a/docs/user-guide/tutorials/prowler-app-s3-integration.mdx b/docs/user-guide/tutorials/prowler-app-s3-integration.mdx
index 97987f1f74..9b7d7a9a2e 100644
--- a/docs/user-guide/tutorials/prowler-app-s3-integration.mdx
+++ b/docs/user-guide/tutorials/prowler-app-s3-integration.mdx
@@ -1,12 +1,16 @@
---
title: 'Amazon S3 Integration'
+sidebarTitle: 'Amazon S3'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-**Prowler App** allows automatic export of scan results to Amazon S3 buckets, providing seamless integration with existing data workflows and storage infrastructure. This comprehensive guide demonstrates configuration and management of Amazon S3 integrations to streamline security finding management and reporting.
+
+
+**Prowler Cloud** allows automatic export of scan results to Amazon S3 buckets, providing seamless integration with existing data workflows and storage infrastructure. This comprehensive guide demonstrates configuration and management of Amazon S3 integrations to streamline security finding management and reporting.
When enabled and configured, scan results are automatically stored in the configured bucket. Results are provided in `csv`, `html` and `json-ocsf` formats, offering flexibility for custom integrations:
@@ -201,7 +205,7 @@ Replace `` with the AWS account ID that contains the IAM role
### Available Templates
-**Prowler App** provides Infrastructure as Code (IaC) templates to automate IAM role setup with S3 integration permissions.
+**Prowler Cloud** provides Infrastructure as Code (IaC) templates to automate IAM role setup with S3 integration permissions.
Templates are optional. Custom IAM roles or static credentials can be used instead.
@@ -278,7 +282,7 @@ If using Prowler's CloudFormation template, execute the following command to upd
3. Edit `terraform.tfvars` with your specific values:
```hcl
- # Required: External ID from Prowler App
+ # Required: External ID from Prowler Cloud
external_id = "your-unique-external-id-here"
# S3 Integration Configuration
@@ -310,7 +314,7 @@ For detailed information, refer to the [Terraform README](https://github.com/pro
## Configuration
-Once the required permissions are set up, proceed to configure the S3 integration in **Prowler App**.
+Once the required permissions are set up, proceed to configure the S3 integration in **Prowler Cloud**.
1. Navigate to "Integrations"

diff --git a/docs/user-guide/tutorials/prowler-app-scan-configuration.mdx b/docs/user-guide/tutorials/prowler-app-scan-configuration.mdx
index 7f87eb53bf..8d50f0072c 100644
--- a/docs/user-guide/tutorials/prowler-app-scan-configuration.mdx
+++ b/docs/user-guide/tutorials/prowler-app-scan-configuration.mdx
@@ -1,5 +1,6 @@
---
title: 'Scan Configuration'
+sidebarTitle: 'Configuration'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
diff --git a/docs/user-guide/tutorials/prowler-app-security-hub-integration.mdx b/docs/user-guide/tutorials/prowler-app-security-hub-integration.mdx
index 592ff2b26d..977ad8e6f1 100644
--- a/docs/user-guide/tutorials/prowler-app-security-hub-integration.mdx
+++ b/docs/user-guide/tutorials/prowler-app-security-hub-integration.mdx
@@ -1,13 +1,17 @@
---
title: "AWS Security Hub Integration"
+sidebarTitle: 'AWS Security Hub'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-Prowler App enables automatic export of security findings to AWS Security Hub, providing seamless integration with AWS's native security and compliance service. This comprehensive guide demonstrates how to configure and manage AWS Security Hub integrations to centralize security findings and enhance compliance tracking across AWS environments.
+
-Integrating Prowler App with AWS Security Hub provides:
+Prowler Cloud enables automatic export of security findings to AWS Security Hub, providing seamless integration with AWS's native security and compliance service. This comprehensive guide demonstrates how to configure and manage AWS Security Hub integrations to centralize security findings and enhance compliance tracking across AWS environments.
+
+Integrating Prowler Cloud with AWS Security Hub provides:
* **Centralized security visibility:** Consolidate findings from multiple AWS accounts and regions
* **Native AWS integration:** Leverage existing AWS security workflows and compliance frameworks
@@ -30,7 +34,7 @@ Refer to [AWS Security Hub pricing](https://aws.amazon.com/security-hub/pricing/
## Prerequisites
-Before configuring AWS Security Hub Integration in Prowler App, complete these steps:
+Before configuring AWS Security Hub Integration in Prowler Cloud, complete these steps:
### AWS Security Hub Setup
@@ -42,9 +46,9 @@ Configure AWS credentials by following the [AWS authentication setup guide](/use
## Configuration
-To configure AWS Security Hub integration in Prowler App:
+To configure AWS Security Hub integration in Prowler Cloud:
-1. Navigate to **Integrations** in the Prowler App interface
+1. Navigate to **Integrations** in Prowler Cloud
2. Locate the **AWS Security Hub** card and click **Manage**, then select **Add integration**

diff --git a/docs/user-guide/tutorials/prowler-app-simple-mutelist.mdx b/docs/user-guide/tutorials/prowler-app-simple-mutelist.mdx
index c0bd7db9b4..4b0d59e24a 100644
--- a/docs/user-guide/tutorials/prowler-app-simple-mutelist.mdx
+++ b/docs/user-guide/tutorials/prowler-app-simple-mutelist.mdx
@@ -3,10 +3,13 @@ title: "Simple Mutelist"
---
import { VersionBadge } from "/snippets/version-badge.mdx";
+import { AppliesTo } from "/snippets/applies-to.mdx";
-Prowler App provides Simple Mutelist, an intuitive way to mute findings directly from the Findings page without writing YAML configuration. This feature streamlines the muting workflow by allowing individual or bulk muting with just a few clicks.
+
+
+Prowler Cloud provides Simple Mutelist, an intuitive way to mute findings directly from the Findings page without writing YAML configuration. This feature streamlines the muting workflow by allowing individual or bulk muting with just a few clicks.
## What Is Simple Mutelist?
diff --git a/docs/user-guide/tutorials/prowler-app-social-login.mdx b/docs/user-guide/tutorials/prowler-app-social-login.mdx
index 45fe8ec62f..62de6fbc9c 100644
--- a/docs/user-guide/tutorials/prowler-app-social-login.mdx
+++ b/docs/user-guide/tutorials/prowler-app-social-login.mdx
@@ -1,12 +1,16 @@
---
title: 'Social Login Configuration'
+sidebarTitle: 'Social Login'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-**Prowler App** supports social login using Google and GitHub OAuth providers. This document guides you through configuring the required environment variables to enable social authentication.
+
+
+Prowler supports social login using Google and GitHub OAuth providers. In **Prowler Cloud** social login is available out of the box. In **Prowler Local Server**, enable it by configuring the environment variables described in this guide.
## Configuring Social Login Credentials
diff --git a/docs/user-guide/tutorials/prowler-app-sso-entra.mdx b/docs/user-guide/tutorials/prowler-app-sso-entra.mdx
index 37f3bbdda5..07cf4709be 100644
--- a/docs/user-guide/tutorials/prowler-app-sso-entra.mdx
+++ b/docs/user-guide/tutorials/prowler-app-sso-entra.mdx
@@ -2,7 +2,11 @@
title: 'Entra ID Configuration'
---
-This page provides instructions for creating and configuring a Microsoft Entra ID (formerly Azure AD) application to use SAML SSO with Prowler App.
+import { AppliesTo } from "/snippets/applies-to.mdx"
+
+
+
+This page provides instructions for creating and configuring a Microsoft Entra ID (formerly Azure AD) application to use SAML SSO with Prowler Cloud.
You can find a walkthrough video [here](https://www.youtube.com/watch?v=zegqm55oJVk).
@@ -28,7 +32,7 @@ You can find a walkthrough video [here](https://www.youtube.com/watch?v=zegqm55o

-6. Enter the "Identifier (Entity ID)" and "Reply URL (Assertion Consumer Service URL)". These values can be obtained from the SAML SSO integration setup in Prowler App. For detailed instructions, refer to the [SAML SSO Configuration](/user-guide/tutorials/prowler-app-sso) page.
+6. Enter the "Identifier (Entity ID)" and "Reply URL (Assertion Consumer Service URL)". These values can be obtained from the SAML SSO integration setup in Prowler Cloud. For detailed instructions, refer to the [SAML SSO Configuration](/user-guide/tutorials/prowler-app-sso) page.

@@ -44,4 +48,4 @@ You can find a walkthrough video [here](https://www.youtube.com/watch?v=zegqm55o

-10. Save the downloaded Metadata XML to a file. To complete the setup, upload this file during the Prowler App integration. (See the [SAML SSO Configuration](/user-guide/tutorials/prowler-app-sso) page for details).
+10. Save the downloaded Metadata XML to a file. To complete the setup, upload this file during the SAML SSO integration setup in Prowler Cloud. (See the [SAML SSO Configuration](/user-guide/tutorials/prowler-app-sso) page for details).
diff --git a/docs/user-guide/tutorials/prowler-app-sso-google-workspace.mdx b/docs/user-guide/tutorials/prowler-app-sso-google-workspace.mdx
index 2f10d443ae..ce0e5edc79 100644
--- a/docs/user-guide/tutorials/prowler-app-sso-google-workspace.mdx
+++ b/docs/user-guide/tutorials/prowler-app-sso-google-workspace.mdx
@@ -2,20 +2,24 @@
title: 'SAML SSO: Google Workspace'
---
-This page explains how to configure SAML-based Single Sign-On (SSO) in Prowler App using **Google Workspace** as the Identity Provider (IdP). The setup is divided into two parts: create a custom SAML app in Google Admin Console, then complete the configuration in Prowler App.
+import { AppliesTo } from "/snippets/applies-to.mdx"
+
+
+
+This page explains how to configure SAML-based Single Sign-On (SSO) in Prowler Cloud using **Google Workspace** as the Identity Provider (IdP). The setup is divided into two parts: create a custom SAML app in Google Admin Console, then complete the configuration in Prowler Cloud.
**Parallel Setup Required**
-Google Admin Console requires the ACS URL and Entity ID from Prowler App, while Prowler App displays these values only after opening the SAML configuration dialog. To work around this, open Prowler App in a separate browser tab, navigate to the profile page, open the "Configure SAML SSO" dialog, and copy the ACS URL and Entity ID before proceeding with the Google configuration.
+Google Admin Console requires the ACS URL and Entity ID from Prowler Cloud, while Prowler Cloud displays these values only after opening the SAML configuration dialog. To work around this, open Prowler Cloud in a separate browser tab, navigate to the profile page, open the "Configure SAML SSO" dialog, and copy the ACS URL and Entity ID before proceeding with the Google configuration.
## Prerequisites
- **Google Workspace**: Super Admin access (or delegated admin with app management permissions).
-- **Prowler App**: Administrator access to the organization (role with "Manage Account" permission).
-- Prowler App version **5.9.0** or later.
+- **Prowler Cloud**: Administrator access to the organization (role with "Manage Account" permission).
+- Prowler version **5.9.0** or later.
---
@@ -44,7 +48,7 @@ On the **Google Identity Provider details** screen:
1. Google displays two options:
- **Option 1**: Click "Download Metadata" to save the XML file directly. This is the recommended approach.
- **Option 2**: Manually copy the **SSO URL**, **Entity ID**, and **Certificate**.
-2. Download the metadata. This file is required to complete the Prowler App configuration in Part B.
+2. Download the metadata. This file is required to complete the configuration in Prowler Cloud (Part B).
3. Click "Continue".

@@ -52,18 +56,18 @@ On the **Google Identity Provider details** screen:
**Save the Metadata File**
-Download and save the IdP metadata XML file before proceeding. This file cannot be easily retrieved later and is required to complete the SAML configuration in Prowler App.
+Download and save the IdP metadata XML file before proceeding. This file cannot be easily retrieved later and is required to complete the SAML configuration in Prowler Cloud.
### Step 4: Configure the Service Provider Details
-Enter the following values obtained from the SAML SSO configuration dialog in Prowler App (see [Part B, Step 1](#step-1-open-the-saml-configuration-dialog) for details on where to find them):
+Enter the following values obtained from the SAML SSO configuration dialog in Prowler Cloud (see [Part B, Step 1](#step-1-open-the-saml-configuration-dialog) for details on where to find them):
| Google Workspace Field | Value |
|------------------------|-------|
-| **ACS URL** | The Assertion Consumer Service (ACS) URL displayed in Prowler App (e.g., `https://api.prowler.com/api/v1/accounts/saml/your-domain.com/acs/`). Self-hosted deployments use a different base URL. |
-| **Entity ID** | The Audience URI displayed in Prowler App (e.g., `urn:prowler.com:sp`). |
+| **ACS URL** | The Assertion Consumer Service (ACS) URL displayed in Prowler Cloud (e.g., `https://api.prowler.com/api/v1/accounts/saml/your-domain.com/acs/`). Prowler Local Server deployments use a different base URL. |
+| **Entity ID** | The Audience URI displayed in Prowler Cloud (e.g., `urn:prowler.com:sp`). |
| **Name ID format** | Select `EMAIL` from the dropdown. |
| **Name ID** | Select `Basic Information > Primary email` from the dropdown. |
@@ -82,7 +86,7 @@ Click "Add mapping" for each entry:
| `Basic Information > First name` | `firstName` | Yes | |
| `Basic Information > Last name` | `lastName` | Yes | |
| `Employee Details > Department` | `userType` | No | Determines the Prowler role. **Case-sensitive.** |
-| `Employee Details > Organization` | `organization` | No | Company name displayed in Prowler App profile. |
+| `Employee Details > Organization` | `organization` | No | Company name displayed in the user profile in Prowler Cloud. |
**Remember the Mapped Fields**
@@ -98,7 +102,7 @@ Click "Finish" to create the SAML app.
**Dynamic Updates**
-Prowler App updates user attributes each time a user logs in. Any changes made in Google Workspace are reflected on the next login.
+Prowler Cloud updates user attributes each time a user logs in. Any changes made in Google Workspace are reflected on the next login.
@@ -108,7 +112,7 @@ Prowler App updates user attributes each time a user logs in. Any changes made i
The `userType` attribute controls which Prowler role is assigned to the user:
- If `userType` matches an existing Prowler role name, the user receives that role automatically.
-- If `userType` does not match any existing role, Prowler App creates a new role with that name **with read-only access** (visibility over all providers, no management permissions). A Prowler administrator can adjust its permissions afterward through the [RBAC Management](/user-guide/tutorials/prowler-app-rbac) tab.
+- If `userType` does not match any existing role, Prowler Cloud creates a new role with that name **with read-only access** (visibility over all providers, no management permissions). A Prowler administrator can adjust its permissions afterward through the [RBAC Management](/user-guide/tutorials/prowler-app-rbac) tab.
- If `userType` is not set, the user's existing roles are left unchanged.
The `userType` value is **case-sensitive** - for example, `Backend` and `backend` are treated as different roles.
@@ -148,13 +152,13 @@ If attempting to use the "Test SAML login" option in Google Admin Console and re
---
-## Part B - Prowler App Configuration
+## Part B - Prowler Cloud Configuration
### Step 1: Open the SAML Configuration Dialog
1. Navigate to the profile settings page:
- **Prowler Cloud**: `https://cloud.prowler.com/profile`
- - **Self-hosted**: `http://{your-domain}/profile`
+ - **Prowler Local Server**: `http://{your-domain}/profile`
2. Find the "SAML SSO Integration" card and click "Enable" (or "Update" if already configured).
3. The "Configure SAML SSO" dialog opens, displaying:
- **ACS URL**: The Assertion Consumer Service URL (copy this value for Part A, Step 4). This URL updates dynamically when the email domain is entered.
@@ -162,21 +166,21 @@ If attempting to use the "Test SAML login" option in Google Admin Console and re
- **Name ID Format**: The expected format (`urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`).
- **Supported Assertion Attributes**: The list of accepted attributes (`firstName`, `lastName`, `userType`, `organization`).
-
+
### Step 2: Enter the Email Domain and Upload Metadata
-1. Enter the **email domain** for the organization (e.g., `prowler.cloud`). Prowler App uses this domain to identify users who should authenticate via SAML. The ACS URL updates automatically to reflect the configured domain.
+1. Enter the **email domain** for the organization (e.g., `prowler.cloud`). Prowler Cloud uses this domain to identify users who should authenticate via SAML. The ACS URL updates automatically to reflect the configured domain.
2. Upload the **metadata XML file** downloaded in Part A, Step 3.
3. Click "Save".
-
+
### Step 3: Verify the Enabled Status
The "SAML SSO Integration" card should now display a **"Status: Enabled"** indicator with a checkmark, confirming that the configuration is complete.
-
+
---
@@ -214,13 +218,13 @@ To test the `userType` → role mapping, set the **Department** attribute in the
1. Navigate to the Prowler login page.
2. Click "Continue with SAML SSO".
3. Enter an email from the configured domain (e.g., `adrian@prowler.cloud`).
-4. Click "Log in". The browser redirects to Google for authentication and returns to Prowler App upon success.
+4. Click "Log in". The browser redirects to Google for authentication and returns to Prowler Cloud upon success.
-
+
### Verify User Profile and Role Mapping
-After a successful SSO login, the user profile in Prowler App reflects the attributes sent by Google Workspace:
+After a successful SSO login, the user profile in Prowler Cloud reflects the attributes sent by Google Workspace:
- **Name**: Populated from the `firstName` and `lastName` attributes.
- **Role**: Created automatically from the `userType` attribute (e.g., `Backend`). If the role did not exist previously, it is created with read-only access by default.
@@ -230,14 +234,14 @@ After a successful SSO login, the user profile in Prowler App reflects the attri
For more details on role assignment behavior and attribute mapping, refer to the [SAML SSO Configuration](/user-guide/tutorials/prowler-app-sso#configure-attribute-mapping-in-the-idp) page.
-
+
### IdP-Initiated SSO (from Google)
1. Sign in to Google Workspace with an account that has access to the Prowler SAML app.
2. Open the Google Workspace app launcher (the grid icon in the top-right corner of any Google page).
-3. Click the Prowler app tile.
-4. The browser redirects directly to Prowler App, authenticated.
+3. Click the Prowler tile.
+4. The browser redirects directly to Prowler Cloud, authenticated.
For more information on the SSO login flows, refer to the [SAML SSO Configuration](/user-guide/tutorials/prowler-app-sso#idp-initiated-sso) page.
@@ -270,7 +274,7 @@ Prowler does not allow two tenants to share the same email domain. If the domain
**Just-in-Time Provisioning**
-Users who authenticate via SAML for the first time are automatically created in Prowler App. No prior invitation is needed. User attributes (`firstName`, `lastName`, `userType`) are updated on every login from the Google directory.
+Users who authenticate via SAML for the first time are automatically created in Prowler Cloud. No prior invitation is needed. User attributes (`firstName`, `lastName`, `userType`) are updated on every login from the Google directory.
@@ -278,10 +282,10 @@ Users who authenticate via SAML for the first time are automatically created in
## Quick Summary
-1. In **Google Admin Console**, create a custom SAML app using the ACS URL and Entity ID from Prowler App.
+1. In **Google Admin Console**, create a custom SAML app using the ACS URL and Entity ID from Prowler Cloud.
2. Configure **attribute mapping**: `firstName`, `lastName`, and optionally `userType` and `organization`.
3. **Download the metadata XML** from Google.
4. **Enable the app** in Google Workspace for the relevant users or groups.
-5. In **Prowler App**, enter the email domain, upload the metadata XML, and save.
+5. In **Prowler Cloud**, enter the email domain, upload the metadata XML, and save.
6. Verify the SAML SSO Integration shows **"Status: Enabled"**.
7. Test login via "Continue with SAML SSO" on the Prowler login page.
diff --git a/docs/user-guide/tutorials/prowler-app-sso.mdx b/docs/user-guide/tutorials/prowler-app-sso.mdx
index 84cccd3d65..bb993942cd 100644
--- a/docs/user-guide/tutorials/prowler-app-sso.mdx
+++ b/docs/user-guide/tutorials/prowler-app-sso.mdx
@@ -1,18 +1,22 @@
---
title: 'SAML Single Sign-On (SSO)'
+sidebarTitle: 'SAML SSO'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
+import { AppliesTo } from "/snippets/applies-to.mdx"
-This guide provides comprehensive instructions to configure SAML-based Single Sign-On (SSO) in Prowler App. This configuration allows users to authenticate using the organization's Identity Provider (IdP).
+
+
+This guide provides comprehensive instructions to configure SAML-based Single Sign-On (SSO) in Prowler Cloud. This configuration allows users to authenticate using the organization's Identity Provider (IdP).
This document is divided into two main sections:
-- **[User Guide](#user-guide-configuration)**: For organization administrators to configure SAML SSO through Prowler App.
+- **[User Guide](#user-guide-configuration)**: For organization administrators to configure SAML SSO through Prowler Cloud.
-- **[Developer and Administrator Guide](#developer-and-administrator-guide)**: For developers and system administrators running self-hosted Prowler App instances, providing technical details on environment configuration, API usage, and testing.
+- **[Developer and Administrator Guide](#developer-and-administrator-guide)**: For developers and system administrators running Prowler Local Server instances, providing technical details on environment configuration, API usage, and testing.
---
@@ -43,7 +47,7 @@ If the SAML configuration is removed, users who previously authenticated via SAM
#### Step 1: Access Profile Settings
-To access the account settings, click the "Account" button in the top-right corner of Prowler App, or navigate directly to `https://cloud.prowler.com/profile` (or `http://localhost:3000/profile` for local setups).
+To access the account settings, click the "Account" button in the top-right corner of Prowler Cloud, or navigate directly to `https://cloud.prowler.com/profile` (or `http://localhost:3000/profile` for local setups).

@@ -63,12 +67,12 @@ Choose a Method:
- Prowler App displays the SAML configuration information needed to configure the IdP. Use this information to create a new SAML application in the IdP.
+ Prowler Cloud displays the SAML configuration information needed to configure the IdP. Use this information to create a new SAML application in the IdP.
1. **Assertion Consumer Service (ACS) URL**: The endpoint in Prowler that will receive the SAML assertion from the IdP.
2. **Audience URI (Entity ID)**: A unique identifier for the Prowler application (Service Provider).
- To configure the IdP, copy the **ACS URL** and **Audience URI** from Prowler App and use them to set up a new SAML application.
+ To configure the IdP, copy the **ACS URL** and **Audience URI** from Prowler Cloud and use them to set up a new SAML application.

@@ -81,13 +85,13 @@ Choose a Method:
**Configure Attribute Mapping in the IdP**
- For Prowler App to correctly identify and provision users, configure the IdP to send the following attributes in the SAML assertion:
+ For Prowler Cloud to correctly identify and provision users, configure the IdP to send the following attributes in the SAML assertion:
| Attribute Name | Description | Required |
|----------------|---------------------------------------------------------------------------------------------------------|----------|
| `firstName` | The user's first name. | Yes |
| `lastName` | The user's last name. | Yes |
- | `userType` | Determines which Prowler role the user receives (e.g., `admin`, `auditor`). If a role with that name already exists, the user receives it automatically; if it does not exist, Prowler App creates a new role with that name with read-only access (visibility over all providers, no management permissions). If `userType` is not defined, the user's existing roles are left unchanged. Role permissions can be edited in the [RBAC Management tab](/user-guide/tutorials/prowler-app-rbac). | No |
+ | `userType` | Determines which Prowler role the user receives (e.g., `admin`, `auditor`). If a role with that name already exists, the user receives it automatically; if it does not exist, Prowler Cloud creates a new role with that name with read-only access (visibility over all providers, no management permissions). If `userType` is not defined, the user's existing roles are left unchanged. Role permissions can be edited in the [RBAC Management tab](/user-guide/tutorials/prowler-app-rbac). | No |
| `organization` | The user's company name. | No |
@@ -100,13 +104,13 @@ Choose a Method:
**Single-Value `userType` Required**
- Map `userType` to an IdP attribute that always contains a single value. If the IdP sends multiple values, Prowler App uses only the first value and does not assign multiple roles or select the highest-privilege role.
+ Map `userType` to an IdP attribute that always contains a single value. If the IdP sends multiple values, Prowler Cloud uses only the first value and does not assign multiple roles or select the highest-privilege role.
**Dynamic Updates**
- Prowler App updates these attributes each time a user logs in. Any changes made in the Identity Provider (IdP) will be reflected when the user logs in again.
+ Prowler Cloud updates these attributes each time a user logs in. Any changes made in the Identity Provider (IdP) will be reflected when the user logs in again.
@@ -138,31 +142,31 @@ Choose a Method:

- 7. **Configure User Attributes in Okta**: Okta acts as the central source for user profile information. Prowler App maps the following Okta user profile attributes during each SAML login:
+ 7. **Configure User Attributes in Okta**: Okta acts as the central source for user profile information. Prowler Cloud maps the following Okta user profile attributes during each SAML login:
- * **First name** (`firstName`): Maps to the user's first name in Prowler App.
- * **Last name** (`lastName`): Maps to the user's last name in Prowler App.
+ * **First name** (`firstName`): Maps to the user's first name in Prowler Cloud.
+ * **Last name** (`lastName`): Maps to the user's last name in Prowler Cloud.

- * **Organization** (`organization`): Maps to the company name displayed in Prowler App. This attribute is optional.
- * **User type** (`userType`): Determines the Prowler role assigned to the user. This attribute is **case-sensitive**: if it matches the exact name of an existing role in Prowler App the user receives that role; if no role with that name exists, a new one is created with read-only access.
+ * **Organization** (`organization`): Maps to the company name displayed in Prowler Cloud. This attribute is optional.
+ * **User type** (`userType`): Determines the Prowler role assigned to the user. This attribute is **case-sensitive**: if it matches the exact name of an existing role in Prowler Cloud the user receives that role; if no role with that name exists, a new one is created with read-only access.

- To modify these values, edit the user's profile directly in the Okta admin console under the "Profile" tab. Changes are reflected in Prowler App the next time the user logs in via SAML.
+ To modify these values, edit the user's profile directly in the Okta admin console under the "Profile" tab. Changes are reflected in Prowler Cloud the next time the user logs in via SAML.
**User Type and Role Assignment**
The `userType` attribute controls which Prowler role is assigned to the user:
- * If a role with the specified name already exists in Prowler App, the user automatically receives that role.
- * If the role does not exist, Prowler App creates a new role with that exact name with read-only access: the user can see all providers and their findings but cannot manage anything. A Prowler administrator (a user whose role includes the "Manage Account" permission) can adjust its permissions afterward through the [RBAC Management tab](/user-guide/tutorials/prowler-app-rbac).
- * If `userType` is not defined in the user's Okta profile, the user's existing roles in Prowler App are left unchanged.
- * `userType` must contain a single value. If the IdP sends multiple values, Prowler App uses only the first value and does not assign multiple roles.
+ * If a role with the specified name already exists in Prowler Cloud, the user automatically receives that role.
+ * If the role does not exist, Prowler Cloud creates a new role with that exact name with read-only access: the user can see all providers and their findings but cannot manage anything. A Prowler administrator (a user whose role includes the "Manage Account" permission) can adjust its permissions afterward through the [RBAC Management tab](/user-guide/tutorials/prowler-app-rbac).
+ * If `userType` is not defined in the user's Okta profile, the user's existing roles in Prowler Cloud are left unchanged.
+ * `userType` must contain a single value. If the IdP sends multiple values, Prowler Cloud uses only the first value and does not assign multiple roles.
- **Example:** To assign the `IT` role to a user, set the `userType` value to `IT` in Okta. If a role named `IT` already exists in Prowler App, the user receives it automatically upon login. If it does not exist, Prowler App creates a new role called `IT` with read-only access, and a Prowler administrator can adjust its permissions as needed.
+ **Example:** To assign the `IT` role to a user, set the `userType` value to `IT` in Okta. If a role named `IT` already exists in Prowler Cloud, the user receives it automatically upon login. If it does not exist, Prowler Cloud creates a new role called `IT` with read-only access, and a Prowler administrator can adjust its permissions as needed.
@@ -178,11 +182,11 @@ Choose a Method:
Once the IdP is configured, it provides a **metadata XML file**. This file contains the IdP's configuration information, such as its public key and login URL.
-To complete the Prowler App configuration:
+To complete the Prowler Cloud configuration:
1. Return to the Prowler SAML configuration page.
-2. Enter the **email domain** for the organization (e.g., `mycompany.com`). Prowler App uses this to identify users who should authenticate via SAML.
+2. Enter the **email domain** for the organization (e.g., `mycompany.com`). Prowler Cloud uses this to identify users who should authenticate via SAML.
3. Upload the **metadata XML file** downloaded from the IdP.
@@ -225,7 +229,7 @@ Users can also initiate the login process directly from Prowler's login page:
3. Enter their email address from the configured domain

4. The system redirects users to the IdP for authentication
-5. After successful authentication, users are returned to Prowler App
+5. After successful authentication, users are returned to Prowler Cloud
This method is useful when users bookmark Prowler or navigate directly to the application.
@@ -233,11 +237,11 @@ This method is useful when users bookmark Prowler or navigate directly to the ap
## Developer and Administrator Guide
-This section provides technical details for developers and administrators of self-hosted Prowler instances.
+This section provides technical details for developers and administrators of Prowler Local Server instances.
### Environment Configuration
-For self-hosted deployments, several environment variables must be configured to ensure SAML SSO functions correctly. These variables are typically set in an `.env` file.
+For Prowler Local Server deployments, several environment variables must be configured to ensure SAML SSO functions correctly. These variables are typically set in an `.env` file.
| Variable | Description | Example |
|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|
diff --git a/docs/user-guide/tutorials/prowler-app.mdx b/docs/user-guide/tutorials/prowler-app.mdx
index 51ebdde861..6c3131d136 100644
--- a/docs/user-guide/tutorials/prowler-app.mdx
+++ b/docs/user-guide/tutorials/prowler-app.mdx
@@ -1,21 +1,22 @@
---
title: 'Prowler Cloud'
+sidebarTitle: 'Getting Started'
---
import { ProviderCards } from "/snippets/provider-cards.mdx"
**Prowler Cloud** is a web application that simplifies running Prowler. This tutorial will guide you through setting up and using it.
-We refer to **Prowler App** as the self-hosted version of **Prowler Cloud**.
+**Prowler Local Server** is the self-hosted version of **Prowler Cloud**. See [Prowler product families](/getting-started/products) for every official product name.
## Accessing Prowler Cloud and API Documentation
If you are a [Prowler Cloud](https://cloud.prowler.com/sign-in) user, you can access API docs at [https://api.prowler.com/api/v1/docs](https://api.prowler.com/api/v1/docs)
-**For Prowler App users**
+**For Prowler Local Server users**
-After [installing](/getting-started/installation/prowler-app) **Prowler App**, access it at [http://localhost:3000](http://localhost:3000).
+After [installing](/getting-started/installation/prowler-app) **Prowler Local Server**, access it at [http://localhost:3000](http://localhost:3000).
To view the auto-generated **Prowler API** documentation, navigate to [http://localhost:8080/api/v1/docs](http://localhost:8080/api/v1/docs). This documentation provides details on available endpoints, parameters, and responses.
@@ -44,7 +45,7 @@ See [how to configure Social Login for Prowler](/user-guide/tutorials/prowler-ap
## Step 2: Log In
-Once registered, log in with your email and password to access Prowler App.
+Once registered, log in with your email and password to access Prowler Cloud.
@@ -84,7 +85,7 @@ For detailed instructions on configuring credentials for each provider, refer to
## Step 5: Test Connection
-After adding your credentials of your cloud account, click the `Launch` button to verify that Prowler App can successfully connect to your provider:
+After adding your credentials of your cloud account, click the `Launch` button to verify that Prowler can successfully connect to your provider:
diff --git a/docs/user-guide/tutorials/prowler-cloud-aws-organizations.mdx b/docs/user-guide/tutorials/prowler-cloud-aws-organizations.mdx
index 2a6128e92e..8bb6e320ae 100644
--- a/docs/user-guide/tutorials/prowler-cloud-aws-organizations.mdx
+++ b/docs/user-guide/tutorials/prowler-cloud-aws-organizations.mdx
@@ -1,5 +1,5 @@
---
-title: 'AWS Organizations in Prowler Cloud'
+title: 'AWS Organizations'
description: 'Onboard all AWS accounts in your Organization through a single guided wizard'
---
@@ -464,7 +464,7 @@ Each AWS account you connect through the Organizations wizard counts as one **pr
- **Large organizations**: connecting a 500-account organization will result in up to 500 providers on your subscription. Review your plan limits before proceeding.
- **Deleted providers**: if you later remove an account, the deleted provider no longer counts toward your subscription.
-For pricing details, see [Prowler Cloud Pricing](/getting-started/products/prowler-cloud-pricing).
+For pricing details, see [Prowler Cloud Pricing](https://prowler.com/pricing).
## Troubleshooting
@@ -505,7 +505,7 @@ No accounts pass the connection test.
- Verify the CloudFormation StackSet was deployed — complete [Step 2](#step-2-deploy-the-cloudformation-stackset) and wait for stack instances to reach **CREATE_COMPLETE**
- Check that the **ExternalId** parameter in the StackSet matches the External ID shown in the Prowler wizard
-- If your accounts use IP-based IAM policies, allow [Prowler Cloud public IPs](/user-guide/tutorials/prowler-cloud-public-ips)
+- If your accounts use IP-based IAM policies, allow [Prowler Cloud egress IPs](/security/networking)
### Connection Test Fails for Some Accounts
diff --git a/docs/user-guide/tutorials/prowler-cloud-azure-management-groups.mdx b/docs/user-guide/tutorials/prowler-cloud-azure-management-groups.mdx
new file mode 100644
index 0000000000..98cfe095ce
--- /dev/null
+++ b/docs/user-guide/tutorials/prowler-cloud-azure-management-groups.mdx
@@ -0,0 +1,11 @@
+---
+title: 'Azure Management Groups'
+description: 'Onboard all Azure subscriptions in your management groups through a single guided wizard'
+tag: "Coming Soon"
+---
+
+Onboarding Azure management groups through a single guided wizard is coming soon to Prowler Cloud.
+
+Today, Azure subscriptions are onboarded individually. See [Getting Started with Azure](/user-guide/providers/azure/getting-started-azure) and [Bulk Provider Provisioning](/user-guide/tutorials/bulk-provider-provisioning) to automate onboarding multiple subscriptions.
+
+Keep an eye on the [changelog](https://github.com/prowler-cloud/prowler/releases) for updates.
diff --git a/docs/user-guide/tutorials/prowler-cloud-gcp-organizations.mdx b/docs/user-guide/tutorials/prowler-cloud-gcp-organizations.mdx
new file mode 100644
index 0000000000..c0c11747a9
--- /dev/null
+++ b/docs/user-guide/tutorials/prowler-cloud-gcp-organizations.mdx
@@ -0,0 +1,11 @@
+---
+title: 'GCP Organizations'
+description: 'Onboard all GCP projects in your organization through a single guided wizard'
+tag: "Coming Soon"
+---
+
+Onboarding a full GCP organization through a single guided wizard is coming soon to Prowler Cloud.
+
+Today, GCP projects are onboarded individually. See [Getting Started with GCP](/user-guide/providers/gcp/getting-started-gcp) and [Bulk Provider Provisioning](/user-guide/tutorials/bulk-provider-provisioning) to automate onboarding multiple projects.
+
+Keep an eye on the [changelog](https://github.com/prowler-cloud/prowler/releases) for updates.
diff --git a/docs/user-guide/tutorials/prowler-cloud-lighthouse-multi-llm.mdx b/docs/user-guide/tutorials/prowler-cloud-lighthouse-multi-llm.mdx
index ea19b1fe7f..0cb251df1f 100644
--- a/docs/user-guide/tutorials/prowler-cloud-lighthouse-multi-llm.mdx
+++ b/docs/user-guide/tutorials/prowler-cloud-lighthouse-multi-llm.mdx
@@ -1,5 +1,6 @@
---
title: 'Using Multiple LLM Providers'
+sidebarTitle: 'Multiple LLM Providers'
---
import { SubscriptionBanner } from "/snippets/subscription-banner.mdx"
diff --git a/docs/user-guide/tutorials/prowler-cloud-public-ips.mdx b/docs/user-guide/tutorials/prowler-cloud-public-ips.mdx
deleted file mode 100644
index f3b285056c..0000000000
--- a/docs/user-guide/tutorials/prowler-cloud-public-ips.mdx
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: 'Prowler Cloud Public IPs'
----
-
-## Overview
-
-Prowler Cloud uses a dedicated egress IPv4 address for all outbound connections to customer infrastructure. This enables organizations to implement network-level security controls by whitelisting Prowler's IP address.
-
-## Use Cases
-
-Whitelisting Prowler's egress IP address enables:
-
-- **Credential Usage Control**: Restrict where cloud provider credentials can be used from across AWS, Azure, GCP, and other providers
-- **Kubernetes Security**: Limit inbound HTTPS traffic to clusters by allowing only Prowler's IP address
-- **Compliance Requirements**: Meet security policies requiring allowlisting of external services
-
-## Query the Egress IP Address
-
-Retrieve Prowler Cloud's current egress IP address using the following command:
-
-```bash
-dig egress.prowler.com +short
-```
-
-This command returns the IPv4 address that Prowler Cloud uses for all outbound connections to customer infrastructure.
-
-
-The egress IP address is stable, but it is recommended to periodically verify it remains current by querying `egress.prowler.com`.
-
diff --git a/docs/user-guide/tutorials/prowler-import-findings.mdx b/docs/user-guide/tutorials/prowler-import-findings.mdx
index e02f3ee7a5..530cd160ee 100644
--- a/docs/user-guide/tutorials/prowler-import-findings.mdx
+++ b/docs/user-guide/tutorials/prowler-import-findings.mdx
@@ -1,5 +1,6 @@
---
title: 'Import Findings'
+sidebarTitle: 'Import Findings'
description: 'Upload OCSF scan results to Prowler Cloud from external sources or the CLI'
---
@@ -133,7 +134,7 @@ Only **Detection Finding** (`class_uid: 2004`) records are accepted. Other OCSF
The **Manage Ingestions** RBAC permission controls access to the ingestion endpoints. Without this permission, findings cannot be submitted via the API or `--push-to-cloud`.
-For more information about RBAC permissions, refer to the [Prowler App RBAC documentation](/user-guide/tutorials/prowler-app-rbac).
+For more information about RBAC permissions, refer to the [Prowler Cloud RBAC documentation](/user-guide/tutorials/prowler-app-rbac).
## Using the CLI
diff --git a/docs/user-guide/tutorials/prowler-scan-scheduling.mdx b/docs/user-guide/tutorials/prowler-scan-scheduling.mdx
index 961d32ad14..f909ed2fa0 100644
--- a/docs/user-guide/tutorials/prowler-scan-scheduling.mdx
+++ b/docs/user-guide/tutorials/prowler-scan-scheduling.mdx
@@ -1,6 +1,7 @@
---
title: 'Scan Scheduling'
-description: 'Create, edit, and monitor recurring scans in Prowler Cloud and Enterprise.'
+sidebarTitle: 'Scheduling'
+description: 'Create, edit, and monitor recurring scans in Prowler Cloud and Prowler Private Cloud.'
---
import { VersionBadge } from "/snippets/version-badge.mdx"
@@ -21,11 +22,11 @@ Before creating or editing scan schedules, ensure that:
## Schedule Options
-A Prowler Cloud or Enterprise subscription supports the following custom recurring schedule options. Prowler self-hosted runs a daily scan automatically and does not expose custom cadence controls.
+A Prowler Cloud or Prowler Private Cloud subscription supports the following custom recurring schedule options. Prowler Local Server runs a daily scan automatically and does not expose custom cadence controls.
-| Schedule Option | Description | Cloud & Enterprise | Self-Hosted |
-|-----------------|-------------|--------------------|-------------|
-| Daily | Runs one scan every day at the selected time. | Yes | Yes |
+| Schedule Option | Description | Prowler Cloud & Prowler Private Cloud | Prowler Local Server |
+|-----------------|-------------|---------------------------------------|----------------------|
+| Daily | Runs one scan every day at the selected time. | Yes | Automatic |
| Every 48 hours | Runs one scan every 48 hours, anchored to the selected time. | Yes | — |
| Weekly | Runs one scan every week on the selected day and time. | Yes | — |
| Monthly | Runs one scan every month on the selected day, from day 1 to day 28. | Yes | — |
From 24b670ac364a83d03eb16f5ba4135b132740a033 Mon Sep 17 00:00:00 2001
From: Deep Shah <66430880+Deep070203@users.noreply.github.com>
Date: Wed, 15 Jul 2026 07:44:20 -0400
Subject: [PATCH 20/22] feat(sdk): add AWS Amplify app secret scanning check
(#11825)
Co-authored-by: Daniel Barranquero
---
permissions/prowler-additions-policy.json | 2 +
.../cloudformation/prowler-scan-role.yml | 2 +
.../amplify-app-secrets-check.added.md | 1 +
.../aws/services/amplify/__init__.py | 0
.../__init__.py | 0
...pp_no_secrets_in_environment.metadata.json | 42 ++++
.../amplify_app_no_secrets_in_environment.py | 105 ++++++++++
.../aws/services/amplify/amplify_client.py | 4 +
.../aws/services/amplify/amplify_service.py | 97 +++++++++
...lify_app_no_secrets_in_environment_test.py | 194 ++++++++++++++++++
.../services/amplify/amplify_service_test.py | 91 ++++++++
11 files changed, 538 insertions(+)
create mode 100644 prowler/changelog.d/amplify-app-secrets-check.added.md
create mode 100644 prowler/providers/aws/services/amplify/__init__.py
create mode 100644 prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/__init__.py
create mode 100644 prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment.metadata.json
create mode 100644 prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment.py
create mode 100644 prowler/providers/aws/services/amplify/amplify_client.py
create mode 100644 prowler/providers/aws/services/amplify/amplify_service.py
create mode 100644 tests/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment_test.py
create mode 100644 tests/providers/aws/services/amplify/amplify_service_test.py
diff --git a/permissions/prowler-additions-policy.json b/permissions/prowler-additions-policy.json
index ba56513732..6c58f6e184 100644
--- a/permissions/prowler-additions-policy.json
+++ b/permissions/prowler-additions-policy.json
@@ -4,6 +4,8 @@
{
"Action": [
"account:Get*",
+ "amplify:ListApps",
+ "amplify:ListBranches",
"appstream:Describe*",
"appstream:List*",
"backup:List*",
diff --git a/permissions/templates/cloudformation/prowler-scan-role.yml b/permissions/templates/cloudformation/prowler-scan-role.yml
index 96e6f7b2a5..c9eee71950 100644
--- a/permissions/templates/cloudformation/prowler-scan-role.yml
+++ b/permissions/templates/cloudformation/prowler-scan-role.yml
@@ -176,6 +176,8 @@ Resources:
Effect: Allow
Action:
- "account:Get*"
+ - "amplify:ListApps"
+ - "amplify:ListBranches"
- "appstream:Describe*"
- "appstream:List*"
- "backup:List*"
diff --git a/prowler/changelog.d/amplify-app-secrets-check.added.md b/prowler/changelog.d/amplify-app-secrets-check.added.md
new file mode 100644
index 0000000000..fa77779872
--- /dev/null
+++ b/prowler/changelog.d/amplify-app-secrets-check.added.md
@@ -0,0 +1 @@
+`amplify_app_no_secrets_in_environment` check for AWS provider, scanning Amplify app and branch environment variables and build settings for hardcoded secrets
diff --git a/prowler/providers/aws/services/amplify/__init__.py b/prowler/providers/aws/services/amplify/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/__init__.py b/prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment.metadata.json b/prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment.metadata.json
new file mode 100644
index 0000000000..1a5c209fcb
--- /dev/null
+++ b/prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment.metadata.json
@@ -0,0 +1,42 @@
+{
+ "Provider": "aws",
+ "CheckID": "amplify_app_no_secrets_in_environment",
+ "CheckTitle": "Amplify app has no sensitive credentials in environment variables or build settings",
+ "CheckType": [
+ "Software and Configuration Checks/AWS Security Best Practices",
+ "TTPs/Credential Access",
+ "Effects/Data Exposure",
+ "Sensitive Data Identifications/Security"
+ ],
+ "ServiceName": "amplify",
+ "SubServiceName": "",
+ "ResourceIdTemplate": "arn:partition:amplify:region:account-id:apps/app-id",
+ "Severity": "high",
+ "ResourceType": "AwsAmplifyApp",
+ "ResourceGroup": "security",
+ "Description": "AWS Amplify apps and their branches are inspected for hardcoded secrets, such as API keys, tokens, or passwords embedded in environment variables or build settings (buildSpec).",
+ "Risk": "Plaintext secrets in Amplify app environment variables or build configurations can be viewed by anyone with read access to the Amplify console, or may leak during the build process, exposing downstream resources and integrations.",
+ "RelatedUrl": "",
+ "AdditionalURLs": [
+ "https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html",
+ "https://docs.prowler.com/developer-guide/secret-scanning-checks"
+ ],
+ "Remediation": {
+ "Code": {
+ "CLI": "aws amplify update-app --app-id --environment-variables ",
+ "NativeIaC": "",
+ "Other": "1. Access the AWS Amplify console.\n2. Navigate to your app settings, choose Environment variables, and check if any secrets are stored in plaintext.\n3. For actual secrets, migrate them to environment secrets or AWS Secrets Manager / Parameter Store and reference them securely during the build phase.\n4. Clean the variables or buildSpec configuration.",
+ "Terraform": ""
+ },
+ "Recommendation": {
+ "Text": "Avoid storing secrets in plaintext environment variables or build specifications for AWS Amplify apps. Store sensitive settings securely in AWS Systems Manager Parameter Store or AWS Secrets Manager.",
+ "Url": "https://hub.prowler.com/check/amplify_app_no_secrets_in_environment"
+ }
+ },
+ "Categories": [
+ "secrets"
+ ],
+ "DependsOn": [],
+ "RelatedTo": [],
+ "Notes": ""
+}
diff --git a/prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment.py b/prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment.py
new file mode 100644
index 0000000000..33175c724f
--- /dev/null
+++ b/prowler/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment.py
@@ -0,0 +1,105 @@
+import json
+
+from prowler.lib.check.models import Check, Check_Report_AWS
+from prowler.lib.utils.utils import (
+ SecretsScanError,
+ annotate_verified_secrets,
+ detect_secrets_scan_batch,
+)
+from prowler.providers.aws.services.amplify.amplify_client import amplify_client
+
+
+class amplify_app_no_secrets_in_environment(Check):
+ """Check that AWS Amplify apps contain no hardcoded secrets in their environment variables or build settings."""
+
+ def execute(self) -> list[Check_Report_AWS]:
+ findings = []
+ secrets_ignore_patterns = amplify_client.audit_config.get(
+ "secrets_ignore_patterns", []
+ )
+ validate = amplify_client.audit_config.get("secrets_validate", False)
+ apps = list(amplify_client.apps.values())
+ line_context_by_app = {}
+
+ payloads_list = []
+ for app_index, app in enumerate(apps):
+ payload, line_context = _build_app_payload(app)
+ line_context_by_app[app_index] = line_context
+ if payload:
+ payloads_list.append((app_index, payload))
+
+ scan_error = None
+ try:
+ batch_results = detect_secrets_scan_batch(
+ payloads_list,
+ excluded_secrets=secrets_ignore_patterns,
+ validate=validate,
+ )
+ except SecretsScanError as error:
+ batch_results = {}
+ scan_error = error
+
+ for app_index, app in enumerate(apps):
+ report = Check_Report_AWS(metadata=self.metadata(), resource=app)
+ report.resource_tags = app.tags
+ report.status = "PASS"
+ report.status_extended = f"No secrets found in Amplify app {app.name} environment variables or build settings."
+
+ line_context = line_context_by_app.get(app_index, {})
+ if line_context:
+ if scan_error:
+ report.status = "MANUAL"
+ report.status_extended = (
+ f"Could not scan Amplify app {app.name} environment variables "
+ f"for secrets: {scan_error}; manual review is required."
+ )
+ findings.append(report)
+ continue
+
+ detect_secrets_output = batch_results.get(app_index)
+ if detect_secrets_output:
+ secrets_string = ", ".join(
+ [
+ f"{secret['type']} in {line_context.get(secret['line_number'], 'environment variables/build settings')}"
+ for secret in detect_secrets_output
+ ]
+ )
+ report.status = "FAIL"
+ report.status_extended = (
+ f"Potential {'secrets' if len(detect_secrets_output) > 1 else 'secret'} "
+ f"found in Amplify app {app.name} environment variables or build settings -> {secrets_string}."
+ )
+ annotate_verified_secrets(report, detect_secrets_output)
+
+ findings.append(report)
+ return findings
+
+
+def _build_app_payload(app) -> tuple[str, dict[int, str]]:
+ """Build a line-oriented scan payload and map each line to a field context."""
+ lines = []
+ line_context = {}
+
+ def add_line(context: str, value: str) -> None:
+ if value is None:
+ return
+ lines.append(json.dumps({context: value}))
+ line_context[len(lines)] = context
+
+ # App environment variables
+ for var_name, var_value in app.environment_variables.items():
+ add_line(f"app environment variable '{var_name}'", var_value)
+
+ # App buildSpec
+ if app.build_spec:
+ for idx, line in enumerate(app.build_spec.splitlines(), start=1):
+ add_line(f"app buildSpec line {idx}", line)
+
+ # Branch environment variables
+ for branch in app.branches:
+ for var_name, var_value in branch.environment_variables.items():
+ add_line(
+ f"branch '{branch.name}' environment variable '{var_name}'", var_value
+ )
+
+ return "\n".join(lines), line_context
diff --git a/prowler/providers/aws/services/amplify/amplify_client.py b/prowler/providers/aws/services/amplify/amplify_client.py
new file mode 100644
index 0000000000..9d69c68424
--- /dev/null
+++ b/prowler/providers/aws/services/amplify/amplify_client.py
@@ -0,0 +1,4 @@
+from prowler.providers.aws.services.amplify.amplify_service import Amplify
+from prowler.providers.common.provider import Provider
+
+amplify_client = Amplify(Provider.get_global_provider())
diff --git a/prowler/providers/aws/services/amplify/amplify_service.py b/prowler/providers/aws/services/amplify/amplify_service.py
new file mode 100644
index 0000000000..1a80f9ebd3
--- /dev/null
+++ b/prowler/providers/aws/services/amplify/amplify_service.py
@@ -0,0 +1,97 @@
+from botocore.exceptions import ClientError
+from pydantic.v1 import BaseModel, Field
+
+from prowler.lib.logger import logger
+from prowler.lib.scan_filters.scan_filters import is_resource_filtered
+from prowler.providers.aws.lib.service.service import AWSService
+
+
+class Branch(BaseModel):
+ """Represents an AWS Amplify App Branch."""
+
+ name: str
+ arn: str
+ environment_variables: dict = Field(default_factory=dict)
+
+
+class App(BaseModel):
+ """Represents an AWS Amplify App."""
+
+ id: str
+ name: str
+ arn: str
+ region: str
+ environment_variables: dict = Field(default_factory=dict)
+ build_spec: str = ""
+ branches: list[Branch] = Field(default_factory=list)
+ tags: list[dict] = Field(default_factory=list)
+
+
+class Amplify(AWSService):
+ """AWS Amplify service class."""
+
+ def __init__(self, provider):
+ super().__init__(__class__.__name__, provider)
+ self.apps = {}
+ self.__threading_call__(self._list_apps)
+ if self.apps:
+ self.__threading_call__(self._list_branches, self.apps.values())
+
+ def _list_apps(self, regional_client) -> None:
+ logger.info("Amplify - Listing apps...")
+ try:
+ list_apps_paginator = regional_client.get_paginator("list_apps")
+ for page in list_apps_paginator.paginate():
+ for app in page.get("apps", []):
+ app_id = app.get("appId")
+ app_name = app.get("name")
+ app_arn = app.get("appArn")
+ if not self.audit_resources or is_resource_filtered(
+ app_arn, self.audit_resources
+ ):
+ tags = app.get("tags", {})
+ tags_list = [tags] if tags else []
+ self.apps[app_arn] = App(
+ id=app_id,
+ name=app_name,
+ arn=app_arn,
+ region=regional_client.region,
+ environment_variables=app.get("environmentVariables", {}),
+ build_spec=app.get("buildSpec", ""),
+ tags=tags_list,
+ )
+ except ClientError as error:
+ logger.error(
+ f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
+ )
+ except Exception as error:
+ logger.error(
+ f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
+ )
+
+ def _list_branches(self, app: App) -> None:
+ logger.info(f"Amplify - Listing branches for app {app.name}...")
+ try:
+ regional_client = self.regional_clients[app.region]
+ list_branches_paginator = regional_client.get_paginator("list_branches")
+ for page in list_branches_paginator.paginate(appId=app.id):
+ for branch in page.get("branches", []):
+ branch_name = branch.get("branchName")
+ branch_arn = branch.get("branchArn")
+ app.branches.append(
+ Branch(
+ name=branch_name,
+ arn=branch_arn,
+ environment_variables=branch.get(
+ "environmentVariables", {}
+ ),
+ )
+ )
+ except ClientError as error:
+ logger.error(
+ f"{app.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
+ )
+ except Exception as error:
+ logger.error(
+ f"{app.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
+ )
diff --git a/tests/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment_test.py b/tests/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment_test.py
new file mode 100644
index 0000000000..e78bf364d3
--- /dev/null
+++ b/tests/providers/aws/services/amplify/amplify_app_no_secrets_in_environment/amplify_app_no_secrets_in_environment_test.py
@@ -0,0 +1,194 @@
+from unittest import mock
+
+from prowler.lib.utils.utils import SecretsScanError
+from prowler.providers.aws.services.amplify.amplify_service import App, Branch
+from tests.providers.aws.utils import (
+ AWS_ACCOUNT_NUMBER,
+ AWS_REGION_US_EAST_1,
+ set_mocked_aws_provider,
+)
+
+
+class Test_amplify_app_no_secrets_in_environment:
+ def test_no_apps(self):
+ amplify_client = mock.MagicMock()
+ amplify_client.apps = {}
+ amplify_client.audit_config = {"secrets_ignore_patterns": []}
+
+ result = _execute_check(amplify_client)
+
+ assert len(result) == 0
+
+ def test_app_with_no_secrets(self):
+ app = _build_app(
+ environment_variables={"key1": "val1"},
+ build_spec="version: 1\nfrontend:\n phases:\n build:\n commands:\n - echo hello",
+ branches=[
+ Branch(
+ name="main",
+ arn=f"arn:aws:amplify:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:apps/app-12345/branches/main",
+ environment_variables={"branch_key": "branch_val"},
+ )
+ ],
+ )
+ amplify_client = mock.MagicMock()
+ amplify_client.apps = {app.arn: app}
+ amplify_client.audit_config = {"secrets_ignore_patterns": []}
+
+ result = _execute_check(amplify_client)
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert (
+ result[0].status_extended
+ == "No secrets found in Amplify app test-app environment variables or build settings."
+ )
+ assert result[0].region == AWS_REGION_US_EAST_1
+ assert result[0].resource_id == "app-12345"
+ assert result[0].resource_arn == app.arn
+
+ def test_app_with_secrets_in_app_variables(self):
+ app = _build_app(
+ environment_variables={
+ "db_pass": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U"
+ },
+ build_spec="",
+ branches=[],
+ )
+ amplify_client = mock.MagicMock()
+ amplify_client.apps = {app.arn: app}
+ amplify_client.audit_config = {"secrets_ignore_patterns": []}
+
+ result = _execute_check(amplify_client)
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert "app environment variable 'db_pass'" in result[0].status_extended
+
+ def test_app_with_secrets_in_branch_variables(self):
+ app = _build_app(
+ environment_variables={},
+ build_spec="",
+ branches=[
+ Branch(
+ name="dev",
+ arn=f"arn:aws:amplify:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:apps/app-12345/branches/dev",
+ environment_variables={
+ "api_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U"
+ },
+ )
+ ],
+ )
+ amplify_client = mock.MagicMock()
+ amplify_client.apps = {app.arn: app}
+ amplify_client.audit_config = {"secrets_ignore_patterns": []}
+
+ result = _execute_check(amplify_client)
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert (
+ "branch 'dev' environment variable 'api_key'" in result[0].status_extended
+ )
+
+ def test_app_with_secrets_in_build_spec(self):
+ app = _build_app(
+ environment_variables={},
+ build_spec="version: 1\nfrontend:\n phases:\n build:\n commands:\n - export JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U",
+ branches=[],
+ )
+ amplify_client = mock.MagicMock()
+ amplify_client.apps = {app.arn: app}
+ amplify_client.audit_config = {"secrets_ignore_patterns": []}
+
+ result = _execute_check(amplify_client)
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert "app buildSpec line 6" in result[0].status_extended
+
+ def test_app_scan_error_marks_manual(self):
+ app = _build_app(
+ environment_variables={"key1": "val1"},
+ build_spec="version: 1",
+ branches=[],
+ )
+ amplify_client = mock.MagicMock()
+ amplify_client.apps = {app.arn: app}
+ amplify_client.audit_config = {"secrets_ignore_patterns": []}
+
+ result = _execute_check_with_mocked_scan(
+ amplify_client,
+ side_effect=SecretsScanError("Scanner failure"),
+ )
+
+ assert len(result) == 1
+ assert result[0].status == "MANUAL"
+ assert (
+ "Could not scan Amplify app test-app environment variables for secrets: Scanner failure"
+ in result[0].status_extended
+ )
+
+
+def _build_app(environment_variables: dict, build_spec: str, branches: list) -> App:
+ app_id = "app-12345"
+ app_name = "test-app"
+ app_arn = (
+ f"arn:aws:amplify:{AWS_REGION_US_EAST_1}:" f"{AWS_ACCOUNT_NUMBER}:apps/{app_id}"
+ )
+ return App(
+ id=app_id,
+ name=app_name,
+ arn=app_arn,
+ region=AWS_REGION_US_EAST_1,
+ environment_variables=environment_variables,
+ build_spec=build_spec,
+ branches=branches,
+ tags=[],
+ )
+
+
+def _execute_check(amplify_client):
+ aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
+ with (
+ mock.patch(
+ "prowler.providers.common.provider.Provider.get_global_provider",
+ return_value=aws_provider,
+ ),
+ mock.patch(
+ "prowler.providers.aws.services.amplify.amplify_app_no_secrets_in_environment.amplify_app_no_secrets_in_environment.amplify_client",
+ amplify_client,
+ ),
+ ):
+ from prowler.providers.aws.services.amplify.amplify_app_no_secrets_in_environment.amplify_app_no_secrets_in_environment import (
+ amplify_app_no_secrets_in_environment,
+ )
+
+ check = amplify_app_no_secrets_in_environment()
+ return check.execute()
+
+
+def _execute_check_with_mocked_scan(
+ amplify_client, return_value=None, side_effect=None
+):
+ aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
+ with (
+ mock.patch(
+ "prowler.providers.common.provider.Provider.get_global_provider",
+ return_value=aws_provider,
+ ),
+ mock.patch(
+ "prowler.providers.aws.services.amplify.amplify_app_no_secrets_in_environment.amplify_app_no_secrets_in_environment.amplify_client",
+ amplify_client,
+ ),
+ ):
+ import prowler.providers.aws.services.amplify.amplify_app_no_secrets_in_environment.amplify_app_no_secrets_in_environment as check_module
+
+ with mock.patch.object(
+ check_module,
+ "detect_secrets_scan_batch",
+ return_value=return_value,
+ side_effect=side_effect,
+ ):
+ check = check_module.amplify_app_no_secrets_in_environment()
+ return check.execute()
diff --git a/tests/providers/aws/services/amplify/amplify_service_test.py b/tests/providers/aws/services/amplify/amplify_service_test.py
new file mode 100644
index 0000000000..90ff5b67ab
--- /dev/null
+++ b/tests/providers/aws/services/amplify/amplify_service_test.py
@@ -0,0 +1,91 @@
+from unittest.mock import patch
+
+import botocore
+from moto import mock_aws
+
+from prowler.providers.aws.services.amplify.amplify_service import Amplify, App, Branch
+from tests.providers.aws.utils import (
+ AWS_ACCOUNT_NUMBER,
+ AWS_REGION_US_EAST_1,
+ set_mocked_aws_provider,
+)
+
+app_id = "app-12345"
+app_name = "test-app"
+app_arn = f"arn:aws:amplify:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:apps/{app_id}"
+branch_name = "main"
+branch_arn = f"{app_arn}/branches/{branch_name}"
+
+app_environment_variables = {"app_key": "app_val"}
+branch_environment_variables = {"branch_key": "branch_val"}
+build_spec = "version: 1"
+app_tags = {"tag_key": "tag_val"}
+
+make_api_call = botocore.client.BaseClient._make_api_call
+
+
+def mock_make_api_call(self, operation_name, kwarg):
+ if operation_name == "ListApps":
+ return {
+ "apps": [
+ {
+ "appId": app_id,
+ "name": app_name,
+ "appArn": app_arn,
+ "environmentVariables": app_environment_variables,
+ "buildSpec": build_spec,
+ "tags": app_tags,
+ }
+ ]
+ }
+ if operation_name == "ListBranches":
+ return {
+ "branches": [
+ {
+ "branchArn": branch_arn,
+ "branchName": branch_name,
+ "environmentVariables": branch_environment_variables,
+ }
+ ]
+ }
+ return make_api_call(self, operation_name, kwarg)
+
+
+def mock_generate_regional_clients(provider, service):
+ regional_client = provider._session.current_session.client(
+ service, region_name=AWS_REGION_US_EAST_1
+ )
+ regional_client.region = AWS_REGION_US_EAST_1
+ return {AWS_REGION_US_EAST_1: regional_client}
+
+
+@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
+@patch(
+ "prowler.providers.aws.aws_provider.AwsProvider.generate_regional_clients",
+ new=mock_generate_regional_clients,
+)
+class TestAmplifyService:
+ @mock_aws
+ def test_amplify_service(self):
+ amplify = Amplify(set_mocked_aws_provider([AWS_REGION_US_EAST_1]))
+
+ assert amplify.session.__class__.__name__ == "Session"
+ assert amplify.service == "amplify"
+ assert len(amplify.apps) == 1
+ assert isinstance(amplify.apps[app_arn], App)
+
+ app = amplify.apps[app_arn]
+ assert app.id == app_id
+ assert app.name == app_name
+ assert app.arn == app_arn
+ assert app.region == AWS_REGION_US_EAST_1
+ assert app.environment_variables == app_environment_variables
+ assert app.build_spec == build_spec
+ assert app.tags == [app_tags]
+
+ assert len(app.branches) == 1
+ branch = app.branches[0]
+ assert isinstance(branch, Branch)
+ assert branch.name == branch_name
+ assert branch.arn == branch_arn
+ assert branch.environment_variables == branch_environment_variables
From 8e9af708f88710c1ece292dd61049be2f2022e4d Mon Sep 17 00:00:00 2001
From: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com>
Date: Wed, 15 Jul 2026 12:45:23 +0100
Subject: [PATCH 21/22] feat(aws): add elbv2_listener_pqc_tls_enabled security
check (#11254)
---
.../cli/tutorials/configuration_file.mdx | 1 +
.../elbv2-listener-pqc-tls-enabled.added.md | 1 +
...itected_framework_security_pillar_aws.json | 1 +
prowler/compliance/aws/ccc_aws.json | 1 +
prowler/compliance/aws/ens_rd2022_aws.json | 2 +
.../aws/fedramp_moderate_revision_4_aws.json | 2 +
prowler/compliance/aws/ffiec_aws.json | 1 +
.../aws/gxp_21_cfr_part_11_aws.json | 1 +
prowler/compliance/aws/iso27001_2013_aws.json | 1 +
.../compliance/aws/kisa_isms_p_2023_aws.json | 2 +
.../aws/kisa_isms_p_2023_korean_aws.json | 2 +
.../aws/nist_800_171_revision_2_aws.json | 1 +
.../aws/nist_800_53_revision_5_aws.json | 1 +
.../aws/rbi_cyber_security_framework_aws.json | 1 +
.../compliance/aws/secnumcloud_3.2_aws.json | 1 +
prowler/config/config.yaml | 15 +
prowler/config/schema/aws.py | 4 +
.../__init__.py | 0
...bv2_listener_pqc_tls_enabled.metadata.json | 42 ++
.../elbv2_listener_pqc_tls_enabled.py | 73 ++
.../aws/services/elbv2/elbv2_service.py | 6 +
tests/config/config_test.py | 13 +
tests/config/fixtures/config.yaml | 15 +
tests/config/schema/aws_schema_test.py | 27 +
.../elbv2_listener_pqc_tls_enabled_test.py | 673 ++++++++++++++++++
25 files changed, 887 insertions(+)
create mode 100644 prowler/changelog.d/elbv2-listener-pqc-tls-enabled.added.md
create mode 100644 prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/__init__.py
create mode 100644 prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled.metadata.json
create mode 100644 prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled.py
create mode 100644 tests/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled_test.py
diff --git a/docs/user-guide/cli/tutorials/configuration_file.mdx b/docs/user-guide/cli/tutorials/configuration_file.mdx
index e2b05e39db..e637ea9c9a 100644
--- a/docs/user-guide/cli/tutorials/configuration_file.mdx
+++ b/docs/user-guide/cli/tutorials/configuration_file.mdx
@@ -78,6 +78,7 @@ The following list includes all the AWS checks with configurable variables that
| `elasticache_redis_cluster_backup_enabled` | `minimum_snapshot_retention_period` | Integer | `7` |
| `elb_is_in_multiple_az` | `elb_min_azs` | Integer | `2` |
| `elbv2_is_in_multiple_az` | `elbv2_min_azs` | Integer | `2` |
+| `elbv2_listener_pqc_tls_enabled` | `elbv2_listener_pqc_tls_allowed_policies` | List of Strings | See `config.yaml` |
| `eventbridge_bus_cross_account_access` | `trusted_account_ids` | List of Strings | `[]` |
| `eventbridge_schema_registry_cross_account_access` | `trusted_account_ids` | List of Strings | `[]` |
| `glue_etl_jobs_no_secrets_in_arguments` | `secrets_ignore_patterns` | List of Strings | `[]` |
diff --git a/prowler/changelog.d/elbv2-listener-pqc-tls-enabled.added.md b/prowler/changelog.d/elbv2-listener-pqc-tls-enabled.added.md
new file mode 100644
index 0000000000..044d0bb0f4
--- /dev/null
+++ b/prowler/changelog.d/elbv2-listener-pqc-tls-enabled.added.md
@@ -0,0 +1 @@
+`elbv2_listener_pqc_tls_enabled` check for AWS provider, verifying that ELBv2 listeners use post-quantum TLS policies
diff --git a/prowler/compliance/aws/aws_well_architected_framework_security_pillar_aws.json b/prowler/compliance/aws/aws_well_architected_framework_security_pillar_aws.json
index a025bb3a3c..9dd009afb3 100644
--- a/prowler/compliance/aws/aws_well_architected_framework_security_pillar_aws.json
+++ b/prowler/compliance/aws/aws_well_architected_framework_security_pillar_aws.json
@@ -1181,6 +1181,7 @@
"elb_insecure_ssl_ciphers",
"elb_ssl_listeners",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/ccc_aws.json b/prowler/compliance/aws/ccc_aws.json
index 7935424193..ef31bfe1ea 100644
--- a/prowler/compliance/aws/ccc_aws.json
+++ b/prowler/compliance/aws/ccc_aws.json
@@ -49,6 +49,7 @@
"elb_insecure_ssl_ciphers",
"elb_ssl_listeners",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/ens_rd2022_aws.json b/prowler/compliance/aws/ens_rd2022_aws.json
index 144437ce52..f81b8a3eea 100644
--- a/prowler/compliance/aws/ens_rd2022_aws.json
+++ b/prowler/compliance/aws/ens_rd2022_aws.json
@@ -2495,6 +2495,7 @@
],
"Checks": [
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled"
@@ -2521,6 +2522,7 @@
],
"Checks": [
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled"
diff --git a/prowler/compliance/aws/fedramp_moderate_revision_4_aws.json b/prowler/compliance/aws/fedramp_moderate_revision_4_aws.json
index eaa3ea25dc..13c4624572 100644
--- a/prowler/compliance/aws/fedramp_moderate_revision_4_aws.json
+++ b/prowler/compliance/aws/fedramp_moderate_revision_4_aws.json
@@ -1377,6 +1377,7 @@
"Checks": [
"apigateway_restapi_client_certificate_enabled",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
@@ -1399,6 +1400,7 @@
"Checks": [
"apigateway_restapi_client_certificate_enabled",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/ffiec_aws.json b/prowler/compliance/aws/ffiec_aws.json
index 8a50b79925..4a2a1b943e 100644
--- a/prowler/compliance/aws/ffiec_aws.json
+++ b/prowler/compliance/aws/ffiec_aws.json
@@ -615,6 +615,7 @@
"Checks": [
"apigateway_restapi_client_certificate_enabled",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/gxp_21_cfr_part_11_aws.json b/prowler/compliance/aws/gxp_21_cfr_part_11_aws.json
index 871af9e726..76ad0c74a5 100644
--- a/prowler/compliance/aws/gxp_21_cfr_part_11_aws.json
+++ b/prowler/compliance/aws/gxp_21_cfr_part_11_aws.json
@@ -266,6 +266,7 @@
"ec2_ebs_default_encryption",
"efs_encryption_at_rest_enabled",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/iso27001_2013_aws.json b/prowler/compliance/aws/iso27001_2013_aws.json
index 1de8c23db8..c7ce030024 100644
--- a/prowler/compliance/aws/iso27001_2013_aws.json
+++ b/prowler/compliance/aws/iso27001_2013_aws.json
@@ -36,6 +36,7 @@
"Checks": [
"elb_insecure_ssl_ciphers",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled"
diff --git a/prowler/compliance/aws/kisa_isms_p_2023_aws.json b/prowler/compliance/aws/kisa_isms_p_2023_aws.json
index 7b0446ac3f..65a6e8c8b8 100644
--- a/prowler/compliance/aws/kisa_isms_p_2023_aws.json
+++ b/prowler/compliance/aws/kisa_isms_p_2023_aws.json
@@ -2064,6 +2064,7 @@
"elb_ssl_listeners",
"elb_ssl_listeners_use_acm_certificate",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
@@ -3142,6 +3143,7 @@
"elb_ssl_listeners_use_acm_certificate",
"elbv2_desync_mitigation_mode",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/kisa_isms_p_2023_korean_aws.json b/prowler/compliance/aws/kisa_isms_p_2023_korean_aws.json
index 40b338ce41..b99a36d38e 100644
--- a/prowler/compliance/aws/kisa_isms_p_2023_korean_aws.json
+++ b/prowler/compliance/aws/kisa_isms_p_2023_korean_aws.json
@@ -2066,6 +2066,7 @@
"elb_ssl_listeners",
"elb_ssl_listeners_use_acm_certificate",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
@@ -3145,6 +3146,7 @@
"elb_ssl_listeners_use_acm_certificate",
"elbv2_desync_mitigation_mode",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/nist_800_171_revision_2_aws.json b/prowler/compliance/aws/nist_800_171_revision_2_aws.json
index 921bd33a53..31c45c6ae3 100644
--- a/prowler/compliance/aws/nist_800_171_revision_2_aws.json
+++ b/prowler/compliance/aws/nist_800_171_revision_2_aws.json
@@ -717,6 +717,7 @@
"apigateway_restapi_client_certificate_enabled",
"ec2_ebs_volume_encryption",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/nist_800_53_revision_5_aws.json b/prowler/compliance/aws/nist_800_53_revision_5_aws.json
index e0ef936229..70864860bf 100644
--- a/prowler/compliance/aws/nist_800_53_revision_5_aws.json
+++ b/prowler/compliance/aws/nist_800_53_revision_5_aws.json
@@ -5592,6 +5592,7 @@
"Checks": [
"apigateway_restapi_client_certificate_enabled",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/rbi_cyber_security_framework_aws.json b/prowler/compliance/aws/rbi_cyber_security_framework_aws.json
index 5de1f5ca8a..554b40cdad 100644
--- a/prowler/compliance/aws/rbi_cyber_security_framework_aws.json
+++ b/prowler/compliance/aws/rbi_cyber_security_framework_aws.json
@@ -40,6 +40,7 @@
"ec2_instance_public_ip",
"efs_encryption_at_rest_enabled",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/compliance/aws/secnumcloud_3.2_aws.json b/prowler/compliance/aws/secnumcloud_3.2_aws.json
index 701f931b05..8075dc3610 100644
--- a/prowler/compliance/aws/secnumcloud_3.2_aws.json
+++ b/prowler/compliance/aws/secnumcloud_3.2_aws.json
@@ -490,6 +490,7 @@
"elbv2_ssl_listeners",
"elb_insecure_ssl_ciphers",
"elbv2_insecure_ssl_ciphers",
+ "elbv2_listener_pqc_tls_enabled",
"cloudfront_distributions_pqc_tls_enabled",
"apigateway_domain_name_pqc_tls_enabled",
"transfer_server_pqc_ssh_kex_enabled",
diff --git a/prowler/config/config.yaml b/prowler/config/config.yaml
index 6d2803be56..aba7fd6481 100644
--- a/prowler/config/config.yaml
+++ b/prowler/config/config.yaml
@@ -424,6 +424,21 @@ aws:
- "SecurityPolicy_TLS13_1_2_PFS_PQ_2025_09"
- "SecurityPolicy_TLS13_1_2_PQ_2025_09"
+ # aws.elbv2_listener_pqc_tls_enabled
+ # Allowed post-quantum TLS security policies for ELBv2 HTTPS/TLS listeners
+ elbv2_listener_pqc_tls_allowed_policies:
+ - "ELBSecurityPolicy-TLS13-1-2-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext1-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext2-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-3-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext0-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext1-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext2-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Res-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09"
+
# aws.rolesanywhere_trust_anchor_pqc_pki
# Allowed post-quantum key algorithms for AWS Private CAs backing IAM Roles Anywhere trust anchors
rolesanywhere_pqc_pca_key_algorithms:
diff --git a/prowler/config/schema/aws.py b/prowler/config/schema/aws.py
index 4e52093029..7ac12d60de 100644
--- a/prowler/config/schema/aws.py
+++ b/prowler/config/schema/aws.py
@@ -415,6 +415,10 @@ class AWSProviderConfig(ProviderConfigBase):
le=6,
description="Min AZs an Application/Network LB must span. Range: 1..6.",
)
+ elbv2_listener_pqc_tls_allowed_policies: Optional[list[str]] = Field(
+ default=None,
+ description="ELBv2 SSL policies that satisfy the PQ TLS listener check.",
+ )
# --- ElastiCache -----------------------------------------------------
minimum_snapshot_retention_period: Optional[int] = Field(
diff --git a/prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/__init__.py b/prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled.metadata.json b/prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled.metadata.json
new file mode 100644
index 0000000000..d86778d5ae
--- /dev/null
+++ b/prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled.metadata.json
@@ -0,0 +1,42 @@
+{
+ "Provider": "aws",
+ "CheckID": "elbv2_listener_pqc_tls_enabled",
+ "CheckTitle": "ELBv2 HTTPS/TLS listeners use a post-quantum TLS security policy",
+ "CheckType": [
+ "Software and Configuration Checks/AWS Security Best Practices"
+ ],
+ "ServiceName": "elbv2",
+ "SubServiceName": "",
+ "ResourceIdTemplate": "",
+ "Severity": "low",
+ "ResourceType": "AwsElbv2LoadBalancer",
+ "ResourceGroup": "network",
+ "Description": "**ELBv2 HTTPS and TLS listeners** are assessed for use of **post-quantum (PQ) TLS security policies**. Listeners whose `SslPolicy` is not in the approved PQ set lack hybrid key exchange (ML-KEM 768 + ECDHE), which can increase harvest-now-decrypt-later exposure for recorded traffic.",
+ "Risk": "Without PQ-ready TLS policies, encrypted traffic captured today may be stored for future cryptanalysis if a **cryptographically relevant quantum computer** becomes available (**harvest-now, decrypt-later** attack). PQ-ready TLS policies reduce this long-term confidentiality risk for sensitive data, credentials, and session tokens transmitted through the load balancer.",
+ "RelatedUrl": "",
+ "AdditionalURLs": [
+ "https://docs.aws.amazon.com/elasticloadbalancing/latest/application/describe-ssl-policies.html",
+ "https://aws.amazon.com/security/post-quantum-cryptography/",
+ "https://csrc.nist.gov/projects/post-quantum-cryptography"
+ ],
+ "Remediation": {
+ "Code": {
+ "CLI": "aws elbv2 modify-listener --listener-arn --ssl-policy ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ "NativeIaC": "```yaml\nResources:\n :\n Type: AWS::ElasticLoadBalancingV2::Listener\n Properties:\n LoadBalancerArn: \n Protocol: HTTPS\n Port: 443\n DefaultActions:\n - Type: forward\n TargetGroupArn: \n Certificates:\n - CertificateArn: \n SslPolicy: ELBSecurityPolicy-TLS13-1-2-PQ-2025-09 # FIX: uses a post-quantum TLS policy\n```",
+ "Other": "1. In the AWS Console, go to EC2 > Load Balancers\n2. Select the load balancer and open the Listeners tab\n3. Select the HTTPS/TLS listener and choose Edit\n4. Set Security policy to ELBSecurityPolicy-TLS13-1-2-PQ-2025-09 (or any approved PQ policy)\n5. Save changes",
+ "Terraform": "```hcl\nresource \"aws_lb_listener\" \"\" {\n load_balancer_arn = \"\"\n port = 443\n protocol = \"HTTPS\"\n ssl_policy = \"ELBSecurityPolicy-TLS13-1-2-PQ-2025-09\" # FIX: post-quantum TLS policy\n certificate_arn = \"\"\n\n default_action {\n type = \"forward\"\n target_group_arn = \"\"\n }\n}\n```"
+ },
+ "Recommendation": {
+ "Text": "Migrate all ELBv2 HTTPS and TLS listeners to a **post-quantum TLS policy** (`ELBSecurityPolicy-TLS13-*-PQ-2025-09` family) to enable hybrid key exchange (ML-KEM + ECDHE). Periodically review and update policies as AWS publishes new PQ-ready options.",
+ "Url": "https://hub.prowler.com/check/elbv2_listener_pqc_tls_enabled"
+ }
+ },
+ "Categories": [
+ "encryption"
+ ],
+ "DependsOn": [],
+ "RelatedTo": [
+ "elbv2_insecure_ssl_ciphers"
+ ],
+ "Notes": ""
+}
diff --git a/prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled.py b/prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled.py
new file mode 100644
index 0000000000..270a2cc31b
--- /dev/null
+++ b/prowler/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled.py
@@ -0,0 +1,73 @@
+"""Check that ELBv2 HTTPS/TLS listeners use post-quantum TLS policies."""
+
+from prowler.lib.check.models import Check, Check_Report_AWS
+from prowler.providers.aws.services.elbv2.elbv2_client import elbv2_client
+
+PQ_TLS_POLICIES_DEFAULT = [
+ "ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext1-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext2-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-3-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext0-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext1-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext2-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Res-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09",
+]
+
+
+class elbv2_listener_pqc_tls_enabled(Check):
+ """Verify that every ELBv2 HTTPS or TLS listener uses a post-quantum TLS policy.
+
+ This check evaluates whether each HTTPS (ALB) or TLS (NLB) listener on an
+ ELBv2 load balancer terminates TLS with a security policy that offers
+ post-quantum (PQ) hybrid key exchange (ML-KEM 768 combined with ECDHE).
+ - PASS: All HTTPS/TLS listeners on the load balancer use a PQ TLS policy.
+ - FAIL: At least one HTTPS/TLS listener uses a non-PQ TLS policy.
+ """
+
+ def execute(self) -> list[Check_Report_AWS]:
+ """Execute the PQ TLS policy check for every ELBv2 load balancer.
+
+ Returns:
+ A list of reports for load balancers with discovered listeners.
+ """
+ findings = []
+ pq_tls_policies = elbv2_client.audit_config.get(
+ "elbv2_listener_pqc_tls_allowed_policies", PQ_TLS_POLICIES_DEFAULT
+ )
+ for lb in elbv2_client.loadbalancersv2.values():
+ report = Check_Report_AWS(metadata=self.metadata(), resource=lb)
+
+ if lb.listener_discovery_failed:
+ continue
+
+ has_tls_listeners = False
+ non_pq_listeners = []
+ for listener_arn, listener in lb.listeners.items():
+ if listener.protocol in ("HTTPS", "TLS"):
+ has_tls_listeners = True
+ if listener.ssl_policy not in pq_tls_policies:
+ ssl_policy = listener.ssl_policy or ""
+ non_pq_listeners.append(
+ f"{listener.protocol}:{listener.port} ({listener_arn}) uses {ssl_policy}"
+ )
+
+ if not has_tls_listeners:
+ report.status = "PASS"
+ report.status_extended = f"ELBv2 {lb.name} has no HTTPS/TLS listeners."
+ findings.append(report)
+ continue
+
+ if non_pq_listeners:
+ report.status = "FAIL"
+ report.status_extended = f"ELBv2 {lb.name} has HTTPS/TLS listeners without post-quantum TLS policy: {', '.join(non_pq_listeners)}."
+ else:
+ report.status = "PASS"
+ report.status_extended = f"ELBv2 {lb.name} has all HTTPS/TLS listeners using a post-quantum TLS policy."
+
+ findings.append(report)
+
+ return findings
diff --git a/prowler/providers/aws/services/elbv2/elbv2_service.py b/prowler/providers/aws/services/elbv2/elbv2_service.py
index c52110869f..e2d9bd3682 100644
--- a/prowler/providers/aws/services/elbv2/elbv2_service.py
+++ b/prowler/providers/aws/services/elbv2/elbv2_service.py
@@ -86,10 +86,14 @@ class ELBv2(AWSService):
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
else:
+ load_balancer[1].listener_discovery_failed = True
+ load_balancer[1].listener_discovery_error = str(error)
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
+ load_balancer[1].listener_discovery_failed = True
+ load_balancer[1].listener_discovery_error = str(error)
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
@@ -209,6 +213,8 @@ class LoadBalancerv2(BaseModel):
drop_invalid_header_fields: Optional[str]
cross_zone_load_balancing: Optional[str]
listeners: Dict[str, Listenerv2] = {}
+ listener_discovery_failed: bool = False
+ listener_discovery_error: Optional[str] = None
scheme: Optional[str]
security_groups: list[str] = []
# Key: ZoneName, Value: SubnetId
diff --git a/tests/config/config_test.py b/tests/config/config_test.py
index 365efbc0c9..d10c384b0d 100644
--- a/tests/config/config_test.py
+++ b/tests/config/config_test.py
@@ -320,6 +320,19 @@ config_aws = {
"minimum_snapshot_retention_period": 7,
"elb_min_azs": 2,
"elbv2_min_azs": 2,
+ "elbv2_listener_pqc_tls_allowed_policies": [
+ "ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext1-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext2-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-3-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext0-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext1-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext2-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Res-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09",
+ ],
"secrets_ignore_patterns": [],
"max_days_secret_unused": 90,
"max_days_secret_unrotated": 90,
diff --git a/tests/config/fixtures/config.yaml b/tests/config/fixtures/config.yaml
index 39cba5f27d..df663e923a 100644
--- a/tests/config/fixtures/config.yaml
+++ b/tests/config/fixtures/config.yaml
@@ -362,6 +362,21 @@ aws:
# Minimum number of Availability Zones that an ELBv2 must be in
elbv2_min_azs: 2
+ # aws.elbv2_listener_pqc_tls_enabled
+ # Allowed post-quantum TLS security policies for ELBv2 HTTPS/TLS listeners
+ elbv2_listener_pqc_tls_allowed_policies:
+ - "ELBSecurityPolicy-TLS13-1-2-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext1-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext2-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-3-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext0-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext1-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Ext2-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-2-Res-FIPS-PQ-2025-09"
+ - "ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09"
+
# AWS Elasticache Configuration
# aws.elasticache_redis_cluster_backup_enabled
# Minimum number of days that a Redis cluster must have backups retention period
diff --git a/tests/config/schema/aws_schema_test.py b/tests/config/schema/aws_schema_test.py
index d37a2e0bf6..838853f52a 100644
--- a/tests/config/schema/aws_schema_test.py
+++ b/tests/config/schema/aws_schema_test.py
@@ -176,6 +176,33 @@ class Test_AWS_Enums:
assert _validate({"ecr_repository_vulnerability_minimum_severity": level}) == {}
+class TestAWSELBv2PQCTLSAllowedPolicies:
+ def test_valid_policy_list_round_trips(self):
+ policies = [
+ "ELBSecurityPolicy-TLS13-1-2-Res-2021-06",
+ "ELBSecurityPolicy-TLS13-1-3-2021-06",
+ ]
+
+ assert _validate({"elbv2_listener_pqc_tls_allowed_policies": policies}) == {
+ "elbv2_listener_pqc_tls_allowed_policies": policies
+ }
+
+ def test_key_is_exposed_in_scan_config_schema(self):
+ aws_properties = SCAN_CONFIG_SCHEMA["properties"]["aws"]["properties"]
+
+ assert "elbv2_listener_pqc_tls_allowed_policies" in aws_properties
+
+ @pytest.mark.parametrize(
+ "value",
+ [
+ "ELBSecurityPolicy-TLS13-1-2-Res-2021-06",
+ ["ELBSecurityPolicy-TLS13-1-2-Res-2021-06", 123],
+ ],
+ )
+ def test_invalid_policy_values_are_dropped(self, value):
+ assert _validate({"elbv2_listener_pqc_tls_allowed_policies": value}) == {}
+
+
class Test_AWS_Secrets_Ignore_Files:
def test_valid_file_patterns_round_trip(self):
files = ["*.deps.json", "vendor/*.js"]
diff --git a/tests/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled_test.py b/tests/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled_test.py
new file mode 100644
index 0000000000..12f4d5a4dd
--- /dev/null
+++ b/tests/providers/aws/services/elbv2/elbv2_listener_pqc_tls_enabled/elbv2_listener_pqc_tls_enabled_test.py
@@ -0,0 +1,673 @@
+"""Tests for elbv2_listener_pqc_tls_enabled check."""
+
+from unittest import mock
+
+import pytest
+from boto3 import client, resource
+from botocore.exceptions import ClientError
+from moto import mock_aws
+
+from tests.providers.aws.utils import (
+ AWS_REGION_EU_WEST_1,
+ AWS_REGION_EU_WEST_1_AZA,
+ AWS_REGION_EU_WEST_1_AZB,
+ AWS_REGION_US_EAST_1,
+ set_mocked_aws_provider,
+)
+
+
+class Test_elbv2_listener_pqc_tls_enabled:
+ """Test cases for the elbv2_listener_pqc_tls_enabled check."""
+
+ def _create_alb_infrastructure(self, region=AWS_REGION_EU_WEST_1):
+ """Helper to create VPC, subnets, security group, target group, and ALB.
+
+ Returns a tuple of (elbv2_client, lb_response, target_group_arn).
+ """
+ conn = client("elbv2", region_name=region)
+ ec2 = resource("ec2", region_name=region)
+
+ security_group = ec2.create_security_group(
+ GroupName="a-security-group", Description="First One"
+ )
+ vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
+ subnet1 = ec2.create_subnet(
+ VpcId=vpc.id,
+ CidrBlock="172.28.7.192/26",
+ AvailabilityZone=f"{region}a",
+ )
+ subnet2 = ec2.create_subnet(
+ VpcId=vpc.id,
+ CidrBlock="172.28.7.0/26",
+ AvailabilityZone=f"{region}b",
+ )
+
+ lb = conn.create_load_balancer(
+ Name="my-lb",
+ Subnets=[subnet1.id, subnet2.id],
+ SecurityGroups=[security_group.id],
+ Scheme="internal",
+ Type="application",
+ )["LoadBalancers"][0]
+
+ response = conn.create_target_group(
+ Name="a-target",
+ Protocol="HTTP",
+ Port=8080,
+ VpcId=vpc.id,
+ HealthCheckProtocol="HTTP",
+ HealthCheckPort="8080",
+ HealthCheckPath="/",
+ HealthCheckIntervalSeconds=5,
+ HealthCheckTimeoutSeconds=3,
+ HealthyThresholdCount=5,
+ UnhealthyThresholdCount=2,
+ Matcher={"HttpCode": "200"},
+ )
+ target_group_arn = response["TargetGroups"][0]["TargetGroupArn"]
+
+ return conn, lb, target_group_arn
+
+ def _create_nlb_infrastructure(self, region=AWS_REGION_EU_WEST_1):
+ """Helper to create VPC, subnets, target group, and NLB.
+
+ Returns a tuple of (elbv2_client, lb_response, target_group_arn).
+ """
+ conn = client("elbv2", region_name=region)
+ ec2 = resource("ec2", region_name=region)
+
+ vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
+ subnet1 = ec2.create_subnet(
+ VpcId=vpc.id,
+ CidrBlock="172.28.7.192/26",
+ AvailabilityZone=AWS_REGION_EU_WEST_1_AZA,
+ )
+ subnet2 = ec2.create_subnet(
+ VpcId=vpc.id,
+ CidrBlock="172.28.7.0/26",
+ AvailabilityZone=AWS_REGION_EU_WEST_1_AZB,
+ )
+
+ lb = conn.create_load_balancer(
+ Name="my-nlb",
+ Subnets=[subnet1.id, subnet2.id],
+ Scheme="internal",
+ Type="network",
+ )["LoadBalancers"][0]
+
+ response = conn.create_target_group(
+ Name="a-target",
+ Protocol="TCP",
+ Port=8080,
+ VpcId=vpc.id,
+ )
+ target_group_arn = response["TargetGroups"][0]["TargetGroupArn"]
+
+ return conn, lb, target_group_arn
+
+ def _mock_and_execute(self, audit_config=None):
+ """Helper to set up mocks and execute the check.
+
+ Must be called inside a @mock_aws decorated method, after AWS
+ resources have been created with moto.
+ """
+ from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2
+
+ audit_config = audit_config or {}
+ aws_provider = set_mocked_aws_provider(
+ [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1],
+ create_default_organization=False,
+ audit_config=audit_config,
+ )
+
+ with (
+ mock.patch(
+ "prowler.providers.common.provider.Provider.get_global_provider",
+ return_value=set_mocked_aws_provider(
+ [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1],
+ audit_config=audit_config,
+ ),
+ ),
+ mock.patch(
+ "prowler.providers.aws.services.elbv2.elbv2_listener_pqc_tls_enabled.elbv2_listener_pqc_tls_enabled.elbv2_client",
+ new=ELBv2(aws_provider),
+ ),
+ ):
+ from prowler.providers.aws.services.elbv2.elbv2_listener_pqc_tls_enabled.elbv2_listener_pqc_tls_enabled import (
+ elbv2_listener_pqc_tls_enabled,
+ )
+
+ check = elbv2_listener_pqc_tls_enabled()
+ return check.execute()
+
+ def _assert_listener_arn_in_status(self, result, listener_arn):
+ """Assert that remediation details identify the affected listener ARN."""
+ assert listener_arn in result[0].status_extended
+
+ # ------------------------------------------------------------------
+ # No-resource scenarios
+ # ------------------------------------------------------------------
+
+ @mock_aws
+ def test_no_load_balancers(self):
+ """Test that no findings are returned when there are no load balancers."""
+ result = self._mock_and_execute()
+ assert len(result) == 0
+
+ @mock_aws
+ def test_lb_with_http_listener_only(self):
+ """Test PASS when a load balancer has no HTTPS/TLS listeners."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTP",
+ Port=80,
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert result[0].status_extended == "ELBv2 my-lb has no HTTPS/TLS listeners."
+ assert result[0].resource_id == "my-lb"
+
+ # ------------------------------------------------------------------
+ # PASS scenarios
+ # ------------------------------------------------------------------
+
+ @pytest.mark.parametrize(
+ "ssl_policy",
+ [
+ "ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext1-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext2-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-3-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext0-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext1-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Ext2-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-2-Res-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09",
+ ],
+ )
+ @mock_aws
+ def test_listener_with_pq_policy_pass(self, ssl_policy):
+ """Test PASS when HTTPS listener uses an allowed PQ TLS policy."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy=ssl_policy,
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert (
+ result[0].status_extended
+ == "ELBv2 my-lb has all HTTPS/TLS listeners using a post-quantum TLS policy."
+ )
+ assert result[0].resource_id == "my-lb"
+ assert result[0].resource_arn == lb["LoadBalancerArn"]
+ assert result[0].region == AWS_REGION_EU_WEST_1
+
+ @mock_aws
+ def test_multiple_https_listeners_all_pq_pass(self):
+ """Test PASS when a LB has multiple HTTPS listeners all using PQ policies."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=8443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert (
+ result[0].status_extended
+ == "ELBv2 my-lb has all HTTPS/TLS listeners using a post-quantum TLS policy."
+ )
+ assert result[0].resource_id == "my-lb"
+
+ @mock_aws
+ def test_mixed_http_and_pq_https_listeners_pass(self):
+ """Test PASS when LB has both HTTP and HTTPS listeners, HTTPS using PQ policy."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ # HTTP listener (out of scope)
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTP",
+ Port=80,
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+ # HTTPS listener with PQ policy
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert result[0].resource_id == "my-lb"
+
+ # ------------------------------------------------------------------
+ # FAIL scenarios
+ # ------------------------------------------------------------------
+
+ @mock_aws
+ def test_listener_with_classical_tls_policy_fail(self):
+ """Test FAIL when HTTPS listener uses a classical (non-PQ) TLS policy."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ listener = conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )["Listeners"][0]
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert (
+ result[0].status_extended
+ == f"ELBv2 my-lb has HTTPS/TLS listeners without post-quantum TLS policy: HTTPS:443 ({listener['ListenerArn']}) uses ELBSecurityPolicy-TLS13-1-2-2021-06."
+ )
+ self._assert_listener_arn_in_status(result, listener["ListenerArn"])
+ assert result[0].resource_id == "my-lb"
+ assert result[0].resource_arn == lb["LoadBalancerArn"]
+ assert result[0].region == AWS_REGION_EU_WEST_1
+
+ @mock_aws
+ def test_listener_with_tls_1_0_pq_policy_fails_by_default(self):
+ """Test FAIL when HTTPS listener uses a TLS 1.0-minimum PQ policy by default."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ listener = conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-0-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )["Listeners"][0]
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert (
+ result[0].status_extended
+ == f"ELBv2 my-lb has HTTPS/TLS listeners without post-quantum TLS policy: HTTPS:443 ({listener['ListenerArn']}) uses ELBSecurityPolicy-TLS13-1-0-PQ-2025-09."
+ )
+ assert result[0].resource_id == "my-lb"
+
+ @mock_aws
+ def test_listener_with_empty_ssl_policy_fail(self):
+ """Test FAIL when an HTTPS listener has no SSL policy value."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ listener = conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )["Listeners"][0]
+
+ from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2
+
+ aws_provider = set_mocked_aws_provider(
+ [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1],
+ create_default_organization=False,
+ )
+ service = ELBv2(aws_provider)
+ service.loadbalancersv2[lb["LoadBalancerArn"]].listeners[
+ listener["ListenerArn"]
+ ].ssl_policy = ""
+
+ with (
+ mock.patch(
+ "prowler.providers.common.provider.Provider.get_global_provider",
+ return_value=aws_provider,
+ ),
+ mock.patch(
+ "prowler.providers.aws.services.elbv2.elbv2_listener_pqc_tls_enabled.elbv2_listener_pqc_tls_enabled.elbv2_client",
+ new=service,
+ ),
+ ):
+ from prowler.providers.aws.services.elbv2.elbv2_listener_pqc_tls_enabled.elbv2_listener_pqc_tls_enabled import (
+ elbv2_listener_pqc_tls_enabled,
+ )
+
+ result = elbv2_listener_pqc_tls_enabled().execute()
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert (
+ result[0].status_extended
+ == f"ELBv2 my-lb has HTTPS/TLS listeners without post-quantum TLS policy: HTTPS:443 ({listener['ListenerArn']}) uses ."
+ )
+ assert result[0].resource_id == "my-lb"
+
+ @mock_aws
+ def test_listener_with_legacy_policy_fail(self):
+ """Test FAIL when HTTPS listener uses a legacy TLS policy."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ listener = conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS-1-1-2017-01",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )["Listeners"][0]
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert (
+ result[0].status_extended
+ == f"ELBv2 my-lb has HTTPS/TLS listeners without post-quantum TLS policy: HTTPS:443 ({listener['ListenerArn']}) uses ELBSecurityPolicy-TLS-1-1-2017-01."
+ )
+ self._assert_listener_arn_in_status(result, listener["ListenerArn"])
+ assert result[0].resource_id == "my-lb"
+ assert result[0].resource_arn == lb["LoadBalancerArn"]
+
+ @mock_aws
+ def test_mixed_pq_and_non_pq_listeners_fail(self):
+ """Test FAIL when LB has one PQ listener and one non-PQ listener."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ # PQ listener
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+ # Non-PQ listener
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=8443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert "ELBSecurityPolicy-TLS13-1-2-2021-06" in result[0].status_extended
+ assert result[0].resource_id == "my-lb"
+
+ @mock_aws
+ def test_multiple_non_pq_listeners_lists_all_policies_fail(self):
+ """Test FAIL lists all non-PQ policies when multiple listeners are non-compliant."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS-1-1-2017-01",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=8443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ # Both non-PQ policies should be mentioned
+ assert "ELBSecurityPolicy-TLS-1-1-2017-01" in result[0].status_extended
+ assert "ELBSecurityPolicy-TLS13-1-2-2021-06" in result[0].status_extended
+ assert result[0].resource_id == "my-lb"
+
+ # ------------------------------------------------------------------
+ # Custom audit_config scenario
+ # ------------------------------------------------------------------
+
+ @mock_aws
+ def test_custom_audit_config_narrows_allowlist(self):
+ """Test that a custom audit_config allowlist is honoured.
+
+ When elbv2_listener_pqc_tls_allowed_policies is overridden to only
+ allow FIPS PQ policies, a non-FIPS PQ policy should FAIL.
+ """
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ # Use a PQ policy that is in the default list but NOT in our custom list
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ custom_config = {
+ "elbv2_listener_pqc_tls_allowed_policies": [
+ "ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09",
+ ]
+ }
+
+ result = self._mock_and_execute(audit_config=custom_config)
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert "ELBSecurityPolicy-TLS13-1-2-PQ-2025-09" in result[0].status_extended
+
+ @mock_aws
+ def test_custom_audit_config_fips_policy_pass(self):
+ """Test PASS when listener uses a FIPS PQ policy and custom config allows it."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ custom_config = {
+ "elbv2_listener_pqc_tls_allowed_policies": [
+ "ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09",
+ "ELBSecurityPolicy-TLS13-1-3-FIPS-PQ-2025-09",
+ ]
+ }
+
+ result = self._mock_and_execute(audit_config=custom_config)
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert (
+ result[0].status_extended
+ == "ELBv2 my-lb has all HTTPS/TLS listeners using a post-quantum TLS policy."
+ )
+
+ @mock_aws
+ def test_custom_audit_config_allows_tls_1_0_pq_policy(self):
+ """Test PASS when custom config explicitly allows a TLS 1.0-minimum PQ policy."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-0-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute(
+ audit_config={
+ "elbv2_listener_pqc_tls_allowed_policies": [
+ "ELBSecurityPolicy-TLS13-1-0-PQ-2025-09"
+ ]
+ }
+ )
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert (
+ result[0].status_extended
+ == "ELBv2 my-lb has all HTTPS/TLS listeners using a post-quantum TLS policy."
+ )
+
+ @mock_aws
+ def test_empty_audit_config_allowlist_fails_tls_listener(self):
+ """Test an intentionally empty allowlist is honoured."""
+ conn, lb, target_group_arn = self._create_alb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="HTTPS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute(
+ audit_config={"elbv2_listener_pqc_tls_allowed_policies": []}
+ )
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert result[0].resource_id == "my-lb"
+ assert "ELBSecurityPolicy-TLS13-1-2-PQ-2025-09" in result[0].status_extended
+
+ @mock_aws
+ def test_tls_listener_with_pq_policy_pass(self):
+ """Test PASS when a TLS listener uses an allowed PQ TLS policy."""
+ conn, lb, target_group_arn = self._create_nlb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="TLS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-PQ-2025-09",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert result[0].resource_id == "my-nlb"
+ assert result[0].resource_arn == lb["LoadBalancerArn"]
+
+ @mock_aws
+ def test_nlb_with_tcp_listener_only(self):
+ """Test PASS when an NLB has no HTTPS/TLS listeners."""
+ conn, lb, target_group_arn = self._create_nlb_infrastructure()
+ conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="TCP",
+ Port=80,
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "PASS"
+ assert result[0].status_extended == "ELBv2 my-nlb has no HTTPS/TLS listeners."
+ assert result[0].resource_id == "my-nlb"
+ assert result[0].resource_arn == lb["LoadBalancerArn"]
+
+ @mock_aws
+ def test_tls_listener_with_non_pq_policy_fail(self):
+ """Test FAIL when a TLS listener uses a non-PQ TLS policy."""
+ conn, lb, target_group_arn = self._create_nlb_infrastructure()
+ listener = conn.create_listener(
+ LoadBalancerArn=lb["LoadBalancerArn"],
+ Protocol="TLS",
+ Port=443,
+ SslPolicy="ELBSecurityPolicy-TLS13-1-2-2021-06",
+ DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
+ )["Listeners"][0]
+
+ result = self._mock_and_execute()
+
+ assert len(result) == 1
+ assert result[0].status == "FAIL"
+ assert (
+ result[0].status_extended
+ == f"ELBv2 my-nlb has HTTPS/TLS listeners without post-quantum TLS policy: TLS:443 ({listener['ListenerArn']}) uses ELBSecurityPolicy-TLS13-1-2-2021-06."
+ )
+ self._assert_listener_arn_in_status(result, listener["ListenerArn"])
+ assert result[0].resource_id == "my-nlb"
+ assert result[0].resource_arn == lb["LoadBalancerArn"]
+
+ @mock_aws
+ def test_listener_discovery_failure_returns_no_findings(self):
+ """Test no findings when listeners cannot be retrieved for a load balancer."""
+ conn, lb, _ = self._create_alb_infrastructure()
+
+ from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2
+
+ aws_provider = set_mocked_aws_provider(
+ [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1],
+ create_default_organization=False,
+ )
+
+ service = ELBv2(aws_provider)
+ error = ClientError(
+ {
+ "Error": {
+ "Code": "AccessDenied",
+ "Message": "User is not authorized to perform: elasticloadbalancing:DescribeListeners",
+ }
+ },
+ "DescribeListeners",
+ )
+ service.loadbalancersv2[lb["LoadBalancerArn"]].listeners = {}
+ service.regional_clients[AWS_REGION_EU_WEST_1] = mock.MagicMock(
+ region=AWS_REGION_EU_WEST_1,
+ get_paginator=mock.MagicMock(side_effect=error),
+ )
+ service._describe_listeners(
+ (lb["LoadBalancerArn"], service.loadbalancersv2[lb["LoadBalancerArn"]])
+ )
+
+ assert service.loadbalancersv2[lb["LoadBalancerArn"]].listener_discovery_failed
+
+ with (
+ mock.patch(
+ "prowler.providers.common.provider.Provider.get_global_provider",
+ return_value=aws_provider,
+ ),
+ mock.patch(
+ "prowler.providers.aws.services.elbv2.elbv2_listener_pqc_tls_enabled.elbv2_listener_pqc_tls_enabled.elbv2_client",
+ new=service,
+ ),
+ ):
+ from prowler.providers.aws.services.elbv2.elbv2_listener_pqc_tls_enabled.elbv2_listener_pqc_tls_enabled import (
+ elbv2_listener_pqc_tls_enabled,
+ )
+
+ result = elbv2_listener_pqc_tls_enabled().execute()
+
+ assert len(result) == 0
From 60c4e9b257465392a2d23ac042f514c712224954 Mon Sep 17 00:00:00 2001
From: Pepe Fagoaga
Date: Wed, 15 Jul 2026 13:45:45 +0200
Subject: [PATCH 22/22] docs(compliance): unify section pages (#11993)
---
docs/docs.json | 11 +++--------
docs/style.css | 3 +--
docs/user-guide/compliance/tutorials/compliance.mdx | 7 ++++---
.../tutorials/cross-provider-compliance.mdx | 2 +-
docs/user-guide/compliance/tutorials/threatscore.mdx | 2 +-
5 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/docs/docs.json b/docs/docs.json
index 211cb9c4d3..d9ac4c2bd8 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -139,7 +139,9 @@
{
"group": "Compliance",
"pages": [
- "user-guide/compliance/tutorials/cross-provider-compliance"
+ "user-guide/compliance/tutorials/compliance",
+ "user-guide/compliance/tutorials/cross-provider-compliance",
+ "user-guide/compliance/tutorials/threatscore"
]
},
{
@@ -425,13 +427,6 @@
}
]
},
- {
- "group": "Compliance",
- "pages": [
- "user-guide/compliance/tutorials/compliance",
- "user-guide/compliance/tutorials/threatscore"
- ]
- },
{
"group": "Cookbooks",
"pages": [
diff --git a/docs/style.css b/docs/style.css
index 9585e7cdeb..9a1ed19a0f 100644
--- a/docs/style.css
+++ b/docs/style.css
@@ -71,7 +71,7 @@
Rendered as a trailing ::after glyph so sidebar labels stay left-aligned.
Nested groups render as li[data-title] with a button toggle; top-level groups
render as h3 headings. Every ungated group that shares a name with a gated one
- (Providers, Compliance, Prowler Cloud, Prowler Lighthouse AI) is top-level,
+ (Providers, Prowler Cloud, Prowler Lighthouse AI) is top-level,
so plain li[data-title] selectors match only the gated nested groups, folded
or unfolded. The Security tab group is top-level (h3) and always expanded,
so it is selected through its sibling list content with :has().
@@ -82,7 +82,6 @@
li[data-title="Prowler Cloud"] > button span:first-child::after,
li[data-title="Prowler Lighthouse AI"] > button span:first-child::after,
li[data-title="Providers"] > button span:first-child::after,
-li[data-title="Compliance"] > button span:first-child::after,
li[data-title="Scans"] > button span:first-child::after,
li[data-title="Prowler MCP"] > button span:first-child::after,
div:has(+ ul a[href="/security/encryption"]) h3 span::after,
diff --git a/docs/user-guide/compliance/tutorials/compliance.mdx b/docs/user-guide/compliance/tutorials/compliance.mdx
index 9ee5df438d..6c13f60529 100644
--- a/docs/user-guide/compliance/tutorials/compliance.mdx
+++ b/docs/user-guide/compliance/tutorials/compliance.mdx
@@ -1,5 +1,6 @@
---
title: 'Compliance'
+sidebarTitle: 'Overview'
description: 'Run security checks against compliance frameworks, review posture across providers, and download CSV or PDF reports from Prowler Cloud and Prowler Local Server, or CSV reports from Prowler CLI.'
---
@@ -8,7 +9,7 @@ Prowler maps every security check to one or more industry-standard compliance fr
Out of the box, Prowler covers frameworks such as CIS Benchmarks, NIST 800-53, NIST CSF, NIS2, ENS RD2022, ISO 27001, PCI-DSS, SOC 2, GDPR, HIPAA, AWS Well-Architected, BSI C5, CSA CCM, MITRE ATT&CK, KISA ISMS-P, FedRAMP, and Prowler ThreatScore. The full catalog is available at [Prowler Hub](https://hub.prowler.com/compliance).
-For the unified compliance score methodology used across frameworks, see [Prowler ThreatScore Documentation](/user-guide/compliance/tutorials/threatscore).
+For the unified compliance score methodology used across frameworks, see [Prowler ThreatScore](/user-guide/compliance/tutorials/threatscore).
@@ -74,7 +75,7 @@ When the selected scan includes Prowler ThreatScore data, a dedicated card appea
Selecting the card opens the ThreatScore framework detail page, covered in [Working With the Framework Detail Page](#working-with-the-framework-detail-page).
-For a complete explanation of the methodology, formula, and weighting, see [Prowler ThreatScore Documentation](/user-guide/compliance/tutorials/threatscore).
+For a complete explanation of the methodology, formula, and weighting, see [Prowler ThreatScore](/user-guide/compliance/tutorials/threatscore).
### Exploring the Framework Grid
@@ -263,6 +264,6 @@ To request a new framework or contribute one, see [Creating a New Security Compl
## Related Documentation
* [Cross-Provider Compliance](/user-guide/compliance/tutorials/cross-provider-compliance)
-* [Prowler ThreatScore Documentation](/user-guide/compliance/tutorials/threatscore)
+* [Prowler ThreatScore](/user-guide/compliance/tutorials/threatscore)
* [Creating a New Security Compliance Framework in Prowler](/developer-guide/security-compliance-framework)
* [Prowler Cloud — Getting Started](/user-guide/tutorials/prowler-app)
diff --git a/docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx b/docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx
index b05fb6b5be..545f5fb834 100644
--- a/docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx
+++ b/docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx
@@ -204,6 +204,6 @@ The PDF detail section renders only **failed** requirements by default so the re
## Related Documentation
* [Compliance](/user-guide/compliance/tutorials/compliance)
-* [Prowler ThreatScore Documentation](/user-guide/compliance/tutorials/threatscore)
+* [Prowler ThreatScore](/user-guide/compliance/tutorials/threatscore)
* [Creating a New Security Compliance Framework in Prowler](/developer-guide/security-compliance-framework)
* [Prowler Cloud — Getting Started](/user-guide/tutorials/prowler-app)
diff --git a/docs/user-guide/compliance/tutorials/threatscore.mdx b/docs/user-guide/compliance/tutorials/threatscore.mdx
index 492f84c5d2..8d790cf90d 100644
--- a/docs/user-guide/compliance/tutorials/threatscore.mdx
+++ b/docs/user-guide/compliance/tutorials/threatscore.mdx
@@ -1,5 +1,5 @@
---
-title: "Prowler ThreatScore Documentation"
+title: "Prowler ThreatScore"
---
## Introduction