Compare commits

...
Author SHA1 Message Date
Alan Buscaglia 2a3c71c435 refactor: simplify gga script and exclude api/ via config 2025-12-16 14:07:42 +01:00
Alan Buscaglia 07a995a210 docs(changelog): add gga integration entry for PR #9571 2025-12-16 14:05:05 +01:00
Alan Buscaglia 73bf93a036 refactor: optimize AGENTS-CODE-REVIEW.md for LLM parsing
- Use REJECT/REQUIRE/PREFER keywords for clear action items
- Remove verbose explanations
- Use bullet points instead of paragraphs
- Add clear section separators
- Condense rules to single lines where possible
2025-12-16 13:52:27 +01:00
Alan Buscaglia d53e76e30a fix: add missing UI rules (shadcn, DRY/KISS, responsive) 2025-12-16 13:51:17 +01:00
Alan Buscaglia e2344b4fc6 fix: skip AI review for directories without AGENTS.md (opt-in model)
Components must have their own AGENTS.md to be included in AI code review.
This allows teams like API to opt-in when ready without blocking their workflow.
2025-12-16 13:49:13 +01:00
Alan Buscaglia eb1fc2b269 fix: add explicit brew tap before installing gga 2025-12-16 13:46:55 +01:00
Alan Buscaglia 4931564648 feat: replace custom Claude validation with Gentleman Guardian Angel (gga)
- Add .gga config in repo root for monorepo support (UI + Python)
- Add AGENTS-CODE-REVIEW.md with centralized code review rules
- Add scripts/gga-review.sh for pre-commit integration with auto-install
- Update .pre-commit-config.yaml to run gga after all formatters/linters
- Simplify ui/.husky/pre-commit to only run healthcheck + build
- Update ui/README.md with new gga documentation

