Skip to content

Commit 684ef9c

Browse files
authored
Merge branch 'master' into fix/ui-compliance-card-layout
2 parents 1f675dd + 921f49a commit 684ef9c

143 files changed

Lines changed: 7682 additions & 521 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/labeler.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ jobs:
6262
"Alan-TheGentleman"
6363
"alejandrobailo"
6464
"amitsharm"
65-
"andoniaf"
65+
# "andoniaf"
6666
"cesararroba"
6767
"danibarranqueroo"
6868
"HugoPBrito"

.github/workflows/sdk-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,11 @@ jobs:
209209
echo "AWS service_paths='${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}'"
210210
211211
if [ "${STEPS_AWS_SERVICES_OUTPUTS_RUN_ALL}" = "true" ]; then
212-
poetry run pytest -p no:randomly -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml tests/providers/aws
212+
poetry run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml tests/providers/aws
213213
elif [ -z "${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}" ]; then
214214
echo "No AWS service paths detected; skipping AWS tests."
215215
else
216-
poetry run pytest -p no:randomly -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml ${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}
216+
poetry run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml ${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}
217217
fi
218218
env:
219219
STEPS_AWS_SERVICES_OUTPUTS_RUN_ALL: ${{ steps.aws-services.outputs.run_all }}

.pre-commit-config.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
1+
# Priority tiers (lower = runs first, same priority = concurrent):
2+
# P0 — fast file fixers
3+
# P10 — validators and guards
4+
# P20 — auto-formatters
5+
# P30 — linters
6+
# P40 — security scanners
7+
# P50 — dependency validation
8+
9+
default_install_hook_types: [pre-commit, pre-push]
10+
111
repos:
212
## GENERAL (prek built-in — no external repo needed)
313
- repo: builtin
414
hooks:
515
- id: check-merge-conflict
16+
priority: 10
617
- id: check-yaml
718
args: ["--allow-multiple-documents"]
819
exclude: (prowler/config/llm_config.yaml|contrib/)
20+
priority: 10
921
- id: check-json
22+
priority: 10
1023
- id: end-of-file-fixer
24+
priority: 0
1125
- id: trailing-whitespace
26+
priority: 0
1227
- id: no-commit-to-branch
28+
priority: 10
1329
- id: pretty-format-json
1430
args: ["--autofix", --no-sort-keys, --no-ensure-ascii]
31+
priority: 10
1532

1633
## TOML
1734
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
@@ -20,20 +37,23 @@ repos:
2037
- id: pretty-format-toml
2138
args: [--autofix]
2239
files: pyproject.toml
40+
priority: 20
2341

2442
## GITHUB ACTIONS
2543
- repo: https://github.com/zizmorcore/zizmor-pre-commit
2644
rev: v1.24.1
2745
hooks:
2846
- id: zizmor
2947
files: ^\.github/
48+
priority: 30
3049

3150
## BASH
3251
- repo: https://github.com/koalaman/shellcheck-precommit
3352
rev: v0.11.0
3453
hooks:
3554
- id: shellcheck
3655
exclude: contrib
56+
priority: 30
3757

3858
## PYTHON — SDK (prowler/, tests/, dashboard/, util/, scripts/)
3959
- repo: https://github.com/myint/autoflake
@@ -48,6 +68,7 @@ repos:
4868
"--remove-all-unused-imports",
4969
"--remove-unused-variable",
5070
]
71+
priority: 20
5172

5273
- repo: https://github.com/pycqa/isort
5374
rev: 8.0.1
@@ -56,13 +77,15 @@ repos:
5677
name: "SDK - isort"
5778
files: { glob: ["{prowler,tests,dashboard,util,scripts}/**/*.py"] }
5879
args: ["--profile", "black"]
80+
priority: 20
5981

6082
- repo: https://github.com/psf/black
6183
rev: 26.3.1
6284
hooks:
6385
- id: black
6486
name: "SDK - black"
6587
files: { glob: ["{prowler,tests,dashboard,util,scripts}/**/*.py"] }
88+
priority: 20
6689

6790
- repo: https://github.com/pycqa/flake8
6891
rev: 7.3.0
@@ -71,6 +94,7 @@ repos:
7194
name: "SDK - flake8"
7295
files: { glob: ["{prowler,tests,dashboard,util,scripts}/**/*.py"] }
7396
args: ["--ignore=E266,W503,E203,E501,W605"]
97+
priority: 30
7498

7599
## PYTHON — API + MCP Server (ruff)
76100
- repo: https://github.com/astral-sh/ruff-pre-commit
@@ -80,9 +104,11 @@ repos:
80104
name: "API + MCP - ruff check"
81105
files: { glob: ["{api,mcp_server}/**/*.py"] }
82106
args: ["--fix"]
107+
priority: 30
83108
- id: ruff-format
84109
name: "API + MCP - ruff format"
85110
files: { glob: ["{api,mcp_server}/**/*.py"] }
111+
priority: 20
86112

87113
## PYTHON — Poetry
88114
- repo: https://github.com/python-poetry/poetry
@@ -93,31 +119,36 @@ repos:
93119
args: ["--directory=./api"]
94120
files: { glob: ["api/{pyproject.toml,poetry.lock}"] }
95121
pass_filenames: false
122+
priority: 50
96123

97124
- id: poetry-lock
98125
name: API - poetry-lock
99126
args: ["--directory=./api"]
100127
files: { glob: ["api/{pyproject.toml,poetry.lock}"] }
101128
pass_filenames: false
129+
priority: 50
102130

103131
- id: poetry-check
104132
name: SDK - poetry-check
105133
args: ["--directory=./"]
106134
files: { glob: ["{pyproject.toml,poetry.lock}"] }
107135
pass_filenames: false
136+
priority: 50
108137

109138
- id: poetry-lock
110139
name: SDK - poetry-lock
111140
args: ["--directory=./"]
112141
files: { glob: ["{pyproject.toml,poetry.lock}"] }
113142
pass_filenames: false
143+
priority: 50
114144

115145
## CONTAINERS
116146
- repo: https://github.com/hadolint/hadolint
117147
rev: v2.14.0
118148
hooks:
119149
- id: hadolint
120150
args: ["--ignore=DL3013"]
151+
priority: 30
121152

122153
## LOCAL HOOKS
123154
- repo: local
@@ -128,6 +159,7 @@ repos:
128159
language: system
129160
types: [python]
130161
files: { glob: ["{prowler,tests,dashboard,util,scripts}/**/*.py"] }
162+
priority: 30
131163

132164
- id: trufflehog
133165
name: TruffleHog
@@ -138,6 +170,7 @@ repos:
138170
language: system
139171
pass_filenames: false
140172
stages: ["pre-commit", "pre-push"]
173+
priority: 40
141174

142175
- id: bandit
143176
name: bandit
@@ -148,6 +181,7 @@ repos:
148181
files: '.*\.py'
149182
exclude:
150183
{ glob: ["{contrib,skills}/**", "**/.venv/**", "**/*_test.py"] }
184+
priority: 40
151185

152186
- id: safety
153187
name: safety
@@ -166,6 +200,7 @@ repos:
166200
".safety-policy.yml",
167201
],
168202
}
203+
priority: 40
169204

170205
- id: vulture
171206
name: vulture
@@ -174,3 +209,4 @@ repos:
174209
language: system
175210
types: [python]
176211
files: '.*\.py'
212+
priority: 40

README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,22 @@ Every AWS provider scan will enqueue an Attack Paths ingestion job automatically
104104