Benefits:
- Provider agnostic: supports Claude, Gemini, Codex, Ollama
- Smart caching: skips unchanged files
- Monorepo support: reviews both TypeScript and Python
- Runs last: reviews code after formatting is applied
- Controlled by CODE_REVIEW_ENABLED environment variable
2025-12-16 13:40:04 +01:00
Rubén De la Torre VicoandDaniel Barranquero 433853493b chore(aws): enhance metadata for trustedadvisor service (#9435)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
2025-12-16 12:49:00 +01:00
Rubén De la Torre VicoandDaniel Barranquero 5aa112d438 chore(aws): enhance metadata for sns service (#9428)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
2025-12-16 12:33:49 +01:00
Rubén De la Torre VicoandDaniel Barranquero 1b2c73d2e3 chore(aws): enhance metadata for servicecatalog service (#9410)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
2025-12-16 12:12:36 +01:00
Rubén De la Torre VicoandDaniel Barranquero 90e3fabc33 chore(aws): enhance metadata for inspector2 service (#9260)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
2025-12-16 11:44:49 +01:00
Daniel BarranqueroandAndoni Alonso d4b90abd10 chore(mongodbatlas): store location as lowercase (#9554)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-12-16 10:40:49 +01:00
Hugo Pereira Brito 251fc6d4e3 fix: changelog trust-boundaries entry (#9563) 2025-12-16 10:06:38 +01:00
Hugo Pereira Brito dd85da703e chore: update prowler hub docs picture (#9564) 2025-12-16 09:40:27 +01:00
22 changed files with 435 additions and 243 deletions
+20
View File
@@ -0,0 +1,20 @@
# Gentleman Guardian Angel (gga) Configuration
# https://github.com/Gentleman-Programming/gentleman-guardian-angel
# AI Provider (required)
# Options: claude, gemini, codex, ollama:<model>
PROVIDER="claude"
# File patterns to include in review (comma-separated globs)
# Review both TypeScript (UI) and Python (SDK, API, MCP) files
FILE_PATTERNS="*.ts,*.tsx,*.js,*.jsx,*.py"
# File patterns to exclude from review (comma-separated globs)
# Excludes: test files, type definitions, and api/ folder (no AGENTS.md yet)
EXCLUDE_PATTERNS="*.test.ts,*.test.tsx,*.spec.ts,*.spec.tsx,*.d.ts,*_test.py,test_*.py,conftest.py,api/*"
# File containing your coding standards (relative to repo root)
RULES_FILE="AGENTS-CODE-REVIEW.md"
# Strict mode: fail if AI response is ambiguous (recommended)
STRICT_MODE="true"
+12 -2
View File
@@ -82,7 +82,6 @@ repos:
args: ["--directory=./"]
pass_filenames: false
- repo: https://github.com/hadolint/hadolint
rev: v2.13.0-beta
hooks:
@@ -129,9 +128,20 @@ repos:
- id: ui-checks
name: UI - Husky Pre-commit
description: "Run UI pre-commit checks (Claude Code validation + healthcheck)"
description: "Run UI pre-commit checks (healthcheck + build)"
entry: bash -c 'cd ui && .husky/pre-commit'
language: system
files: '^ui/.*\.(ts|tsx|js|jsx|json|css)$'
pass_filenames: false
verbose: true
- id: gga
name: Gentleman Guardian Angel (AI Code Review)
description: "AI-powered code review - runs last after all formatters/linters"
entry: ./scripts/gga-review.sh
language: system
files: '\.(ts|tsx|js|jsx|py)$'
exclude: '(\.test\.|\.spec\.|_test\.py|test_.*\.py|conftest\.py|\.d\.ts)'
pass_filenames: false
stages: ["pre-commit"]
verbose: true
+89
View File
@@ -0,0 +1,89 @@
# Code Review Rules
## References
- UI details: `ui/AGENTS.md`
- SDK details: `prowler/AGENTS.md`
- MCP details: `mcp_server/AGENTS.md`
---
## ALL FILES
REJECT if:
- Hardcoded secrets/credentials
- `any` type (TypeScript) or missing type hints (Python)
- Code duplication (violates DRY)
- Silent error handling (no logging)
---
## TypeScript/React (ui/)
REJECT if:
- `import React` or `import * as React` → use `import { useState }`
- Union types `type X = "a" | "b"` → use `const X = {...} as const`
- `var()` or hex colors in className → use Tailwind classes
- `useMemo` or `useCallback` without justification (React 19 Compiler)
- `z.string().email()` → use `z.email()` (Zod v4)
- `z.string().nonempty()` → use `z.string().min(1)` (Zod v4)
- Missing `"use client"` in client components
- Missing `"use server"` in server actions
- Images without `alt` attribute
- Interactive elements without `aria` labels
- Non-semantic HTML when semantic exists
PREFER:
- `components/shadcn/` over custom components
- `cn()` for conditional/merged classes
- Local files if used 1 place, `components/shared/` if 2+
- Responsive classes: `sm:`, `md:`, `lg:`, `xl:`
EXCEPTION:
- `var()` allowed in chart/graph component props (not className)
---
## Python (prowler/, mcp_server/)
REJECT if:
- Missing type hints on public functions
- Missing docstrings on classes/public methods
- Bare `except:` without specific exception
- `print()` instead of `logger`
REQUIRE for SDK checks:
- Inherit from `Check`
- `execute()` returns `list[CheckReport]`
- `report.status` = `"PASS"` | `"FAIL"`
- `.metadata.json` file exists
REQUIRE for MCP tools:
- Extend `BaseTool` (auto-registration)
- `MinimalSerializerMixin` for responses
- `from_api_response()` for API transforms
---
## Response Format
FIRST LINE must be exactly:
```
STATUS: PASSED
```
or
```
STATUS: FAILED
```
If FAILED, list: `file:line - rule - issue`
@@ -6,7 +6,7 @@ title: "Overview"
**Why this matters**: Every engineer has asked, “What does this check actually do?” Prowler Hub answers that question in one place, lets you pin to a specific version, and pulls definitions into your own tools or dashboards.
![](/images/products/prowler-hub.webp)
![](/images/products/prowler-hub.png)
<Card title="Go to Prowler Hub" href="https://hub.prowler.com" />
@@ -14,4 +14,4 @@ Prowler Hub also provides a fully documented public API that you can integrate i
📚 Explore the API docs at: https://hub.prowler.com/api/docs
Whether youre customizing policies, managing compliance, or enhancing visibility, Prowler Hub is built to support your security operations.
Whether youre customizing policies, managing compliance, or enhancing visibility, Prowler Hub is built to support your security operations.
Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

+13 -2
View File
@@ -14,14 +14,25 @@ All notable changes to the **Prowler SDK** are documented in this file.
- Update AWS Kafka service metadata to new format [(#9261)](https://github.com/prowler-cloud/prowler/pull/9261)
- Update AWS KMS service metadata to new format [(#9263)](https://github.com/prowler-cloud/prowler/pull/9263)
- Update AWS MemoryDB service metadata to new format [(#9266)](https://github.com/prowler-cloud/prowler/pull/9266)
- Update AWS Inspector v2 service metadata to new format [(#9260)](https://github.com/prowler-cloud/prowler/pull/9260)
- Update AWS Service Catalog service metadata to new format [(#9410)](https://github.com/prowler-cloud/prowler/pull/9410)
- Update AWS SNS service metadata to new format [(#9428)](https://github.com/prowler-cloud/prowler/pull/9428)
- Update AWS Trusted Advisor service metadata to new format [(#9435)](https://github.com/prowler-cloud/prowler/pull/9435)
---
## [5.15.1] (Prowler UNRELEASED)
## [5.15.2] (Prowler UNRELEASED)
### Fixed
- Fix typo `trustboundaries` category to `trust-boundaries` [(#9536)](https://github.com/prowler-cloud/prowler/pull/9536)
- Store MongoDB Atlas provider regions as lowercase [(#9554)](https://github.com/prowler-cloud/prowler/pull/9554)
---
## [5.15.1] (Prowler v5.15.1)
### Fixed
- Fix false negative in AWS `apigateway_restapi_logging_enabled` check by refining stage logging evaluation to ensure logging level is not set to "OFF" [(#9304)](https://github.com/prowler-cloud/prowler/pull/9304)
- Fix typo `trustboundaries` category to `trust-boundaries` [(#9536)](https://github.com/prowler-cloud/prowler/pull/9536)
---
@@ -1,29 +1,39 @@
{
"Provider": "aws",
"CheckID": "inspector2_active_findings_exist",
"CheckTitle": "Check if Inspector2 active findings exist",
"CheckTitle": "Inspector2 is enabled with no active findings",
"CheckAliases": [
"inspector2_findings_exist"
],
"CheckType": [],
"CheckType": [
"Software and Configuration Checks/Vulnerabilities/CVE",
"Software and Configuration Checks/Patch Management",
"Software and Configuration Checks/AWS Security Best Practices",
"Industry and Regulatory Standards/AWS Foundational Security Best Practices"
],
"ServiceName": "inspector2",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:inspector2:region:account-id/detector-id",
"Severity": "medium",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "Other",
"Description": "This check determines if there are any active findings in your AWS account that have been detected by AWS Inspector2. Inspector2 is an automated security assessment service that helps improve the security and compliance of applications deployed on AWS.",
"Risk": "Without using AWS Inspector, you may not be aware of all the security vulnerabilities in your AWS resources, which could lead to unauthorized access, data breaches, or other security incidents.",
"RelatedUrl": "https://docs.aws.amazon.com/inspector/latest/user/findings-understanding.html",
"Description": "**Amazon Inspector2** active findings are assessed across eligible resources when the service is `ENABLED`.\n\nIndicates whether any findings remain in the **Active** state versus none.",
"Risk": "**Unremediated Inspector2 findings** mean known vulnerabilities or exposures persist on workloads.\n\nThis enables:\n- Unauthorized access and data exfiltration (C)\n- Code tampering and privilege escalation (I)\n- Service disruption via exploitation or malware (A)",
"RelatedUrl": "",
"AdditionalURLs": [
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Inspector/amazon-inspector-findings.html",
"https://docs.aws.amazon.com/inspector/latest/user/findings-understanding.html",
"https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html"
],
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Inspector/amazon-inspector-findings.html",
"Terraform": ""
"CLI": "aws inspector2 create-filter --name <example_resource_name> --action SUPPRESS --filter-criteria '{\"findingStatus\":[{\"comparison\":\"EQUALS\",\"value\":\"ACTIVE\"}]}'",
"NativeIaC": "```yaml\n# CloudFormation: Suppress all ACTIVE Inspector findings\nResources:\n <example_resource_name>:\n Type: AWS::InspectorV2::Filter\n Properties:\n Name: <example_resource_name>\n Action: SUPPRESS # critical: converts matching findings to Suppressed, not Active\n FilterCriteria:\n FindingStatus:\n - Comparison: EQUALS\n Value: ACTIVE # critical: targets all active findings\n```",
"Other": "1. In the AWS Console, go to Amazon Inspector\n2. Open Suppression rules (or Filters) and click Create suppression rule\n3. Set condition: Finding status = Active\n4. Set action to Suppress and click Create\n5. Verify the Active findings count is 0 on the dashboard",
"Terraform": "```hcl\n# Terraform: Suppress all ACTIVE Inspector findings\nresource \"aws_inspector2_filter\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n action = \"SUPPRESS\" # critical: converts matching findings to Suppressed, not Active\n\n filter_criteria {\n finding_status {\n comparison = \"EQUALS\"\n value = \"ACTIVE\" # critical: targets all active findings\n }\n }\n}\n```"
},
"Recommendation": {
"Text": "Review the active findings from Inspector2",
"Url": "https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html"
"Text": "Prioritize and remediate **Active findings** quickly: patch hosts and runtimes, update/rebuild images, fix vulnerable code, and close unintended exposure.\n\nApply **least privilege**, use **defense in depth**, and avoid broad suppressions. Integrate findings into CI/CD and vulnerability management for continuous prevention.",
"Url": "https://hub.prowler.com/check/inspector2_active_findings_exist"
}
},
"Categories": [],
@@ -1,31 +1,37 @@
{
"Provider": "aws",
"CheckID": "inspector2_is_enabled",
"CheckTitle": "Check if Inspector2 is enabled for Amazon EC2 instances, ECR container images and Lambda functions.",
"CheckTitle": "Inspector2 is enabled for Amazon EC2 instances, ECR container images, Lambda functions, and Lambda code",
"CheckAliases": [
"inspector2_findings_exist"
],
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices"
"Software and Configuration Checks/AWS Security Best Practices",
"Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices"
],
"ServiceName": "inspector2",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:inspector2:region:account-id/detector-id",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "AwsAccount",
"Description": "Ensure that the new version of Amazon Inspector is enabled in order to help you improve the security and compliance of your AWS cloud environment. Amazon Inspector 2 is a vulnerability management solution that continually scans scans your Amazon EC2 instances, ECR container images, and Lambda functions to identify software vulnerabilities and instances of unintended network exposure.",
"Risk": "Without using AWS Inspector, you may not be aware of all the security vulnerabilities in your AWS resources, which could lead to unauthorized access, data breaches, or other security incidents.",
"RelatedUrl": "https://docs.aws.amazon.com/inspector/latest/user/findings-understanding.html",
"ResourceType": "Other",
"Description": "**Amazon Inspector 2** activation and coverage across regions, verifying that scanning is active for **EC2**, **ECR**, **Lambda functions**, and **Lambda code** where applicable.\n\nIt flags missing account activation or gaps in any scan type.",
"Risk": "Absent or partial coverage leaves **unpatched vulnerabilities**, risky **code dependencies**, and **unintended network exposure** undetected.\n\nAttackers can exploit known CVEs for **remote code execution**, **lateral movement**, and **data exfiltration**, degrading **confidentiality**, **integrity**, and **availability**.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Inspector2/enable-amazon-inspector2.html",
"https://docs.aws.amazon.com/inspector/latest/user/findings-understanding.html",
"https://docs.aws.amazon.com/inspector/latest/user/getting_started_tutorial.html"
],
"Remediation": {
"Code": {
"CLI": "aws inspector2 enable --resource-types 'EC2' 'ECR' 'LAMBDA' 'LAMBDA_CODE'",
"CLI": "aws inspector2 enable --resource-types EC2 ECR LAMBDA LAMBDA_CODE",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Inspector2/enable-amazon-inspector2.html",
"Terraform": ""
"Other": "1. Sign in to the AWS Console and open Amazon Inspector (v2)\n2. If not yet activated: click Get started > Activate Amazon Inspector\n3. If already activated: go to Settings > Scans and ensure EC2, ECR, Lambda functions, and Lambda code are all enabled, then Save",
"Terraform": "```hcl\nresource \"aws_inspector2_enabler\" \"<example_resource_name>\" {\n resource_types = [\"EC2\", \"ECR\", \"LAMBDA\", \"LAMBDA_CODE\"] # Enables Inspector2 scans for all required resource types\n}\n```"
},
"Recommendation": {
"Text": "Enable Amazon Inspector 2 for your AWS account.",
"Url": "https://docs.aws.amazon.com/inspector/latest/user/getting_started_tutorial.html"
"Text": "Enable **Amazon Inspector 2** across all regions and activate scans for **EC2**, **ECR**, **Lambda**, and **Lambda code**.\n\nApply **defense in depth**: auto-enable coverage for new workloads, integrate findings with patching and CI/CD gates, enforce remediation SLAs, and grant only **least privilege** to process and act on findings.",
"Url": "https://hub.prowler.com/check/inspector2_is_enabled"
}
},
"Categories": [],
@@ -1,28 +1,32 @@
{
"Provider": "aws",
"CheckID": "servicecatalog_portfolio_shared_within_organization_only",
"CheckTitle": "Service Catalog portfolios should be shared within an AWS organization only",
"CheckTitle": "Service Catalog portfolio is shared only within the AWS Organization",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices"
"Software and Configuration Checks/AWS Security Best Practices",
"TTPs/Initial Access/Unauthorized Access"
],
"ServiceName": "servicecatalog",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:servicecatalog:{region}:{account-id}:portfolio/{portfolio-id}",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "AwsServiceCatalogPortfolio",
"Description": "This control checks whether AWS Service Catalog shares portfolios within an organization when the integration with AWS Organizations is enabled. The control fails if portfolios aren't shared within an organization.",
"Risk": "Sharing Service Catalog portfolios outside of an organization may result in access granted to unintended AWS accounts, potentially exposing sensitive resources.",
"RelatedUrl": "https://docs.aws.amazon.com/servicecatalog/latest/adminguide/catalogs_portfolios_sharing.html",
"ResourceType": "Other",
"Description": "**AWS Service Catalog portfolios** are assessed to confirm sharing occurs via **AWS Organizations** integration, not direct `ACCOUNT` shares. It reviews shared portfolios and identifies those targeted to individual accounts instead of organizational scopes.",
"Risk": "Sharing with individual accounts enables recipients to import and launch products outside centralized guardrails, inheriting launch roles. This can cause unauthorized provisioning, data exposure, and configuration drift-impacting confidentiality, integrity, and availability through misused privileges and uncontrolled costs.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://docs.aws.amazon.com/servicecatalog/latest/adminguide/catalogs_portfolios_sharing.html"
],
"Remediation": {
"Code": {
"CLI": "aws servicecatalog create-portfolio-share --portfolio-id <portfolio-id> --organization-ids <org-id>",
"NativeIaC": "",
"Other": "https://docs.aws.amazon.com/servicecatalog/latest/adminguide/catalogs_portfolios_sharing.html",
"Terraform": ""
"NativeIaC": "```yaml\n# CloudFormation: Share Service Catalog portfolio only within the AWS Organization\nResources:\n <example_resource_name>:\n Type: AWS::ServiceCatalog::PortfolioShare\n Properties:\n PortfolioId: <example_resource_id>\n OrganizationNode: # CRITICAL: share within AWS Organizations\n Type: ORGANIZATION # Shares the portfolio with the entire org\n Value: <example_resource_id> # e.g., o-xxxxxxxxxx\n```",
"Other": "1. In the AWS Console, go to Service Catalog > Portfolios and open the target portfolio\n2. Open the Shares/Sharing tab\n3. Remove every share of Type \"Account\" (stop sharing with each account)\n4. Click Share, choose \"AWS Organizations\", set Type to \"Organization\", enter your Org ID (o-xxxxxxxxxx), and share\n5. Verify no remaining shares of Type \"Account\" exist",
"Terraform": "```hcl\n# Share Service Catalog portfolio only within the AWS Organization\nresource \"aws_servicecatalog_portfolio_share\" \"<example_resource_name>\" {\n portfolio_id = \"<example_resource_id>\"\n\n organization_node { # CRITICAL: share within AWS Organizations\n type = \"ORGANIZATION\" # Shares the portfolio with the entire org\n value = \"<example_resource_id>\" # e.g., o-xxxxxxxxxx\n }\n}\n```"
},
"Recommendation": {
"Text": "Configure AWS Service Catalog to share portfolios only within your AWS Organization for more secure access management.",
"Url": "https://docs.aws.amazon.com/servicecatalog/latest/adminguide/catalogs_portfolios_sharing.html"
"Text": "Prefer **organizational sharing** for portfolios and avoid `ACCOUNT` targets. Enforce **least privilege** on portfolio access and launch roles, and review shares regularly. Apply **separation of duties** and **defense in depth** so only governed accounts consume products and blast radius remains constrained.",
"Url": "https://hub.prowler.com/check/servicecatalog_portfolio_shared_within_organization_only"
}
},
"Categories": [
@@ -1,26 +1,33 @@
{
"Provider": "aws",
"CheckID": "sns_subscription_not_using_http_endpoints",
"CheckTitle": "Ensure there are no SNS subscriptions using HTTP endpoints",
"CheckType": [],
"CheckTitle": "SNS subscription uses an HTTPS endpoint",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices/Network Reachability",
"Effects/Data Exposure"
],
"ServiceName": "sns",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:sns:region:account-id:topic",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "AwsSnsTopic",
"Description": "Ensure there are no SNS subscriptions using HTTP endpoints",
"Risk": "When you use HTTPS, messages are automatically encrypted during transit, even if the SNS topic itself isn't encrypted. Without HTTPS, a network-based attacker can eavesdrop on network traffic or manipulate it using an attack such as man-in-the-middle.",
"RelatedUrl": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit",
"Description": "Amazon SNS subscriptions are evaluated for endpoint protocol. Subscriptions using `http` are identified, while **HTTPS** endpoints indicate encrypted delivery in transit.",
"Risk": "Using **HTTP** leaves SNS deliveries unencrypted, compromising **confidentiality** via eavesdropping. MITM attackers can modify payloads or headers, damaging **integrity**, inject malicious content into downstream systems, or capture subscription data for spoofing and unauthorized actions.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-subscription.html",
"https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit"
],
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "",
"Terraform": ""
"NativeIaC": "```yaml\n# CloudFormation: Ensure SNS subscription uses HTTPS\nResources:\n <example_resource_name>:\n Type: AWS::SNS::Subscription\n Properties:\n TopicArn: <example_resource_id>\n Protocol: https # Critical: use HTTPS protocol to remediate HTTP usage\n Endpoint: https://<example_endpoint> # Critical: HTTPS endpoint URL\n```",
"Other": "1. Open the Amazon SNS console and go to Subscriptions\n2. Select the subscription with Protocol set to HTTP and click Delete\n3. Click Create subscription\n4. Choose the same Topic ARN, set Protocol to HTTPS, and enter your HTTPS endpoint URL\n5. Create the subscription and confirm it from your endpoint if required",
"Terraform": "```hcl\n# Terraform: Ensure SNS subscription uses HTTPS\nresource \"aws_sns_topic_subscription\" \"<example_resource_name>\" {\n topic_arn = \"<example_resource_id>\"\n protocol = \"https\" # Critical: enforce HTTPS protocol\n endpoint = \"https://<example_endpoint>\" # Critical: HTTPS endpoint URL\n}\n```"
},
"Recommendation": {
"Text": "To enforce only encrypted connections over HTTPS, add the aws:SecureTransport condition in the IAM policy that's attached to unencrypted SNS topics. This forces message publishers to use HTTPS instead of HTTP",
"Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-security-best-practices.html#enforce-encryption-data-in-transit"
"Text": "Require **HTTPS** for all SNS subscription endpoints. Prefer domain-based endpoints, verify SNS message signatures, and apply **least privilege**. Enforce TLS using IAM conditions like `aws:SecureTransport`, and use private connectivity (VPC endpoints) where possible for defense in depth.",
"Url": "https://hub.prowler.com/check/sns_subscription_not_using_http_endpoints"
}
},
"Categories": [
@@ -1,26 +1,37 @@
{
"Provider": "aws",
"CheckID": "sns_topics_kms_encryption_at_rest_enabled",
"CheckTitle": "Ensure there are no SNS Topics unencrypted",
"CheckType": [],
"CheckTitle": "SNS topic is encrypted at rest with KMS",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices",
"Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices",
"Software and Configuration Checks/Industry and Regulatory Standards/NIST 800-53 Controls (USA)",
"Software and Configuration Checks/Industry and Regulatory Standards/NIST CSF Controls (USA)",
"Software and Configuration Checks/Industry and Regulatory Standards/PCI-DSS",
"Software and Configuration Checks/Industry and Regulatory Standards/ISO 27001 Controls"
],
"ServiceName": "sns",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:sns:region:account-id:topic",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "AwsSnsTopic",
"Description": "Ensure there are no SNS Topics unencrypted",
"Risk": "If not enabled sensitive information at rest is not protected.",
"RelatedUrl": "https://docs.aws.amazon.com/sns/latest/dg/sns-server-side-encryption.html",
"Description": "**Amazon SNS topics** are assessed for **server-side encryption** with **AWS KMS**. Topics lacking a configured KMS key (e.g., missing `kms_master_key_id`) are identified as unencrypted at rest.",
"Risk": "Without KMS-backed SSE, SNS stores message bodies unencrypted at rest, undermining **confidentiality**.\n\nPrivileged insiders or compromised service components could access plaintext during persistence windows, causing data exposure. You also lose KMS controls such as key policies, rotation, and detailed audit trails.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SNS/topic-encrypted-with-kms-customer-master-keys.html",
"https://docs.aws.amazon.com/sns/latest/dg/sns-server-side-encryption.html"
],
"Remediation": {
"Code": {
"CLI": "aws sns set-topic-attributes --topic-arn <TOPIC_ARN> --attribute-name 'KmsMasterKeyId' --attribute-value <KEY>",
"NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_15#cloudformation",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SNS/topic-encrypted-with-kms-customer-master-keys.html",
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_15#terraform"
"CLI": "aws sns set-topic-attributes --topic-arn <TOPIC_ARN> --attribute-name KmsMasterKeyId --attribute-value alias/aws/sns",
"NativeIaC": "```yaml\n# CloudFormation: Enable SSE for an SNS topic\nResources:\n <example_resource_name>:\n Type: AWS::SNS::Topic\n Properties:\n KmsMasterKeyId: alias/aws/sns # Critical: Enables encryption at rest with AWS managed KMS key\n```",
"Other": "1. Open the AWS Console and go to Amazon SNS > Topics\n2. Select the topic and click Edit\n3. Under Encryption, enable encryption and choose the AWS managed key for SNS (alias/aws/sns)\n4. Click Save changes",
"Terraform": "```hcl\n# Enable SSE for an SNS topic\nresource \"aws_sns_topic\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n kms_master_key_id = \"alias/aws/sns\" # Critical: Enables encryption at rest\n}\n```"
},
"Recommendation": {
"Text": "Use Amazon SNS with AWS KMS.",
"Url": "https://docs.aws.amazon.com/sns/latest/dg/sns-server-side-encryption.html"
"Text": "Enable **server-side encryption** on all SNS topics with **AWS KMS**; prefer **customer-managed keys** for control.\n\nApply **least privilege** on key use, enforce rotation, and monitor key/access logs. Minimize sensitive data in messages and use end-to-end encryption *where feasible* to add defense in depth.",
"Url": "https://hub.prowler.com/check/sns_topics_kms_encryption_at_rest_enabled"
}
},
"Categories": [
@@ -1,26 +1,35 @@
{
"Provider": "aws",
"CheckID": "sns_topics_not_publicly_accessible",
"CheckTitle": "Check if SNS topics have policy set as Public",
"CheckType": [],
"CheckTitle": "SNS topic is not publicly accessible",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices",
"Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices",
"Effects/Data Exposure",
"TTPs/Initial Access"
],
"ServiceName": "sns",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:sns:region:account-id:topic",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "AwsSnsTopic",
"Description": "Check if SNS topics have policy set as Public",
"Risk": "Publicly accessible services could expose sensitive data to bad actors.",
"RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/sns-topic-policy.html",
"Description": "**SNS topic policies** are analyzed for **public principals** (e.g., `*`). Topics that grant access without restrictive conditions such as `aws:SourceArn`, `aws:SourceAccount`, `aws:PrincipalOrgID`, or `sns:Endpoint` scoping are treated as publicly accessible.",
"Risk": "**Public SNS topics** allow anyone or unknown accounts to:\n- **Subscribe** and siphon messages (confidentiality)\n- **Publish** spoofed payloads that alter workflows (integrity)\n- **Flood** messages causing outages and costs (availability)\nThey also enable cross-account abuse and bypass expected trust boundaries.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SNS/topics-everyone-publish.html",
"https://docs.aws.amazon.com/config/latest/developerguide/sns-topic-policy.html"
],
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/SNS/topics-everyone-publish.html",
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-sns-topic-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform"
"CLI": "aws sns set-topic-attributes --topic-arn <TOPIC_ARN> --attribute-name Policy --attribute-value '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::<ACCOUNT_ID>:root\"},\"Action\":\"sns:Publish\",\"Resource\":\"<TOPIC_ARN>\"}]}'",
"NativeIaC": "```yaml\n# CloudFormation: restrict SNS topic policy to the account (not public)\nResources:\n <example_resource_name>:\n Type: AWS::SNS::TopicPolicy\n Properties:\n Topics:\n - arn:aws:sns:<region>:<account_id>:<example_resource_name>\n PolicyDocument:\n Version: '2012-10-17'\n Statement:\n - Effect: Allow\n Action: sns:Publish\n Resource: arn:aws:sns:<region>:<account_id>:<example_resource_name>\n Principal:\n AWS: arn:aws:iam::<account_id>:root # Critical: restrict to account root to remove public access\n```",
"Other": "1. Open the Amazon SNS console and select Topics\n2. Choose the topic and go to the Access policy tab\n3. Edit the policy and remove any Principal set to \"*\" (Everyone/Public)\n4. Add a statement allowing only your account root: Principal = arn:aws:iam::<ACCOUNT_ID>:root with Action sns:Publish and Resource set to the topic ARN\n5. Save changes",
"Terraform": "```hcl\n# Restrict SNS topic policy to the account (not public)\nresource \"aws_sns_topic_policy\" \"<example_resource_name>\" {\n arn = \"<TOPIC_ARN>\"\n policy = jsonencode({\n Version = \"2012-10-17\"\n Statement = [{\n Effect = \"Allow\"\n Action = \"sns:Publish\"\n Resource = \"<TOPIC_ARN>\"\n Principal = { AWS = \"arn:aws:iam::<ACCOUNT_ID>:root\" } # Critical: restrict principal to the account to remove public access\n }]\n })\n}\n```"
},
"Recommendation": {
"Text": "Ensure there is a business requirement for service to be public.",
"Url": "https://docs.aws.amazon.com/config/latest/developerguide/sns-topic-policy.html"
"Text": "Restrict the **topic policy** to specific principals and minimal actions:\n- Avoid `Principal:*`\n- Allow only needed actions (e.g., `sns:Publish`)\n- Add conditions like `aws:SourceArn`, `aws:SourceAccount`, `aws:PrincipalOrgID`, or `sns:Endpoint`\nApply **least privilege**, separate duties, and review policies regularly.",
"Url": "https://hub.prowler.com/check/sns_topics_not_publicly_accessible"
}
},
"Categories": [
@@ -1,26 +1,32 @@
{
"Provider": "aws",
"CheckID": "trustedadvisor_errors_and_warnings",
"CheckTitle": "Check Trusted Advisor for errors and warnings.",
"CheckType": [],
"CheckTitle": "Trusted Advisor check has no errors or warnings",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices"
],
"ServiceName": "trustedadvisor",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:service:region:account-id",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "Other",
"Description": "Check Trusted Advisor for errors and warnings.",
"Risk": "Improve the security of your application by closing gaps, enabling various AWS security features and examining your permissions.",
"RelatedUrl": "https://aws.amazon.com/premiumsupport/technology/trusted-advisor/best-practice-checklist/",
"Description": "**AWS Trusted Advisor** check statuses are assessed to identify items in `warning` or `error`. The finding reflects the state reported by Trusted Advisor across categories such as **Security**, **Fault Tolerance**, **Service Limits**, and **Cost**, indicating where configurations or quotas require attention.",
"Risk": "Unaddressed **warnings/errors** can leave misconfigurations that impact CIA:\n- **Confidentiality**: public access or weak auth exposes data\n- **Integrity**: overly permissive settings allow unwanted changes\n- **Availability**: limit exhaustion or poor resilience triggers outages\nThey can also increase unnecessary cost.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://aws.amazon.com/premiumsupport/technology/trusted-advisor/best-practice-checklist/",
"https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/TrustedAdvisor/checks.html"
],
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/TrustedAdvisor/checks.html",
"Other": "1. Sign in to the AWS Console and open Trusted Advisor\n2. Go to Checks and filter Status to Warning and Error\n3. Open each failing check and click View details/Recommended actions\n4. Apply the listed fix to the affected resources\n5. Click Refresh on the check and repeat until all checks show OK",
"Terraform": ""
},
"Recommendation": {
"Text": "Review and act upon its recommendations.",
"Url": "https://aws.amazon.com/premiumsupport/technology/trusted-advisor/best-practice-checklist/"
"Text": "Adopt a continuous process to remediate Trusted Advisor findings:\n- Prioritize **`error`** then `warning`\n- Assign ownership and SLAs\n- Integrate alerts with workflows\n- Enforce **least privilege**, segmentation, encryption, MFA, and tested backups\n- Reassess regularly to confirm fixes and prevent regression",
"Url": "https://hub.prowler.com/check/trustedadvisor_errors_and_warnings"
}
},
"Categories": [],
@@ -1,29 +1,37 @@
{
"Provider": "aws",
"CheckID": "trustedadvisor_premium_support_plan_subscribed",
"CheckTitle": "Check if a Premium support plan is subscribed",
"CheckType": [],
"CheckTitle": "AWS account is subscribed to an AWS Premium Support plan",
"CheckType": [
"Software and Configuration Checks/AWS Security Best Practices"
],
"ServiceName": "trustedadvisor",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:iam::AWS_ACCOUNT_NUMBER:root",
"ResourceIdTemplate": "",
"Severity": "low",
"ResourceType": "Other",
"Description": "Check if a Premium support plan is subscribed.",
"Risk": "Ensure that the appropriate support level is enabled for the necessary AWS accounts. For example, if an AWS account is being used to host production systems and environments, it is highly recommended that the minimum AWS Support Plan should be Business.",
"RelatedUrl": "https://aws.amazon.com/premiumsupport/plans/",
"Description": "**AWS account** is subscribed to an **AWS Premium Support plan** (e.g., Business or Enterprise)",
"Risk": "Without **Premium Support**, critical incidents face slower response, reducing **availability** and delaying containment of security events. Limited Trusted Advisor coverage lets **misconfigurations** persist, risking **data exposure** and **privilege misuse**. Lack of expert guidance increases change risk during production impacts.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/Support/support-plan.html",
"https://aws.amazon.com/premiumsupport/plans/"
],
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/Support/support-plan.html",
"Other": "1. Sign in to the AWS Management Console as the account root user\n2. Open https://console.aws.amazon.com/support/home#/plans\n3. Click \"Change plan\"\n4. Select \"Business Support\" (or higher) and click \"Continue\"\n5. Review and confirm the upgrade",
"Terraform": ""
},
"Recommendation": {
"Text": "It is recommended that you subscribe to the AWS Business Support tier or higher for all of your AWS production accounts. If you don't have premium support, you must have an action plan to handle issues which require help from AWS Support. AWS Support provides a mix of tools and technology, people, and programs designed to proactively help you optimize performance, lower costs, and innovate faster.",
"Url": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/Support/support-plan.html"
"Text": "Adopt **Business** or higher for production and mission-critical accounts.\n- Integrate Support into IR with defined contacts/severity\n- Enforce **least privilege** for case access\n- Use Trusted Advisor for proactive hardening\n- If opting out, ensure an equivalent 24/7 support and escalation path",
"Url": "https://hub.prowler.com/check/trustedadvisor_premium_support_plan_subscribed"
}
},
"Categories": [],
"Categories": [
"resilience"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
@@ -17,6 +17,28 @@ class Clusters(MongoDBAtlasService):
super().__init__(__class__.__name__, provider)
self.clusters = self._list_clusters()
def _extract_location(self, cluster_data: dict) -> str:
"""
Extract location from cluster data and convert to lowercase
Args:
cluster_data: Cluster data from API
Returns:
str: Location in lowercase, empty string if not found
"""
try:
replication_specs = cluster_data.get("replicationSpecs", [])
if replication_specs and len(replication_specs) > 0:
region_configs = replication_specs[0].get("regionConfigs", [])
if region_configs and len(region_configs) > 0:
region_name = region_configs[0].get("regionName", "")
if region_name:
return region_name.lower()
except (KeyError, IndexError, AttributeError):
pass
return ""
def _list_clusters(self):
"""
List all MongoDB Atlas clusters across all projects
@@ -89,9 +111,7 @@ class Clusters(MongoDBAtlasService):
"connectionStrings", {}
),
tags=cluster_data.get("tags", []),
location=cluster_data.get("replicationSpecs", {})[0]
.get("regionConfigs", {})[0]
.get("regionName", ""),
location=self._extract_location(cluster_data),
)
# Use a unique key combining project_id and cluster_name
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# Gentleman Guardian Angel (gga) - AI Code Review Hook
# This script is called by pre-commit after all formatters/linters have run
set -e
# Colors
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Check if AI code review is enabled
if [ "${CODE_REVIEW_ENABLED:-false}" != "true" ]; then
echo -e "${YELLOW}⏭️ AI code review disabled (CODE_REVIEW_ENABLED!=true)${NC}"
exit 0
fi
# Check if AGENTS-CODE-REVIEW.md exists
if [ ! -f "AGENTS-CODE-REVIEW.md" ]; then
echo -e "${YELLOW}⏭️ AI code review skipped (AGENTS-CODE-REVIEW.md not found)${NC}"
exit 0
fi
# Install gga if not present
if ! command -v gga &> /dev/null; then
echo -e "${BLUE}📦 Installing Gentleman Guardian Angel (gga)...${NC}"
if command -v brew &> /dev/null; then
brew tap gentleman-programming/tap 2>/dev/null || true
brew install gga
else
# Fallback: install from source for Linux/CI environments
GGA_TMP_DIR=$(mktemp -d)
git clone --depth 1 https://github.com/Gentleman-Programming/gentleman-guardian-angel.git "$GGA_TMP_DIR"
chmod +x "$GGA_TMP_DIR/install.sh"
"$GGA_TMP_DIR/install.sh"
rm -rf "$GGA_TMP_DIR"
fi
fi
# Verify gga is available
if ! command -v gga &> /dev/null; then
echo "❌ Failed to install gga"
echo "Please install manually: https://github.com/Gentleman-Programming/gentleman-guardian-angel"
exit 1
fi
# Run gga code review
# Exclusions are configured in .gga file (EXCLUDE_PATTERNS)
exec gga run
@@ -157,7 +157,7 @@ class TestMongoDBAtlasMutelist:
"*": {
"Checks": {
"clusters_backup_enabled": {
"Regions": ["WESTERN_EUROPE"],
"Regions": ["western_europe"],
"Resources": ["*"],
}
}
@@ -172,7 +172,7 @@ class TestMongoDBAtlasMutelist:
finding.check_metadata.CheckID = "clusters_backup_enabled"
finding.status = "FAIL"
finding.resource_name = "any-cluster"
finding.location = "WESTERN_EUROPE"
finding.location = "western_europe"
finding.resource_tags = []
assert mutelist.is_finding_muted(finding, "any-org-id")
@@ -64,7 +64,7 @@ def mock_clusters_list_clusters(_):
pit_enabled=True,
connection_strings={"standard": "mongodb://cluster.mongodb.net"},
tags=[{"key": "environment", "value": "test"}],
location="US_EAST_1",
location="us_east_1",
)
}
@@ -109,4 +109,4 @@ class Test_Clusters_Service:
assert cluster.connection_strings["standard"] == "mongodb://cluster.mongodb.net"
assert cluster.tags[0]["key"] == "environment"
assert cluster.tags[0]["value"] == "test"
assert cluster.location == "US_EAST_1"
assert cluster.location == "us_east_1"
+4 -118
View File
@@ -1,15 +1,14 @@
#!/bin/bash
# Prowler UI - Pre-Commit Hook
# Optionally validates ONLY staged files against AGENTS.md standards using Claude Code
# Controlled by CODE_REVIEW_ENABLED in .env
# Runs healthcheck (typecheck + lint) and build for UI changes
# AI code review is handled by gga in .pre-commit-config.yaml
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
@@ -19,127 +18,14 @@ echo "🚀 Prowler UI - Pre-Commit Hook"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Load .env file (look in git root directory)
# Get git root and navigate to ui directory
GIT_ROOT=$(git rev-parse --show-toplevel)
if [ -f "$GIT_ROOT/ui/.env" ]; then
CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" "$GIT_ROOT/ui/.env" | cut -d'=' -f2 | tr -d ' ')
elif [ -f "$GIT_ROOT/.env" ]; then
CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" "$GIT_ROOT/.env" | cut -d'=' -f2 | tr -d ' ')
elif [ -f ".env" ]; then
CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" .env | cut -d'=' -f2 | tr -d ' ')
else
CODE_REVIEW_ENABLED="false"
fi
# Normalize the value to lowercase
CODE_REVIEW_ENABLED=$(echo "$CODE_REVIEW_ENABLED" | tr '[:upper:]' '[:lower:]')
echo -e "${BLUE}️ Code Review Status: ${CODE_REVIEW_ENABLED}${NC}"
echo ""
# Get staged files (what will be committed)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx?|jsx?)$' || true)
if [ "$CODE_REVIEW_ENABLED" = "true" ]; then
if [ -z "$STAGED_FILES" ]; then
echo -e "${YELLOW}⚠️ No TypeScript/JavaScript files staged to validate${NC}"
echo ""
else
echo -e "${YELLOW}🔍 Running Claude Code standards validation...${NC}"
echo ""
echo -e "${BLUE}📋 Files to validate:${NC}"
echo "$STAGED_FILES" | while IFS= read -r file; do echo " - $file"; done
echo ""
echo -e "${BLUE}📤 Sending to Claude Code for validation...${NC}"
echo ""
# Build prompt with full file contents
VALIDATION_PROMPT=$(
cat <<'PROMPT_EOF'
You are a code reviewer for the Prowler UI project. Analyze the full file contents of changed files below and validate they comply with AGENTS.md standards.
**RULES TO CHECK:**
1. React Imports: NO `import * as React` or `import React, {` → Use `import { useState }`
2. TypeScript: NO union types like `type X = "a" | "b"` → Use const-based: `const X = {...} as const`
3. Tailwind: NO `var()` or hex colors in className → Use Tailwind utilities and semantic color classes. Exception: `var()` is allowed when passing colors to chart/graph components that require CSS color strings (not Tailwind classes) for their APIs.
4. cn(): Use for merging multiple classes or for conditionals (handles Tailwind conflicts with twMerge) → `cn(BUTTON_STYLES.base, BUTTON_STYLES.active, isLoading && "opacity-50")`
5. React 19: NO `useMemo`/`useCallback` without reason
6. Zod v4: Use `.min(1)` not `.nonempty()`, `z.email()` not `z.string().email()`. All inputs must be validated with Zod.
7. File Org: 1 feature = local, 2+ features = shared
8. Directives: Server Actions need "use server", clients need "use client"
9. Implement DRY, KISS principles. (example: reusable components, avoid repetition)
10. Layout must work for all the responsive breakpoints (mobile, tablet, desktop)
11. ANY types cannot be used - CRITICAL: Check for `: any` in all visible lines
12. Use the components inside components/shadcn if possible
13. Check Accessibility best practices (like alt tags in images, semantic HTML, Aria labels, etc.)
=== FILES TO REVIEW ===
PROMPT_EOF
)
# Add full file contents for each staged file
for file in $STAGED_FILES; do
VALIDATION_PROMPT="$VALIDATION_PROMPT
=== FILE: $file ===
$(cat "$file" 2>/dev/null || echo "Error reading file")"
done
VALIDATION_PROMPT="$VALIDATION_PROMPT
=== END FILES ===
**IMPORTANT: Your response MUST start with exactly one of these lines:**
STATUS: PASSED
STATUS: FAILED
**If FAILED:** List each violation with File, Line Number, Rule Number, and Issue.
**If PASSED:** Confirm all files comply with AGENTS.md standards.
**Start your response now with STATUS:**"
# Send to Claude Code
if VALIDATION_OUTPUT=$(echo "$VALIDATION_PROMPT" | claude 2>&1); then
echo "$VALIDATION_OUTPUT"
echo ""
# Check result - STRICT MODE: fail if status unclear
if echo "$VALIDATION_OUTPUT" | grep -q "^STATUS: PASSED"; then
echo ""
echo -e "${GREEN}✅ VALIDATION PASSED${NC}"
echo ""
elif echo "$VALIDATION_OUTPUT" | grep -q "^STATUS: FAILED"; then
echo ""
echo -e "${RED}❌ VALIDATION FAILED${NC}"
echo -e "${RED}Fix violations before committing${NC}"
echo ""
exit 1
else
echo ""
echo -e "${RED}❌ VALIDATION ERROR${NC}"
echo -e "${RED}Could not determine validation status from Claude Code response${NC}"
echo -e "${YELLOW}Response must start with 'STATUS: PASSED' or 'STATUS: FAILED'${NC}"
echo ""
echo -e "${YELLOW}To bypass validation temporarily, set CODE_REVIEW_ENABLED=false in .env${NC}"
echo ""
exit 1
fi
else
echo -e "${YELLOW}⚠️ Claude Code not available${NC}"
fi
echo ""
fi
else
echo -e "${YELLOW}⏭️ Code review disabled (CODE_REVIEW_ENABLED=false)${NC}"
echo ""
fi
cd "$GIT_ROOT/ui" || exit 1
# Run healthcheck (typecheck and lint check)
echo -e "${BLUE}🏥 Running healthcheck...${NC}"
echo ""
cd ui || cd .
if pnpm run healthcheck; then
echo ""
echo -e "${GREEN}✅ Healthcheck passed${NC}"
+2
View File
@@ -11,6 +11,8 @@ All notable changes to the **Prowler UI** are documented in this file.
### 🔄 Changed
- Replace custom Claude pre-commit validation with Gentleman Guardian Angel (gga) for provider-agnostic, monorepo-aware AI code reviews [(#9571)](https://github.com/prowler-cloud/prowler/pull/9571)
### 🐞 Fixed
---
+65 -21
View File
@@ -2,10 +2,12 @@
This repository hosts the UI component for Prowler, providing a user-friendly web interface to interact seamlessly with Prowler's features.
## 🚀 Production deployment
### Docker deployment
#### Clone the repository
```console
# HTTPS
git clone https://github.com/prowler-cloud/ui.git
@@ -14,16 +16,21 @@ git clone https://github.com/prowler-cloud/ui.git
git clone git@github.com:prowler-cloud/ui.git
```
#### Build the Docker image
```bash
docker build -t prowler-cloud/ui . --target prod
```
#### Run the Docker container
```bash
docker run -p 3000:3000 prowler-cloud/ui
```
### Local deployment
#### Clone the repository
```console
@@ -48,8 +55,11 @@ pnpm start
```
## 🧪 Development deployment
### Docker deployment
#### Clone the repository
```console
# HTTPS
git clone https://github.com/prowler-cloud/ui.git
@@ -58,16 +68,21 @@ git clone https://github.com/prowler-cloud/ui.git
git clone git@github.com:prowler-cloud/ui.git
```
#### Build the Docker image
```bash
docker build -t prowler-cloud/ui . --target dev
```
#### Run the Docker container
```bash
docker run -p 3000:3000 prowler-cloud/ui
```
### Local deployment
#### Clone the repository
```console
@@ -109,45 +124,74 @@ pnpm run dev
## Git Hooks & Code Review
This project uses Git hooks to maintain code quality. When you commit changes to TypeScript/JavaScript files, the pre-commit hook can optionally validate them against our coding standards using Claude Code.
This project uses Git hooks to maintain code quality:
### Enabling Code Review
1. **UI Pre-commit Hook** (`ui/.husky/pre-commit`): Runs healthcheck (typecheck + lint) and build for UI changes
2. **AI Code Review** (`.pre-commit-config.yaml`): Uses [Gentleman Guardian Angel (gga)](https://github.com/Gentleman-Programming/gentleman-guardian-angel) to validate code against `AGENTS-CODE-REVIEW.md` standards
To enable automatic code review on commits, add this to your `.env` file in the project root:
### Enabling AI Code Review
The AI code review runs **after** all formatters and linters have processed the code. To enable it, set in your environment or `.env` file:
```bash
CODE_REVIEW_ENABLED=true
export CODE_REVIEW_ENABLED=true
```
When enabled, the hook will:
- ✅ Validate your staged changes against `AGENTS.md` standards
- ✅ Check for common issues (any types, incorrect imports, styling violations, etc.)
- ✅ Block commits that don't comply with the standards
- ✅ Provide helpful feedback on how to fix issues
When enabled:
### Disabling Code Review
- ✅ Validates staged changes against `AGENTS-CODE-REVIEW.md` standards
- ✅ Reviews both TypeScript (UI) and Python (SDK, API, MCP) files
- ✅ Runs last, after black/isort/prettier have formatted the code
- ✅ Smart caching: skips unchanged files for faster reviews
- ✅ Blocks commits that don't comply with standards
To disable code review (faster commits, useful for quick iterations):
### Disabling AI Code Review
```bash
CODE_REVIEW_ENABLED=false
export CODE_REVIEW_ENABLED=false
```
Or remove the variable from your `.env` file.
Or simply don't set the variable (disabled by default).
### Requirements
- [Claude Code CLI](https://github.com/anthropics/claude-code) installed and authenticated
- `.env` file in the project root with `CODE_REVIEW_ENABLED` set
- **AI CLI**: One of the following must be installed and authenticated:
- [Claude Code CLI](https://claude.ai/code) (default, recommended)
- [Gemini CLI](https://github.com/google-gemini/gemini-cli)
- [Codex CLI](https://www.npmjs.com/package/@openai/codex)
- [Ollama](https://ollama.ai) (local models)
**Note:** `gga` will be installed automatically on first commit if not present.
### Configuration
The AI code review is configured via `.gga` in the **repository root**:
```bash
PROVIDER="claude" # AI provider
FILE_PATTERNS="*.ts,*.tsx,*.js,*.jsx,*.py"
EXCLUDE_PATTERNS="*.test.ts,*.spec.ts,*_test.py,test_*.py,conftest.py,*.d.ts"
RULES_FILE="AGENTS-CODE-REVIEW.md" # Centralized review rules
STRICT_MODE="true"
```
Available providers: `claude`, `gemini`, `codex`, `ollama:<model>`
### Troubleshooting
If hooks aren't running after commits:
If gga installation fails:
```bash
# Verify hooks are configured
git config --get core.hooksPath # Should output: ui/.husky
# Homebrew (macOS)
brew install gentleman-programming/tap/gga
# Reconfigure if needed
git config core.hooksPath "ui/.husky"
# From source (Linux/macOS)
git clone https://github.com/Gentleman-Programming/gentleman-guardian-angel.git /tmp/gga
cd /tmp/gga && ./install.sh
```
To clear the gga cache:
```bash
gga cache clear
```