105105
| 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 |
106106
|---|---|---|---|---|---|---|
107-
| AWS | 572 | 83 | 41 | 17 | Official | UI, API, CLI |
108-
| Azure | 165 | 20 | 18 | 13 | Official | UI, API, CLI |
109-
| GCP | 100 | 13 | 15 | 11 | Official | UI, API, CLI |
110-
| Kubernetes | 83 | 7 | 7 | 9 | Official | UI, API, CLI |
111-
| GitHub | 21 | 2 | 1 | 2 | Official | UI, API, CLI |
112-
| M365 | 89 | 9 | 4 | 5 | Official | UI, API, CLI |
113-
| OCI | 48 | 13 | 3 | 10 | Official | UI, API, CLI |
114-
| Alibaba Cloud | 61 | 9 | 3 | 9 | Official | UI, API, CLI |
115-
| Cloudflare | 29 | 2 | 0 | 5 | Official | UI, API, CLI |
107+
| AWS | 595 | 84 | 43 | 17 | Official | UI, API, CLI |
108+
| Azure | 167 | 22 | 19 | 16 | Official | UI, API, CLI |
109+
| GCP | 102 | 18 | 17 | 12 | Official | UI, API, CLI |
110+
| Kubernetes | 83 | 7 | 7 | 11 | Official | UI, API, CLI |
111+
| GitHub | 24 | 3 | 1 | 5 | Official | UI, API, CLI |
112+
| M365 | 101 | 10 | 4 | 10 | Official | UI, API, CLI |
113+
| OCI | 51 | 14 | 4 | 10 | Official | UI, API, CLI |
114+
| Alibaba Cloud | 61 | 9 | 4 | 9 | Official | UI, API, CLI |
115+
| Cloudflare | 29 | 3 | 0 | 5 | Official | UI, API, CLI |
116116
| IaC | [See `trivy` docs.](https://trivy.dev/latest/docs/coverage/iac/) | N/A | N/A | N/A | Official | UI, API, CLI |
117117
| MongoDB Atlas | 10 | 3 | 0 | 8 | Official | UI, API, CLI |
118118
| LLM | [See `promptfoo` docs.](https://www.promptfoo.dev/docs/red-team/plugins/) | N/A | N/A | N/A | Official | CLI |
119119
| Image | N/A | N/A | N/A | N/A | Official | CLI, API |
120-
| Google Workspace | 1 | 1 | 0 | 1 | Official | CLI |
121-
| OpenStack | 27 | 4 | 0 | 8 | Official | UI, API, CLI |
122-
| Vercel | 30 | 6 | 0 | 5 | Official | CLI |
120+
| Google Workspace | 25 | 4 | 2 | 4 | Official | CLI |
121+
| OpenStack | 34 | 5 | 0 | 9 | Official | UI, API, CLI |
122+
| Vercel | 26 | 6 | 0 | 5 | Official | CLI |
123123
| NHN | 6 | 2 | 1 | 0 | Unofficial | CLI |
124124

125125
> [!Note]

api/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
All notable changes to the **Prowler API** are documented in this file.
44

5+
## [1.27.0] (Prowler UNRELEASED)
6+
7+
### 🚀 Added
8+
9+
- New `scan-reset-ephemeral-resources` post-scan task zeroes `failed_findings_count` for resources missing from the latest full-scope scan, keeping ephemeral resources from polluting the Resources page sort [(#10929)](https://github.com/prowler-cloud/prowler/pull/10929)
10+
11+
---
12+
513
## [1.26.1] (Prowler v5.25.1)
614

715
### 🐞 Fixed

api/src/backend/api/models.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,10 +595,40 @@ class Scan(RowLevelSecurityProtectedModel):
595595
objects = ActiveProviderManager()
596596
all_objects = models.Manager()
597597

598+
_SCOPING_SCANNER_ARG_KEYS_CACHE: tuple[str, ...] | None = None
599+
600+
@classmethod
601+
def get_scoping_scanner_arg_keys(cls) -> tuple[str, ...]:
602+
"""Return the scanner_args keys that mark a scan as scoped.
603+
604+
Derived from ``prowler.lib.scan.scan.Scan.__init__`` so the API stays
605+
in sync with whatever the SDK actually accepts as filters. Cached at
606+
class level — the signature is stable for the process lifetime.
607+
"""
608+
if cls._SCOPING_SCANNER_ARG_KEYS_CACHE is None:
609+
import inspect
610+
611+
from prowler.lib.scan.scan import Scan as ProwlerScan
612+
613+
params = inspect.signature(ProwlerScan.__init__).parameters
614+
cls._SCOPING_SCANNER_ARG_KEYS_CACHE = tuple(
615+
name for name in params if name not in ("self", "provider")
616+
)
617+
return cls._SCOPING_SCANNER_ARG_KEYS_CACHE
618+
598619
class TriggerChoices(models.TextChoices):
599620
SCHEDULED = "scheduled", _("Scheduled")
600621
MANUAL = "manual", _("Manual")
601622

623+
# Trigger values for scans that ran the SDK end-to-end. Imported scans (or
624+
# any future trigger) are intentionally NOT in this set — they may carry
625+
# only a partial slice of resources, so post-scan logic that depends on a
626+
# full-scope sweep (e.g. resetting ephemeral resource findings) must skip
627+
# them by default.
628+
LIVE_SCAN_TRIGGERS = frozenset(
629+
(TriggerChoices.SCHEDULED.value, TriggerChoices.MANUAL.value)
630+
)
631+
602632
id = models.UUIDField(primary_key=True, default=uuid7, editable=False)
603633
name = models.CharField(
604634
blank=True, null=True, max_length=100, validators=[MinLengthValidator(3)]
@@ -681,6 +711,24 @@ class Meta(RowLevelSecurityProtectedModel.Meta):
681711
class JSONAPIMeta:
682712
resource_name = "scans"
683713

714+
def is_full_scope(self) -> bool:
715+
"""Return True if this scan ran with no scoping filters at all.
716+
717+
Used to gate post-scan operations (such as resetting the
718+
failed_findings_count of resources missing from the scan) that are only
719+
safe when the scan covered every check, service, and category. Imported
720+
scans are NOT full-scope by definition — they may carry only a partial
721+
slice of resources, so they're rejected via ``trigger`` even before the
722+
scanner_args check.
723+
"""
724+
if self.trigger not in self.LIVE_SCAN_TRIGGERS:
725+
return False
726+
scanner_args = self.scanner_args or {}
727+
for key in self.get_scoping_scanner_arg_keys():
728+
if scanner_args.get(key):
729+
return False
730+
return True
731+
684732

685733
class AttackPathsScan(RowLevelSecurityProtectedModel):
686734
objects = ActiveProviderManager()

0 commit comments

Comments
 (0)