Compare commits

...

1094 Commits

Author SHA1 Message Date
sumit_chaturvedi
95cb36e09b refactor(e2e): reuse login helper and update test cases 2025-06-27 10:26:20 +05:30
sumit_chaturvedi
1880b97687 chore(UI): fix the env variable 2025-06-25 22:44:12 +05:30
sumit_chaturvedi
ae1219dac8 refactor(e2e): increase timeout to avoid test failure 2025-06-25 17:56:43 +05:30
sumit_chaturvedi
dc9d5b0bcd test(e2e): implement login flow tests with valid and invalid credentials 2025-06-25 15:24:26 +05:30
sumit_chaturvedi
498a38634c refactor(e2e): removed sign-up redirection 2025-06-25 14:50:36 +05:30
sumit_chaturvedi
5e8385607a chore(e2e): updated page load timing 2025-06-25 14:27:29 +05:30
sumit_chaturvedi
60b090284a refactor(e2e): remove global-setup file — Docker lifecycle handled in CI 2025-06-25 12:39:59 +05:30
sumit_chaturvedi
6c3ceda58a chore(e2e): update execSync command to use 'docker compose' format 2025-06-25 11:04:08 +05:30
sumit_chaturvedi
6080343eaf chore(e2e): add temporary AUTH_SECRET for Playwright E2E test runs 2025-06-24 19:36:05 +05:30
sumit_chaturvedi
b081027f5e chore(e2e): add GitHub Actions workflow for Playwright UI E2E tests 2025-06-24 16:41:08 +05:30
sumit_chaturvedi
a5c7cfc752 docs: changelog update 2025-06-23 15:37:20 +05:30
sumit_chaturvedi
d68a798d25 feat: add basic Playwright tests for login and findings page 2025-06-23 15:17:04 +05:30
sumit_chaturvedi
bd0749daa8 feat(ui): add Playwright setup with basic configuration for E2E testing in Next.js 2025-06-23 10:56:57 +05:30
Víctor Fernández Poyatos
223aab8ece chore(API): skip safety vulnerabilities related to asteval (#8076) 2025-06-20 14:28:23 +02:00
César Arroba
3ec57340a0 chore(gha): check changelog when label is added or deleted (#8071) 2025-06-20 16:35:19 +05:45
Pablo Lara
80d73cc05b feat: integrate Google Tag Manager manually to avoid ORB blocking (#8070) 2025-06-20 12:47:17 +02:00
César Arroba
94f02df11e chore(gha): check changelog changes on pull request (#7991)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-06-19 14:51:59 +05:45
Pepe Fagoaga
c454ceb296 fix(changelog): Add missing entries (#8066) 2025-06-19 14:12:39 +05:45
Pepe Fagoaga
76ec13a1d6 chore(ocsf): remove version number and point to the latest (#8064) 2025-06-19 13:33:28 +05:45
Pepe Fagoaga
783b6ea982 chore(api): clean up old files (#8051) 2025-06-19 11:57:48 +05:45
Alejandro Bailo
6b7b700a98 feat: filters relationships in findings and scans page (#8046)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-06-18 17:19:41 +02:00
César Arroba
b3f2a1c532 chore(ui): add NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID variable on Dockerfile (#8061) 2025-06-18 16:31:55 +02:00
Sergio Garcia
c4e1bd3ed2 fix: add missing changelog compliance timestamps (#8060) 2025-06-18 16:28:48 +02:00
Sergio Garcia
d0d4e0d483 fix(compliance): use unified timestampt for all requirements (#8052) 2025-06-18 22:00:51 +08:00
Pablo Lara
14a9f0e765 feat: add Google Tag Manager integration (#8058) 2025-06-18 15:47:48 +02:00
Rubén De la Torre Vico
b572575c8d feat(azure): add new check iam_role_user_access_admin_restricted (#8040)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-06-18 21:24:23 +08:00
Rubén De la Torre Vico
a626e41162 docs: add provider-specific developer guide sections (#7996)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-06-18 21:20:33 +08:00
Hugo Pereira Brito
22343faa1e feat(storage): add new check storage_default_to_entra_authorization_enabled (#7981) 2025-06-18 21:16:07 +08:00
Hugo Pereira Brito
c5b37887ef chore: add pr to changelog (#8054) 2025-06-18 14:32:21 +02:00
Rubén De la Torre Vico
f9aed36d0b feat(azure): add new check databricks_workspace_cmk_encryption_enabled (#8017) 2025-06-18 18:36:37 +08:00
Hugo Pereira Brito
facc0627d7 feat(azure): add new check storage_geo_redundant_enabled (#7980)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-18 18:10:02 +08:00
Rubén De la Torre Vico
76f0d890e9 feat(azure): add Databricks service and check for workspace VNet injection (#8008)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-06-18 17:38:09 +08:00
Hugo Pereira Brito
7de7122c3b fix(m365): avoid user requests in setup_identity app context and user auth log enhancement (#8043) 2025-06-18 11:27:11 +02:00
Hugo Pereira Brito
1b73ab2fe4 feat(storage): add new check storage_cross_tenant_replication_disabled (#7977)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-18 15:54:13 +08:00
Rubén De la Torre Vico
cc8f6131e6 feat(azure): add new check storage_blob_versioning_is_enabled (#7927)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-18 15:46:38 +08:00
Andoni Alonso
dfd5c9aee7 feat(aws): add check to ensure Codebuild Github projects are only use allowed Github orgs (#7595)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-18 00:17:18 +08:00
dependabot[bot]
3986bf3f42 chore(deps): bump asteval from 1.0.5 to 1.0.6 (#8049)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-18 00:11:18 +08:00
Sergio Garcia
c45ef1e286 chore(deps): update requests dependency (#8048) 2025-06-18 00:04:09 +08:00
dependabot[bot]
8d8f498dc2 chore(deps): bump asteval from 1.0.5 to 1.0.6 (#8047)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 23:32:13 +08:00
Sergio Garcia
c4bd9122d4 feat(IaC): PoC for IaC Security Scanner (#7852)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-06-17 23:23:25 +08:00
dependabot[bot]
644cdc81b9 chore(deps): bump requests from 2.32.3 to 2.32.4 in /api (#7986)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 16:46:29 +02:00
Pablo Lara
e5584f21b3 feat: make user and password fields optional but mutually required fo… (#8044) 2025-06-17 14:46:00 +02:00
Rubén De la Torre Vico
b868d39bef chore(deps): add pre-commit as a dev dependency (#8042) 2025-06-17 18:54:32 +08:00
Alejandro Bailo
ef9809f61f fix: correct parenthesis around the render condition (#8041) 2025-06-17 12:22:17 +02:00
Alejandro Bailo
9a04ca3611 feat: touching up compliances views (#8022)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-06-17 11:23:14 +02:00
Pedro Martín
1c9b3a1394 feat(m365): add ISO 27001 2022 compliance framework (#7985)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-17 17:04:36 +08:00
dependabot[bot]
5ee7bd6459 chore(deps): bump protobuf from 6.30.2 to 6.31.1 (#8037)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-17 16:31:04 +08:00
Chandrapal Badshah
05d2b86ba8 feat(lighthouse): update NextJS logic to work with latest APIs (#8033)
Co-authored-by: Chandrapal Badshah <12944530+Chan9390@users.noreply.github.com>
2025-06-17 10:25:37 +02:00
Andoni Alonso
84c30af6f8 chore(sentry): handle exceptions ignores not based in ClassNames (#8034) 2025-06-17 09:42:24 +02:00
dcanotrad
e8a829b75e docs(dev-guide): improve quality redrive (#7718)
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <rubendltv22@gmail.com>
2025-06-17 09:28:22 +02:00
Sergio Garcia
a0d169470d chore(metadata): add validator for ResourceType (#8035) 2025-06-17 00:06:32 +08:00
Rubén De la Torre Vico
1fd6046511 chore: add missing init file to check repository_secret_scanning_enabled (#8029) 2025-06-16 21:31:18 +08:00
Sergio Garcia
524455b0f3 fix(metadata): add missing ResourceType values (#8028)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-06-16 21:30:55 +08:00
Víctor Fernández Poyatos
e6e1e37c1e fix(findings): exclude blank resource types from metadata endpoints (#8027) 2025-06-16 18:19:21 +05:45
Prowler Bot
2914510735 chore(regions_update): Changes in regions for AWS services (#8026)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-06-16 19:00:06 +08:00
Rubén De la Torre Vico
7e43c7797f fix(eks): add EKS to service without subservices (#7959)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-16 16:46:48 +08:00
Rubén De la Torre Vico
6954ef880e fix(azure): add new way to auth against App Insight (#7763) 2025-06-16 16:46:36 +08:00
Chandrapal Badshah
5f5e7015a9 feat(lighthouse): Add django endpoints to store config (#7848)
Co-authored-by: Chandrapal Badshah <12944530+Chan9390@users.noreply.github.com>
Co-authored-by: Adrián Jesús Peña Rodríguez <adrianjpr@gmail.com>
Co-authored-by: Víctor Fernández Poyatos <vicferpoy@gmail.com>
2025-06-16 10:11:57 +02:00
Andoni Alonso
bfafa518b1 feat(aws): avoid bypassing IAM check using wildcards (#7708) 2025-06-16 07:42:01 +02:00
Hugo Pereira Brito
e34e59ff2d fix(network): allow 0 as compliant value (#7926)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-13 19:50:19 +08:00
Daniel Barranquero
7f80d2db46 fix(app): change api call for ftps_state (#7923) 2025-06-13 19:28:55 +08:00
sumit-tft
4a2a3921da feat(UI): Add Provider detail component in Findings, Scan details (#7968)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-06-13 12:17:18 +02:00
Pedro Martín
e26b2e6527 feat(api): handle MitreAttack compliance requirements (#7987)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-06-13 10:26:34 +02:00
Mitchell @ Securemetrics
954814c1d7 feat(contrib): add PowerBI integration (#7826)
Co-authored-by: Pedro Martín <pedromarting3@gmail.com>
2025-06-13 09:55:07 +02:00
Andoni Alonso
113224cbd9 chore: update CHANGELOG (#8015) 2025-06-13 15:38:56 +08:00
Andoni Alonso
f5f1fce779 fix(iam): check always if root credentials are present (#7967) 2025-06-12 17:48:09 +02:00
Pepe Fagoaga
0ba9383202 chore(changelog): make all consistent (#8010)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-06-12 20:09:01 +05:45
Adrián Jesús Peña Rodríguez
8e9a9797c7 fix(export): add name sanitization (#8007) 2025-06-12 20:02:18 +05:45
Pablo Lara
2b4e6bffae chore: update package-lock after lighthouse was merged (#8011) 2025-06-12 15:32:58 +02:00
Chandrapal Badshah
74f7a86c2b feat(lighthouse): Add chat interface (#7878)
Co-authored-by: Chandrapal Badshah <12944530+Chan9390@users.noreply.github.com>
2025-06-12 15:19:41 +02:00
Pablo Lara
e218435b2f fix: improve error handling in UpdateViaCredentialsForm with early re… (#7988) 2025-06-12 11:39:49 +02:00
Prowler Bot
5ec34ad5e7 chore(regions_update): Changes in regions for AWS services (#7973)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-06-12 17:24:15 +08:00
Pedro Martín
c4b0859efd fix(dashboard): handle account uids with 0 at start and end (#7955)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-12 17:21:52 +08:00
Pedro Martín
1241a490f9 fix(kubernetes): change object type to set for apiserver check (#7952) 2025-06-12 17:02:48 +08:00
Pedro Martín
4ec498a612 fix(k8s): remove typo for PCI 4.0 compliance framework (#7971) 2025-06-12 16:41:58 +08:00
Pedro Martín
119c5e80a9 feat(gcp): add NIS 2 compliance framework (#7912)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-06-12 16:40:33 +08:00
sumit-tft
d393bc48a2 fix(PRWLR-7380): button nesting hydration error (#7998) 2025-06-12 10:02:20 +02:00
Daniel Barranquero
e09e3855b1 fix(gcp): remove azure video from gcp docs (#8001) 2025-06-12 09:54:25 +02:00
Alejandro Bailo
8751615faa feat: MittreAtack compliance detailed view (#8002) 2025-06-12 09:27:47 +02:00
Prowler Bot
e7c17ab0b3 chore(regions_update): Changes in regions for AWS services (#7898)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-06-12 15:14:28 +08:00
dependabot[bot]
f05d3eb334 chore(deps): bump trufflesecurity/trufflehog from 3.88.26 to 3.88.35 (#7896)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 15:14:02 +08:00
dependabot[bot]
cf449d4607 chore(deps): bump aws-actions/configure-aws-credentials from 4.1.0 to 4.2.1 (#7895)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 15:13:35 +08:00
dependabot[bot]
b338ac9add chore(deps): bump codecov/codecov-action from 5.4.2 to 5.4.3 (#7894)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 15:13:12 +08:00
dependabot[bot]
366d2b392a chore(deps): bump docker/build-push-action from 6.16.0 to 6.18.0 (#7893)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 15:12:52 +08:00
dependabot[bot]
41fc536b44 chore(deps): bump github/codeql-action from 3.28.16 to 3.28.18 (#7892)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 15:12:28 +08:00
Adrián Jesús Peña Rodríguez
e042445ecf fix(migration): create site stuff before socialaccount (#7999) 2025-06-11 13:34:21 +02:00
Víctor Fernández Poyatos
c17129afe3 revert: RLS transactions handling and DB custom backend (#7994) 2025-06-11 14:47:10 +05:45
Alejandro Bailo
4876d8435c feat: generic compliance detailed view (#7990) 2025-06-11 09:40:53 +02:00
Pedro Martín
1bd0d774e5 feat(mutelist): make validate_mutelist method static (#7811) 2025-06-11 11:33:49 +05:45
Alejandro Bailo
c119cece89 feat: ThreatScore compliance detailed view (#7979) 2025-06-10 10:43:27 +02:00
Adrián Jesús Peña Rodríguez
e24b211d22 feat(sso): add sso with saml to API (#7822) 2025-06-10 10:17:54 +02:00
Hugo Pereira Brito
c589c95727 feat(storage): add new check storage_account_key_access_disabled (#7974)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-06-10 08:23:09 +02:00
Hugo Pereira Brito
7e4f1a73bf feat(storage): add new check storage_ensure_file_shares_soft_delete_is_enabled (#7966) 2025-06-10 08:09:11 +02:00
Pepe Fagoaga
4d00aece45 chore(changelog): move entry for their version (#7969) 2025-06-09 21:50:13 +05:45
Hugo Pereira Brito
49aaf011aa fix(parser): add GitHub provider to prowler -h usage section (#7906) 2025-06-09 17:47:29 +02:00
Adrián Jesús Peña Rodríguez
898934c7f8 chore: update django version (#7984) 2025-06-09 17:33:16 +02:00
Pepe Fagoaga
81c4b5a9c1 chore(api): Delete old docker compose file (#7982) 2025-06-09 21:01:52 +05:45
Pepe Fagoaga
fe31656ffe fix(k8s): return a session if using kubeconfig_content (#7953) 2025-06-09 19:11:59 +05:45
Hugo Pereira Brito
359059dee6 fix(docs): add Organization.Read.All to M365 provider requirements (#7961) 2025-06-09 12:11:14 +02:00
Alejandro Bailo
2eaa37921d feat: KISA detailed view (#7965) 2025-06-09 09:29:34 +02:00
Pablo Lara
3a99909b75 chore: align Next.js version to 14.2.29 across Prowler and Cloud (#7962) 2025-06-06 13:54:42 +02:00
Pablo Lara
2ecd9ad2c5 docs: update changelog (#7960) 2025-06-06 13:17:38 +02:00
Alejandro Bailo
50dc396aa3 feat: scan id filter drowpdown (#7949)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-06-06 12:38:14 +02:00
Andoni Alonso
acf333493a chore(api): reorder docker layers to speed up build times (#7957) 2025-06-06 10:42:14 +02:00
Pedro Martín
bd6272f5a7 feat(docs): add information about tenants and read-only roles (#7956) 2025-06-06 10:14:33 +02:00
Pepe Fagoaga
8c95e1efaf chore: update API changelog for v5.7.3 (#7948) 2025-06-05 15:54:36 +02:00
Hugo Pereira Brito
845a0aa0d5 fix(changelog): add entries for password encryption in v5.7.3 (#7939)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-06-05 14:23:12 +02:00
Hugo Pereira Brito
75a11be9e6 fix(docs): add final permission assignments example (#7943) 2025-06-05 18:07:43 +05:45
Hugo Pereira Brito
a778d005b6 fix(docs): add mfa warning for users (#7924)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-06-05 17:55:27 +05:45
Pedro Martín
1281f4ec5e chore(changelog): update following the correct format (#7908) 2025-06-05 17:52:36 +05:45
Víctor Fernández Poyatos
6332427e5e fix(compliance): add manual status to requirements (#7938) 2025-06-05 10:54:51 +02:00
Alejandro Bailo
d89df83904 fix: Improve the perfomance removing regions heatmap (#7934) 2025-06-05 08:13:47 +02:00
Víctor Fernández Poyatos
be420afebc feat(database): handle already closed connections (#7935) 2025-06-04 16:09:36 +02:00
Adrián Jesús Peña Rodríguez
fb914a2c90 revert: remove get_with_retry (#7932) 2025-06-04 15:01:47 +02:00
Pablo Lara
4ac3cfc33d docs: update changelog (#7931) 2025-06-04 13:54:25 +02:00
Alejandro Bailo
c74360ab63 fix: clear filters sync (#7928) 2025-06-04 13:32:52 +02:00
Alejandro Bailo
4dc4d82d42 feat: aws-well-architected compliance detailed view (#7925) 2025-06-04 12:26:27 +02:00
Víctor Fernández Poyatos
6e7a32cb51 revert(views): calling order to initial view method (#7921) 2025-06-03 16:38:00 +02:00
Alejandro Bailo
49e501c4be feat: CIS compliance detail view (#7913)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-06-03 15:47:46 +02:00
Víctor Fernández Poyatos
9ee78fe65f fix(views): calling order to initial view method (#7918) 2025-06-03 13:34:44 +02:00
Víctor Fernández Poyatos
7a0549d39c fix(rls): Apply persistent RLS transactions (#7916) 2025-06-03 13:10:41 +02:00
Alejandro Bailo
3e8c86d880 feat: ISO compliance detail view (#7897)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-06-03 09:20:52 +02:00
Pablo Lara
e34c18757d fix: Fix named export for addCredentialsServiceAccountFormSchema (#7909) 2025-06-03 08:33:24 +02:00
Alejandro Bailo
5c1a47d108 feat: compliance detail view + ENS (#7853)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-06-02 18:20:22 +02:00
Víctor Fernández Poyatos
59c51d5a4a feat(compliance): Rework compliance overviews (#7877) 2025-06-02 17:06:24 +02:00
Pedro Martín
66aa67f636 feat(changelog): update version with fixes (#7904)
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-06-02 12:32:45 +02:00
Pablo Lara
bdda377482 docs: update the changelog (#7901) 2025-06-02 11:49:04 +02:00
Hugo Pereira Brito
aa11ed70bd chore(docs): replace old permission images (#7900) 2025-06-02 11:47:11 +02:00
Adrián Jesús Peña Rodríguez
0580dca6cf fix: set user_id for tenant operations (#7890)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-06-02 11:06:49 +02:00
Pablo Lara
678ef0ab5a feat(providers): setup workflow to support new GCP credential method (#7872) 2025-06-02 10:23:39 +02:00
César Arroba
4888c27713 chore: fix commit sha when a pr is merged (#7889) 2025-05-30 17:40:57 +05:45
Hugo Pereira Brito
b256c10622 chore: replace Directory.Read.All permission to Domain.Read.All for Azure (#7888) 2025-05-30 10:24:49 +02:00
Adrián Jesús Peña Rodríguez
878e4e0bbc fix: add new get method to avoid race conditions when creating async tasks (#7876)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-05-30 10:07:32 +02:00
Hugo Pereira Brito
6c3653c483 fix(docs): remove warning of encrypted password for cloud (#7886) 2025-05-30 12:01:32 +04:00
Daniel Barranquero
71ac703e6f fix(api): connection correctly reflected (#7831)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-05-29 20:23:15 +05:45
Sergio Garcia
a89e3598f2 fix(gcp): test connection by verifying token (#7882) 2025-05-29 13:20:53 +02:00
Alison Vilela
5d043cc929 fix(awslambda): aws service awslambda not working (#7869) 2025-05-29 12:50:23 +05:45
Pepe Fagoaga
921f94ebbf fix(k8s): UID validation for valid context names (#7871) 2025-05-29 12:32:57 +05:45
sumit-tft
48c9ed8a79 fix(ui): increase limit to retrieve more than 10 scan list (#7865) 2025-05-29 07:52:36 +02:00
Hugo Pereira Brito
12987ec9f9 fix(admincenter): service and group visibility (#7870) 2025-05-28 16:48:49 +02:00
Hugo Pereira Brito
40b90ed063 fix(tests): typo in m365 domain test (#7866) 2025-05-28 16:43:58 +02:00
Alejandro Bailo
60314e781f feat: enhance CustomDropdownFilter (#7868) 2025-05-28 16:30:28 +02:00
Harsh Kumar
bc56d48595 feat(dashboard): add client-side search functionality to findings table (#7804)
Co-authored-by: Harsh Kumar <harsh.k@cybersecurist.com>
2025-05-28 11:44:01 +02:00
Pedro Martín
2d71cef3d5 feat(azure): add NIS 2 compliance framework (#7857) 2025-05-28 11:35:40 +02:00
Daniel Barranquero
41f6637497 fix(defender): update defender_ensure_notify_alerts_severity_is_high logic (#7862)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-28 10:32:44 +02:00
Pedro Martín
c2e54bbbcc fix(threatscore): remove compliance name in tests to remove dummy files (#7859)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-28 10:03:20 +02:00
sumit-tft
df8aacd09d fix(ui): Added missing icons (kisa, prowlerThreat) on compliance page (#7860) 2025-05-28 09:51:28 +02:00
Matt Keeler
2dd6be59b9 fix(m365): add compliantDevice grant control support (#7844) 2025-05-28 09:05:00 +02:00
Hugo Pereira Brito
9e8e3eb0e6 fix(m365): update documentation (#7823)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
2025-05-28 08:52:03 +02:00
Sergio Garcia
3728430f8c chore: update README (#7842)
Co-authored-by: Pedro Martín <pedromarting3@gmail.com>
2025-05-27 14:25:37 +02:00
sumit-tft
ea97de7f43 fix(ui): updated to use the correct message when download report clicked (#7758)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-05-27 10:51:08 +02:00
Rubén De la Torre Vico
f254a4bc0d feat(app): split SDK App service calls (#7778) 2025-05-27 09:52:50 +02:00
Pedro Martín
66acfd8691 feat(aws): add NIS2 compliance framework (#7839) 2025-05-27 09:35:57 +02:00
Matt Keeler
02ca82004f fix(typo): minor language updates (#7843) 2025-05-27 09:26:51 +02:00
Rubén De la Torre Vico
60b5a79b27 fix(vpc): change the ServiceName from EC2 to VPC (#7840) 2025-05-26 17:52:59 +02:00
Sergio Garcia
be1e3e942b feat(api): support GCP Service Account key (#7824)
Co-authored-by: Sergio Garcia <38561120+garcitm@users.noreply.github.com>
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-05-26 15:42:39 +02:00
Sergio Garcia
3658e85cfc chore(github): add Branch class (#7838) 2025-05-26 14:34:44 +02:00
Adrián Jesús Peña Rodríguez
15e4d1acce refactor(reports): change API response message when tasks are running (#7837) 2025-05-26 12:20:05 +02:00
Andoni Alonso
44afd9ed31 fix: repository repository_dependency_scanning_enabled check logic (#7834) 2025-05-26 10:44:19 +02:00
Andoni Alonso
4f099c5663 refactor(github): use owner instead of repository in findings attributes (#7833) 2025-05-26 10:40:41 +02:00
Andoni Alonso
eaec683eb9 feat(repositoy): add new check repository_inactive_not_archived (#7786)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-26 10:39:09 +02:00
Adrián Jesús Peña Rodríguez
50bcd828e9 fix(reports): change invalid search term for tasks (#7830) 2025-05-26 10:24:11 +02:00
Alejandro Bailo
91545e409e feat: change tenant name in /profile page (#7829)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-05-23 14:45:28 +02:00
Alejandro Bailo
33031d2c96 feat: implement provider UID extraction and mapping in scans pages (#7820)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-05-23 13:42:35 +02:00
Hugo Pereira Brito
1b42dda817 fix(formSchemas): encrypted password typo (#7828) 2025-05-23 12:52:17 +02:00
Hugo Pereira Brito
f726d964a8 fix(m365): remove last encrypted password appearances (#7825) 2025-05-23 12:27:57 +02:00
Hugo Pereira Brito
36aaec8a55 chore(m365powershell): manage encryption from plaintext password (#7784)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
2025-05-22 17:36:58 +02:00
Andoni Alonso
99164ce93e feat(repository): add new check repository_default_branch_requires_signed_commits (#7777)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-22 12:45:13 +02:00
Andoni Alonso
7ebc5d3c31 feat(repository): add new check repository_dependency_scanning_enabled (#7771)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-22 12:22:59 +02:00
Andoni Alonso
06ff3db8af feat(repository): add new check repository_secret_scanning_enabled (#7759)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-22 11:23:42 +02:00
Alejandro Bailo
c44ea3943e feat: resources in finding tables (#7813) 2025-05-22 08:58:25 +02:00
Andoni Alonso
d036e0054b feat(repository): add new check repository_default_branch_requires_codeowners_review (#7753)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-21 16:18:55 +02:00
Pedro Martín
f72eb7e212 fix(files): remove empty files (#7819) 2025-05-21 16:15:04 +02:00
Andoni Alonso
62dcbc2961 feat(repository): add new check repository_has_codeowners_file (#7752) 2025-05-21 15:28:30 +02:00
Hugo Pereira Brito
dddec4c688 fix(m365): add powershell.close() to msgraph services (#7816) 2025-05-21 15:13:03 +02:00
Sergio Garcia
6d00554082 chore(readme): add Prowler Hub link (#7814)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-05-21 17:46:54 +05:45
Pedro Martín
65d3fcee4c feat(prowler-threatscore): add Weight field inside req (#7795)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-21 12:57:10 +02:00
Pedro Martín
16cd0e4661 feat(prowler_threatscore): add a level for accordion in dashboard (#7739)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-21 12:46:47 +02:00
Hugo Pereira Brito
6e184dae93 fix(admincenter): admincenter_users_admins_reduced_license_footprint logic (#7779)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-21 12:46:35 +02:00
Pablo Lara
118f3d163d docs: update changelog UI (#7808) 2025-05-21 12:39:48 +02:00
Pedro Martín
7d84d67935 feat(gcp): add CIS 4.0 compliance framework (#7785) 2025-05-21 12:38:34 +02:00
Víctor Fernández Poyatos
1c1c58c975 feat(findings): Add new index for finding UID lookup (#7800) 2025-05-21 11:56:54 +02:00
Andoni Alonso
31ea672c61 fix: move changes to release 5.8 (#7801) 2025-05-21 11:45:54 +02:00
Toni de la Fuente
7016779b8e chore(README): update README.md (#7799) 2025-05-21 11:31:23 +02:00
Pedro Martín
4e958fdf39 feat(kubernetes): add CIS 1.11 compliance framework (#7790)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-21 11:09:47 +02:00
Pedro Martín
c6259b6c75 fix(dashboard): remove typo from subscribe cards (#7792) 2025-05-21 11:08:52 +02:00
Sergio Garcia
021e243ada feat(kubernetes): support HTTPS_PROXY and K8S_SKIP_TLS_VERIFY (#7720) 2025-05-21 10:49:18 +02:00
Alejandro Bailo
acdf420941 feat: profile page (#7780)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-05-21 10:47:32 +02:00
Hugo Pereira Brito
4e84507130 feat(entra): add new check entra_users_mfa_capable (#7734)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-05-21 10:31:56 +02:00
Prowler Bot
2a61610fec chore(regions_update): Changes in regions for AWS services (#7774)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-05-21 10:29:08 +02:00
Daniel Barranquero
9b127eba93 feat(admincenter): add new check admincenter_external_calendar_sharing_disabled (#7733)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-05-21 09:14:45 +02:00
Hugo Pereira Brito
1a89d65516 fix(m365powershell): add sanitize to test_credentials (#7761)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-05-21 08:49:04 +02:00
Daniel Barranquero
84749df708 feat(admincenter): add new check admincenter_organization_customer_lockbox_enabled (#7732)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-05-21 08:48:36 +02:00
Pepe Fagoaga
6f7cd85a18 chore(backport): create label on minor release (#7791) 2025-05-21 12:14:30 +05:45
Alejandro Bailo
ad39061e1a fix: retrieve more than 10 providers (#7793) 2025-05-21 08:07:43 +02:00
Pablo Lara
615bacccaf chore: tweak some wording for consistency (#7794) 2025-05-21 07:59:53 +02:00
Prowler Bot
b3a2479fab chore(release): Bump version to v5.8.0 (#7788)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-05-20 22:27:21 +05:45
sumit-tft
871c877a33 fix: AWS I AM role validation when field is empty (#7787)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-05-20 11:25:40 +02:00
Pedro Martín
7fd58de3bf feat(export): support m365 - prowler threatscore (#7783) 2025-05-19 15:59:42 +02:00
Víctor Fernández Poyatos
40f24b4d70 fix(providers): Fix m365 UID validation (#7781) 2025-05-19 13:34:46 +02:00
Adrián Jesús Peña Rodríguez
d8f80699d4 chore: update api changelog (#7775) 2025-05-19 14:52:32 +05:45
Pablo Lara
f24d0efc77 docs: update changelog (#7773) 2025-05-19 14:34:28 +05:45
Hugo Pereira Brito
a18dd76a5a chore(m365): accept all tenant domains in authentication (#7746) 2025-05-19 13:53:54 +05:45
Pedro Martín
a2362b4bbc fix(cis): rename and add sections and subsections (#7738) 2025-05-19 09:42:04 +02:00
Pedro Martín
e5f1c2b19c feat(aws): add CIS 5.0 compliance framework (#7766) 2025-05-19 09:41:56 +02:00
Pedro Martín
0490ab6944 docs(checks): improve docs related with checks (#7768) 2025-05-19 09:17:14 +02:00
Sergio Garcia
97baa8a1e6 chore(ec2): improve severity logic in SG all ports open check (#7764) 2025-05-16 15:09:48 +02:00
Hugo Pereira Brito
637ebdc3db feat(repository): add new check repository_branch_delete_on_merge_enabled (#6209)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-16 15:03:37 +02:00
Hugo Pereira Brito
451b36093f feat(repository): add new check repository_default_branch_requires_conversation_resolution (#6208)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-16 14:57:15 +02:00
Víctor Fernández Poyatos
beb0457aff fix(findings): Fix latest metadata backfill condition and optimization (#7765) 2025-05-16 14:50:40 +02:00
Víctor Fernández Poyatos
0335ea4e0b fix(findings): Fix latest metadata backfill condition (#7762) 2025-05-16 12:41:12 +02:00
sumit-tft
355abca5a3 fix(ui): Removed the alias if not available in findings detail page (#7751) 2025-05-16 09:02:47 +02:00
sumit-tft
7d69cc4cd9 fix: Updated the high risk section provider icons to make it consistent (#7706) 2025-05-16 08:53:34 +02:00
Hugo Pereira Brito
cdc4b362a4 feat(repository): add new check repository_default_branch_protection_applies_to_admins (#6205)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-16 08:29:45 +02:00
Pablo Lara
6417e6bbba feat: use getFindingsLatest when no scan or date filters are applied (#7756) 2025-05-16 08:18:12 +02:00
Víctor Fernández Poyatos
b810d45d34 feat(findings): Add /findings/latest and /findings/metadata/latest endpoints (#7743) 2025-05-15 16:08:09 +02:00
Ogonna Iwunze
f5a2695c3b fix(check): Add support for condition with restriction on SNS endpoint (#7750)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-15 16:00:00 +02:00
Hugo Pereira Brito
977c788fff feat(repository): add new check repository_default_branch_status_checks_required (#6204)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-15 15:33:49 +02:00
Hugo Pereira Brito
21f8b5dbad fix(check): add missing __init__.py files (#7748) 2025-05-15 11:22:58 +02:00
Hugo Pereira Brito
1c874d1283 feat(repository): add new check repository_default_branch_deletion_disabled (#6200)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-15 08:33:36 +02:00
Hugo Pereira Brito
8f9bdae2b7 feat(repository): add new check repository_default_branch_disallows_force_push (#6197)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-14 16:48:47 +02:00
Pablo Lara
600813fb99 fix: force z-index componet select provider (#7744)
Co-authored-by: StylusFrost <pm.diaz.pena@gmail.com>
2025-05-14 15:19:41 +02:00
Hugo Pereira Brito
5a9ccd60a0 feat(repository): add new check repository_default_branch_requires_linear_history (#6162)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-14 14:37:27 +02:00
Hugo Pereira Brito
beb7a53efe feat(repository): add new check repository_default_branch_protection_enabled (#6161)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-14 13:42:59 +02:00
Hugo Pereira Brito
8431ce42a1 feat(organization): add new check organization_members_mfa_required (#6304)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-14 13:29:08 +02:00
Pablo Lara
c5a9b63970 fix: UID Filter Improvement (#7741)
Co-authored-by: sumit_chaturvedi <chaturvedi.sumit@tftus.com>
2025-05-14 11:36:27 +02:00
Hugo Pereira Brito
a765c1543e feat: add GitHub provider documentation and CIS v1.0.0 compliance (#6116)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-14 10:47:33 +02:00
Hugo Pereira Brito
484a773f5b feat(github): add new service Organization (#6300)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-14 10:40:26 +02:00
Hugo Pereira Brito
9ecf570790 feat(github): add new check repository_code_changes_multi_approval_requirement (#6160)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-14 10:06:52 +02:00
Adrián Jesús Peña Rodríguez
f8c840f283 fix: ensure proper folder creation (#7729) 2025-05-14 10:02:41 +02:00
Pepe Fagoaga
deec9efa97 feat(ui): Add AWS CloudFormation Quick Link to deploy the IAM Role (#7735) 2025-05-14 09:30:01 +02:00
César Arroba
2ee62cca8e chore: add ref on checkout step (#7740) 2025-05-14 12:24:49 +05:45
Hugo Pereira Brito
413b948ca0 feat(github): add GitHub provider (#5787)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-13 15:28:01 +02:00
Pablo Lara
d548e869fa docs: update changelog (#7731) 2025-05-13 13:41:41 +02:00
Sergio Garcia
5c8919372c fix(deps): solve h11 package vulnerability (#7728) 2025-05-13 13:29:22 +02:00
Sergio Garcia
9baac9fd89 fix(deps): solve h11 package vulnerability (#7696) 2025-05-13 13:10:06 +02:00
sumit-tft
252b664e49 fix: Added filter to get connected providers only for banner to show (#7723) 2025-05-13 12:58:23 +02:00
Víctor Fernández Poyatos
496e0f1e0a fix(overviews): Split in n queries to use database indexes for providers (#7725) 2025-05-13 12:34:14 +02:00
dependabot[bot]
80342d612f chore(deps): bump h11 from 0.14.0 to 0.16.0 in /api (#7610)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-13 12:15:14 +02:00
Pablo Lara
02d7eaf268 chore: bump tailwind-merge from 2.5.3 to 3.2.0 (#7722) 2025-05-13 09:27:27 +02:00
Hugo Pereira Brito
1a8df3bf18 fix(defender): enhance policies checks logic (#7666)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-12 17:02:30 +02:00
Pablo Lara
16f2209d3f chore: add M365 to scan page filters (#7704) 2025-05-12 16:20:07 +02:00
Pablo Lara
70e22af550 chore(deps): upgrade recharts from 2.13.0-alpha.4 to 2.15.2 (#7717) 2025-05-12 16:09:54 +02:00
Sergio Garcia
44f26bc0d5 chore(docs): quality redrive to README.md (#7616)
Co-authored-by: dcanotrad <168282715+dcanotrad@users.noreply.github.com>
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-05-12 15:23:14 +02:00
Alejandro Bailo
a19f5d9a9a feat: scan label validation (#7693) 2025-05-12 15:07:44 +02:00
Hugo Pereira Brito
b78f53a722 chore(findings): enhance m365 authentication method information (#7681) 2025-05-12 18:31:32 +05:45
Víctor Fernández Poyatos
c20f07ced4 feat(findings): Improve performance on /findings/metadata, /overviews and filters (#7690) 2025-05-12 14:34:37 +02:00
Hugo Pereira Brito
7c3a53908b chore(compliance): update CIS 4.0 for M365 (#7699)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-12 12:59:50 +02:00
Pepe Fagoaga
ea3c71e22c fix(bump-version): bump for fix also in minors (#7712) 2025-05-12 12:45:17 +02:00
Pedro Martín
40eaa79777 docs(compliance): update compliance page with latest changes (#7694)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-12 12:37:43 +02:00
Prowler Bot
aa8119970e chore(regions_update): Changes in regions for AWS services (#7709)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-05-12 12:37:21 +02:00
Pepe Fagoaga
55fc8cb55b chore(api): Set tab name for API reference (#7713) 2025-05-12 16:16:29 +05:45
Andoni Alonso
abf51eceee fix(typo): rename generate_compliance_json_from_csv_threatscore (#7698) 2025-05-12 12:29:30 +02:00
Pedro Martín
458c51dda3 feat(m365): add Prowler Threatscore (#7692)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-12 12:28:50 +02:00
Sergio Garcia
c8d2a44ab0 feat(kubernetes): allow setting cluster name in in-cluster mode (#7695) 2025-05-12 12:28:04 +02:00
César Arroba
0a71628298 chore: add pass PR url (#7711) 2025-05-12 11:55:00 +02:00
Pablo Lara
60e0040577 fix: move ProviderType to shared types and update usages (#7710) 2025-05-12 11:54:42 +02:00
Alejandro Bailo
5c375d63c5 feat: Horizontal bar chart (#7680) 2025-05-12 11:14:10 +02:00
Adrián Jesús Peña Rodríguez
4d84529ba2 docs: update the download export documentation (#7682) 2025-05-12 14:45:53 +05:45
Prowler Bot
0737d9e8bb chore(release): Bump version to v5.7.0 (#7697)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-05-12 14:41:28 +05:45
Alejandro Bailo
50c5294bc0 feat: accordion component (#7700) 2025-05-12 14:17:40 +05:45
Hugo Pereira Brito
f63e9e5e77 fix(m365): invalid user credentials exception (#7677) 2025-05-12 13:22:13 +05:45
Hugo Pereira Brito
3cab52772c feat(m365): add categories for tenant type e3 and e5 (#7691) 2025-05-09 08:11:44 +02:00
Pepe Fagoaga
81aa035451 chore(changelog): prepare for v5.6.0 (#7688) 2025-05-08 16:49:56 +05:45
Pedro Martín
899f31f1ee fix(prowler_threatscore): fine-tune LevelOfRisk (#7667) 2025-05-08 15:23:31 +05:45
Pedro Martín
e142a9e0f4 fix(dashboard): drop duplicates for rows (#7686) 2025-05-08 14:20:19 +05:45
Sergio Garcia
ed26c2c42c fix(mutelist): properly handle wildcards and regex (#7685) 2025-05-08 12:10:55 +05:45
Pedro Martín
1017510a67 fix(dashboard): remove muted findings on compliance page (#7683) 2025-05-07 13:52:14 -04:00
Adrián Jesús Peña Rodríguez
bfa16607b0 feat: add compliance to API report files and its endpoint (#7653)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-05-07 20:44:58 +05:45
Hugo Pereira Brito
4c874b68f5 fix(metadata): typo in defender_chat_report_policy_configured (#7678) 2025-05-07 09:30:49 -04:00
Sergio Garcia
9458e2bbc4 fix(inspector2): handle error when getting active findings (#7670)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-07 14:39:34 +02:00
Alejandro Bailo
2da7b926ed feat: add DeltaIndicator in new findings (#7676) 2025-05-07 17:59:56 +05:45
Daniel Barranquero
8d4f0ab90a feat(docs): add snapshots to M365 docs (#7673) 2025-05-07 12:19:10 +02:00
Hugo Pereira Brito
83aefc42c1 fix(powershell): remove platform-specific execution (#7675) 2025-05-07 11:44:13 +02:00
Alejandro Bailo
a6489f39fd refactor(finding-detail): remove "Next Scan" field (#7674) 2025-05-07 14:39:35 +05:45
Pablo Lara
15c34952cf docs: update changelog (#7672) 2025-05-07 09:43:17 +02:00
Alejandro Bailo
d002f2f719 feat: diff between providers actions depending on their secrets (#7669) 2025-05-07 09:35:53 +02:00
Sergio Garcia
8530676419 chore(actions): run tests in dependabot updates (#7671) 2025-05-07 11:43:01 +05:45
Pedro Martín
fe5a78e4d4 feat(aws): add static credentials for S3 and SH (#7322) 2025-05-06 17:55:53 +02:00
Pablo Lara
d823b2b9de chore: tweaks for m365 provider (#7668) 2025-05-06 17:06:44 +02:00
Alejandro Bailo
3b17eb024c feat: add delta attribute in findings detail view with and finding id to the url (#7654) 2025-05-06 16:52:15 +02:00
Pablo Lara
87951a8371 feat(compliance): add a button to download the report in compliance card (#7665) 2025-05-06 14:44:02 +02:00
Andoni Alonso
e5ca51d1e7 feat(teams): add new checks teams_security_reporting_enabled and defender_chat_report_policy_configured (#7614)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
Co-authored-by: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com>
2025-05-06 11:30:00 +02:00
Daniel Barranquero
e2fd3fe36e feat(defender): add new check defender_malware_policy_comprehensive_attachments_filter_applied (#7661) 2025-05-06 10:29:36 +02:00
Daniel Barranquero
6b0d73d7f9 feat(exchange): make exchange_user_mailbox_auditing_enabled check configurable (#7662)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-05 15:16:41 -04:00
Hugo Pereira Brito
7eec60f4d9 feat(m365): ensure all forms of mail forwarding are blocked or disabled (#7658)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-05-05 11:21:14 -04:00
Daniel Barranquero
9d788af932 docs(m365): add documentation for m365 (#7622)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-05 16:46:32 +02:00
Pedro Martín
bbc0388d4d chore(changelog): update with latest PR (#7628)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-05 10:40:59 -04:00
Pedro Martín
887db29d96 feat(dashboard): support m365 provider (#7633)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-05-05 10:38:06 -04:00
dependabot[bot]
ae74cab70a chore(deps): bump docker/build-push-action from 6.15.0 to 6.16.0 (#7650)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 09:58:38 -04:00
Prowler Bot
e6d48c1fa4 chore(regions_update): Changes in regions for AWS services (#7657)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-05-05 09:56:16 -04:00
dependabot[bot]
d5ab72a97c chore(deps): bump github/codeql-action from 3.28.15 to 3.28.16 (#7649)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 09:54:34 -04:00
dependabot[bot]
473631f83b chore(deps): bump trufflesecurity/trufflehog from 3.88.23 to 3.88.26 (#7648)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 09:54:16 -04:00
drewadwade
a580b1ee04 fix(azure): CIS v2.0 4.4.1 Uses Wrong Check (#7656)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2025-05-05 15:53:55 +02:00
dependabot[bot]
844dd5ba95 chore(deps): bump actions/setup-python from 5.5.0 to 5.6.0 (#7647)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-05 09:53:40 -04:00
sumit-tft
44f8e4c488 feat(ui): Page size for datatables (#7634) 2025-05-05 15:42:06 +02:00
Alejandro Bailo
180eb61fee fix: error about page number persistence when filters change (#7655) 2025-05-05 12:23:04 +02:00
Andoni Alonso
9828824b73 chore(sentry): attach stacktrace to logging events (#7598)
Co-authored-by: Adrián Jesús Peña Rodríguez <adrianjpr@gmail.com>
2025-05-05 10:38:57 +02:00
Daniel Barranquero
c938a25693 feat(exchange): add new check exchange_organization_modern_authentication_enabled (#7636)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-02 12:44:39 +02:00
Daniel Barranquero
cccd69f27c feat(exchange): add new check exchange_roles_assignment_policy_addins_disabled (#7644)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-02 11:58:56 +02:00
Daniel Barranquero
3949806b5d feat(exchange): add new check exchange_mailbox_properties_auditing_e3_enabled (#7642)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-02 10:48:30 +02:00
Daniel Barranquero
e7d249784d feat(exchange): add new check exchange_transport_config_smtp_auth_disabled (#7640)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-02 09:05:53 +02:00
Daniel Barranquero
25b1efe532 feat(exchange): add new check exchange_organization_mailtips_enabled (#7637)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-05-02 08:46:14 +02:00
Adrián Jesús Peña Rodríguez
c289ddacf2 feat: add m365 to API (#7563)
Co-authored-by: Andoni A <14891798+andoniaf@users.noreply.github.com>
2025-04-30 17:09:47 +02:00
Hugo Pereira Brito
3fd9c51086 feat(m365): automate PowerShell modules installation (#7618)
Co-authored-by: Andoni A <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: Adrián Jesús Peña Rodríguez <adrianjpr@gmail.com>
2025-04-30 16:41:59 +02:00
Pedro Martín
de01087246 fix(s3): add ContentType in upload_file (#7635)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-04-30 19:48:23 +05:45
Pablo Lara
fe42bb47f7 fix: set correct default value for session duration (#7639) 2025-04-30 13:00:45 +02:00
Víctor Fernández Poyatos
c56bd519bb test(performance): Add base framework for API performance tests (#7632) 2025-04-30 12:36:25 +02:00
Daniel Barranquero
79b29d9437 feat(exchange): add new check exchange_mailbox_policy_additional_storage_restricted (#7638)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-04-30 12:05:41 +02:00
Pedro Martín
82eecec277 feat(sharepoint): add new check related with OneDrive Sync (#7589)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
2025-04-30 11:43:41 +02:00
Pedro Martín
ceacd077d2 fix(typos): remove unneeded files (#7627) 2025-04-29 13:24:24 +05:45
Pepe Fagoaga
5a0fb13ece fix(run-sh): Use poetry's env (#7621) 2025-04-29 13:01:12 +05:45
Erlend Ekern
78439b4c0c chore(dockerfile): add image source as docker label (#7617) 2025-04-29 13:00:47 +05:45
Pedro Martín
06f94f884f feat(compliance): add new Prowler Threat Score Compliance Framework (#7603)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-28 09:57:52 +02:00
dependabot[bot]
b8836c6404 chore(deps): bump @babel/runtime from 7.24.7 to 7.27.0 in /ui (#7502)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-28 08:49:33 +02:00
Andoni Alonso
ac79b86810 feat(teams): add new check teams_meeting_presenters_restricted (#7613)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-25 14:34:05 -04:00
Andoni Alonso
793c2ae947 feat(teams): add new check teams_meeting_recording_disabled (#7607)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-25 12:35:54 -04:00
Andoni Alonso
cdcc5c6e35 feat(teams): add new check teams_meeting_external_chat_disabled (#7605)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-25 11:30:38 -04:00
Andoni Alonso
51db81aa5c feat(teams): add new check teams_meeting_external_control_disabled (#7604)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-25 10:59:36 -04:00
Hugo Pereira Brito
a51a185f49 fix(powershell): handle m365 provider execution and logging (#7602)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-25 10:44:25 -04:00
Hugo Pereira Brito
90453fd07e feat(teams): add new check teams_meeting_chat_anonymous_users_disabled (#7579)
Co-authored-by: Andoni A <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-25 09:29:24 -04:00
Pablo Lara
d740bf84c3 feat: add new M365 to the provider overview table (#7615) 2025-04-25 15:24:47 +02:00
Pedro Martín
d13d2677ea fix(compliance): improve compliance and dashboard (#7596)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-24 13:28:18 -04:00
dependabot[bot]
b076c98ba1 chore(deps): bump h11 from 0.14.0 to 0.16.0 (#7609)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 13:19:11 -04:00
Hugo Pereira Brito
d071dea7f7 feat(teams): add new check teams_meeting_dial_in_lobby_bypass_disabled (#7571)
Co-authored-by: Andoni A <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-24 13:05:52 -04:00
Hugo Pereira Brito
d9782c7b8a feat(teams): add new check teams_meeting_external_lobby_bypass_disabled (#7568)
Co-authored-by: Andoni A <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-24 12:13:42 -04:00
Pedro Martín
f85450d0b5 fix(html): remove first empty line (#7606)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-24 11:23:24 -04:00
Pepe Fagoaga
b129326ed6 chore(actions): Bump Prowler version on release (#7560) 2025-04-24 10:25:36 -04:00
Hugo Pereira Brito
eaf0d06b63 chore(m365): add test_connection function (#7541)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-24 10:20:58 -04:00
Pedro Martín
87f3e0a138 fix(nhn): remove unneeded parameter (#7600) 2025-04-24 13:21:52 +02:00
Daniel Barranquero
8e3c856a14 feat(exchange): add new check exchange_external_email_tagging_enabled (#7580)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-23 14:11:39 -04:00
Daniel Barranquero
12c2439196 feat(exchange): add new check exchange_transport_rules_whitelist_disabled (#7569)
Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-23 13:47:51 -04:00
Daniel Barranquero
deb1e0ff34 feat(defender): Add new check defender_antispam_policy_inbound_no_allowed_domains (#7500)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-23 13:29:24 -04:00
Hugo Pereira Brito
808e8297b0 feat(teams): add new check teams_meeting_anonymous_user_start_disabled (#7567) 2025-04-23 10:31:17 -04:00
Hugo Pereira Brito
738ce56955 fix(docs): overview m365 auth (#7588) 2025-04-23 09:58:32 -04:00
Sergio Garcia
190fd0b93c fix(scan): handle cloud provider errors and ignore expected sentry noise (#7582) 2025-04-23 09:58:04 -04:00
Pablo Lara
ca6df26918 chore: remove deprecated launch scan page from old 4-step workflow (#7592) 2025-04-23 15:13:05 +02:00
Pablo Lara
bcfeb97e4a feat(m365): add the new provider m365 - UI part (#7591) 2025-04-23 14:23:33 +02:00
Hugo Pereira Brito
0234957907 feat(teams): add new check teams_meeting_anonymous_user_join_disabled (#7565)
Co-authored-by: Andoni A <14891798+andoniaf@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 16:02:16 -04:00
Hugo Pereira Brito
8713b74204 feat(teams): add new check teams_external_users_cannot_start_conversations (#7562)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 14:36:54 -04:00
Hugo Pereira Brito
cbaddad358 feat(teams): add new check teams_unmanaged_communication_disabled (#7561)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 13:25:30 -04:00
Hugo Pereira Brito
2379544425 feat(teams): add new check teams_external_domains_restricted (#7557)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-22 13:04:51 -04:00
Hugo Pereira Brito
29fefba62e fix(teams): teams_email_sending_to_channel_disabled docstrings (#7559) 2025-04-22 12:57:18 -04:00
Daniel Barranquero
098382117e feat(defender): add new check defender_antispam_connection_filter_policy_safe_list_off (#7494)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 12:52:34 -04:00
Daniel Barranquero
d816d73174 feat(defender): add new check defender_antispam_connection_filter_policy_empty_ip_allowlist (#7492)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 12:28:18 -04:00
Matt Keeler
30eb78c293 fix(aws): use correct ports in ec2_instance_port_cifs_exposed_to_internet recommendation (#7574)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 12:24:12 -04:00
Daniel Barranquero
a671b092ee feat(defender): add new check defender_domain_dkim_enabled (#7485)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 11:15:33 -04:00
Pepe Fagoaga
0edf199282 fix(actions): Include files within providers for SDK tests (#7577) 2025-04-22 10:28:43 -04:00
Andoni Alonso
2478555f0e fix(aws): update bucket naming validation to accept dots (#7545)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 10:06:14 -04:00
Daniel Barranquero
b07080245d feat(defender): add new check defender_antispam_outbound_policy_configured (#7480)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-22 09:58:07 -04:00
Pepe Fagoaga
2ebf217bb0 fix(k8s): Remove command as it is not needed (#7570) 2025-04-22 09:33:40 -04:00
Prowler Bot
bb527024d9 chore(regions_update): Changes in regions for AWS services (#7550)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-22 09:32:22 -04:00
Sergio Garcia
e897978c3e fix(azure): handle new FlowLog properties (#7546) 2025-04-22 09:21:17 -04:00
Pepe Fagoaga
00f1c02532 chore(tests): Split by provider in the SDK (#7564) 2025-04-22 16:46:15 +05:45
César Arroba
348d1a2fda chore: pass labels on PR merge trigger (#7558) 2025-04-21 16:43:40 +02:00
César Arroba
f1df8ba458 chore: revert pass labels (#7556) 2025-04-21 12:46:42 +02:00
César Arroba
b5ea418933 chore: pass labels as json is required (#7555) 2025-04-21 12:10:18 +02:00
César Arroba
734fa5a4e6 chore: fix merged PR action, incorrect order on payload (#7554) 2025-04-21 12:03:14 +02:00
César Arroba
08f6d4b69b chore: pass labels (#7553) 2025-04-21 11:57:50 +02:00
César Arroba
29d3bb9f9a chore: fix json body (#7552) 2025-04-21 15:01:03 +05:45
César Arroba
4d217e642b chore: fix trigger (#7551) 2025-04-21 14:56:17 +05:45
César Arroba
bd56e03991 chore(gha): trigger cloud pull-request when a PR is merged (#7212) 2025-04-21 14:54:22 +05:45
Felix Dreissig
0b6aa0ddcd fix(aws): remove SHA-1 from ACM insecure key algorithms (#7547) 2025-04-18 16:25:44 -04:00
Daniel Barranquero
4f3496194d feat(defender): add new check defender_antiphishing_policy_configured (#7453) 2025-04-18 12:42:19 -04:00
Daniel Barranquero
d09a680aaa feat(defender): add new check defender_malware_policy_notifications_internal_users_malware_enabled (#7435)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-18 11:08:05 -04:00
Daniel Barranquero
56d7431d56 feat(defender): add service and new check defender_malware_policy_common_attachments_filter_enabled (#7425)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-17 13:33:43 -04:00
Daniel Barranquero
abae5f1626 feat(exchange): add new check exchange_mailbox_audit_bypass_disabled (#7418)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-16 14:06:32 -04:00
Daniel Barranquero
7d0e94eecb feat(exchange): add service and new check exchange_organization_mailbox_auditing_enabled (#7408)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-16 12:19:06 -04:00
Hugo Pereira Brito
23b65c7728 feat(teams): add new check teams_email_sending_to_channel_disabled (#7533)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-16 11:13:55 -04:00
Sergio Garcia
aa3182ebc5 feat(gcp): support CLOUDSDK_AUTH_ACCESS_TOKEN (#7495) 2025-04-16 10:35:04 -04:00
Sergio Garcia
32d27df0ba chore(regions): change interval to weekly (#7539) 2025-04-16 09:35:30 -04:00
Prowler Bot
6439f0a5f3 chore(regions_update): Changes in regions for AWS services (#7538)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-16 09:25:29 -04:00
Sergio Garcia
19476632ff chore(dependabot): change settings (#7536) 2025-04-16 11:26:57 +05:45
Pedro Martín
d4c12e4632 fix(iam): change some logger.info values (#7526)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-04-15 13:25:37 -04:00
Hugo Pereira Brito
52bd48168f feat: adapt Microsoft365 provider to use PowerShell (#7331)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-15 13:24:09 -04:00
Bogdan A
c0d935e232 docs(gcp): update required permissions for GCP (#7488) 2025-04-15 10:23:45 -04:00
Pepe Fagoaga
24dfd47329 fix(pypi): package name location in pyproject.toml while replicating for prowler-cloud (#7531) 2025-04-15 20:01:27 +05:45
dependabot[bot]
fbae338689 chore(deps): bump python from 3.12.9-alpine3.20 to 3.12.10-alpine3.20 (#7520)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 09:26:04 -04:00
dependabot[bot]
186fd88f8c chore(deps): bump codecov/codecov-action from 5.4.0 to 5.4.2 (#7522)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 09:25:44 -04:00
dependabot[bot]
14ff34c00a chore(deps): bump actions/setup-node from 4.3.0 to 4.4.0 (#7521)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 09:25:23 -04:00
Prowler Bot
a66fa394d3 chore(regions_update): Changes in regions for AWS services (#7527)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-15 09:20:20 -04:00
Pepe Fagoaga
931766fe08 chore(action): Remove cache in PyPI release (#7532) 2025-04-15 18:58:26 +05:45
Pepe Fagoaga
c134914896 revert: fix(findings): increase uid max length to 600 (#7528) 2025-04-15 15:54:32 +05:45
Pepe Fagoaga
25dac080a5 chore(changelog): prepare for 5.5.1 (#7523) 2025-04-15 11:46:20 +05:45
Sergio Garcia
910d39eee4 chore(sdk): update changelog (#7512) 2025-04-15 11:19:50 +05:45
Pepe Fagoaga
d604ae5569 fix(pyproject): Restore packages location (#7510) 2025-04-14 16:50:50 -04:00
Bogdan A
42f46b0fb1 feat(gcp): add check for unused Service Accounts (#7419)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-14 11:53:54 -04:00
Pepe Fagoaga
abb5864224 chore(release): bump for 5.6.0 (#7503) 2025-04-14 11:50:46 -04:00
Prowler Bot
2e2a2bd89a chore(regions_update): Changes in regions for AWS services (#7491)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-14 10:29:19 -04:00
Sergio Garcia
f8ee841921 fix(gcp): handle projects without ID (#7496) 2025-04-14 10:25:54 -04:00
Pedro Martín
ceda8c76d2 feat(azure): add SOC2 compliance framework (#7489) 2025-04-14 10:16:20 -04:00
Pedro Martín
afe0b7443f fix(defender): add default name to contacts (#7483) 2025-04-14 10:16:07 -04:00
Prowler Bot
9b773897d2 chore(regions_update): Changes in regions for AWS services (#7487)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-14 09:53:40 -04:00
Pedro Martín
d6ec4c2c96 feat(sdk): add changelog file (#7499) 2025-04-14 09:22:50 -04:00
Prowler Bot
14ef169e99 chore(regions_update): Changes in regions for AWS services (#7497)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-14 09:22:21 -04:00
Pepe Fagoaga
22141f9706 fix(findings): increase uid max length to 600 (#7498)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-04-14 17:46:13 +05:45
Pablo Lara
a5c6fee5b4 fix: update redirect URL for SSO (#7493) 2025-04-11 18:25:28 +05:45
Pablo Lara
d3a5a5c0a1 fix: resolve social login issue in AuthForm on sign-up page (#7490) 2025-04-11 09:59:10 +02:00
dependabot[bot]
5d81869de4 chore(deps): bump tj-actions/changed-files from 46.0.4 to 46.0.5 (#7486)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 22:31:33 -04:00
Pepe Fagoaga
73ebf95d89 chore(changelog): Prepare for v5.5.0 (#7484) 2025-04-09 20:50:56 +05:45
Sergio Garcia
9f4574f4ff fix: handle errors in AWS and Azure (#7482) 2025-04-09 20:19:38 +05:45
Pedro Martín
cb239b20ab fix(aws): add default session_duration (#7479) 2025-04-09 19:19:17 +05:45
eeche
3ef79588b4 feat(NHN): add NHN cloud provider with 6 checks (#6870)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-04-09 09:13:24 -04:00
Prowler Bot
61000e386b chore(regions_update): Changes in regions for AWS services (#7478)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-09 09:11:29 -04:00
Pablo Lara
53cb57901f fix: fix TS type for session duration (#7481) 2025-04-09 13:44:53 +02:00
Pedro Martín
993ff4d78e feat(gcp): add SOC2 compliance framework (#7476) 2025-04-08 15:04:08 -04:00
Drew Kerrigan
8fb10fbbf7 fix(ui): Remove UTC from timestamps in app (#7474) 2025-04-08 17:43:44 +02:00
Pablo Lara
11e834f639 feat: update the NextJS version to the latest (#7473) 2025-04-08 17:40:39 +02:00
Prowler Bot
62bf2fbb9c chore(regions_update): Changes in regions for AWS services (#7467)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-08 10:21:42 -04:00
dependabot[bot]
e57930d6c2 chore(deps): bump github/codeql-action from 3.28.13 to 3.28.15 (#7463)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-08 09:38:18 -04:00
Pepe Fagoaga
e0c417a466 fix(action): Use poetry > v2 (#7472) 2025-04-08 18:34:24 +05:45
Sergio Garcia
b55f8efed1 fix: handle errors in AWS, Azure, and GCP (#7456) 2025-04-08 18:05:43 +05:45
Pablo Lara
7cbc60d977 feat: add link with the service status using static icon (#7468) 2025-04-08 12:06:21 +02:00
Adrián Jesús Peña Rodríguez
5b7912b558 fix(provider): disable periodic task on views before deleting (#7466)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-04-08 15:35:22 +05:45
Pedro Martín
57fca3e54d fix(soc2_aws): update compliance and remove some requirements (#7452) 2025-04-07 15:47:19 -04:00
Pedro Martín
e31c27b123 fix(gcp): handle logic for empty project names (#7436) 2025-04-07 11:51:15 -04:00
Sergio Garcia
74f1da818e fix(gcp): ignore redirect balancers and add regional ones (#7442) 2025-04-07 11:47:02 -04:00
Pedro Martín
910cfa601b fix(aws): add resource arn for transit gateways (#7447) 2025-04-07 11:46:53 -04:00
dependabot[bot]
fe321c3f8a chore(deps): bump tj-actions/changed-files from 46.0.3 to 46.0.4 (#7443)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 09:11:54 -04:00
Prowler Bot
43de0d405f chore(regions_update): Changes in regions for AWS services (#7446)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-07 09:11:23 -04:00
dependabot[bot]
ac6ed31c8e chore(deps): bump trufflesecurity/trufflehog from 3.88.22 to 3.88.23 (#7444)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 09:11:07 -04:00
Prowler Bot
9d47437de4 chore(regions_update): Changes in regions for AWS services (#7445)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-07 09:10:49 -04:00
Pablo Lara
eb7a62ff77 refactor: extract common auth headers into reusable helper (#7439) 2025-04-07 08:16:55 +02:00
Pedro Martín
67bc16b46d fix(defender): add default resource name in contacts (#7438) 2025-04-04 09:35:11 -04:00
Sergio Garcia
8552a578a0 fix(aws): solve multiple errors (#7431) 2025-04-04 09:34:58 -04:00
Sergio Garcia
a5d277e045 fix(docs): solve broken links (#7432) 2025-04-04 09:15:48 -04:00
Adrián Jesús Peña Rodríguez
6dbf2ac606 feat: add missing SDK fields to API findings and resources (#7318) 2025-04-04 14:57:49 +02:00
Prowler Bot
b1569ac2f3 chore(regions_update): Changes in regions for AWS services (#7434)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-04 08:36:23 -04:00
dependabot[bot]
3d0145b522 chore(deps): bump trufflesecurity/trufflehog from 3.88.20 to 3.88.22 (#7433)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-04 08:34:51 -04:00
Pedro Martín
44174526d6 docs: add onboarding information step by step for each provider (#7362) 2025-04-04 13:00:43 +02:00
Pablo Lara
0fd395ea83 fix: correct fetch variable name from invitations to roles (#7437) 2025-04-04 12:08:57 +02:00
dependabot[bot]
5e9d4a80a1 chore(deps): bump msgraph-sdk from 1.18.0 to 1.23.0 (#7128)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-04-04 11:27:39 +02:00
Pedro Martín
e4d234fe03 fix(azure): remove resource_name inside the Check_Report (#7420) 2025-04-03 11:35:02 -04:00
Prowler Bot
3202184718 chore(regions_update): Changes in regions for AWS services (#7424)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-03 09:39:00 -04:00
Sergio Garcia
41e576f4f1 fix(gcp): make logging sink check at project level (#7421) 2025-04-03 09:37:46 -04:00
Pepe Fagoaga
d8dce07019 chore(deletion): Add environment variable for batch size (#7423)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-04-03 15:31:13 +05:45
Prowler Bot
2b0a3144c7 chore(regions_update): Changes in regions for AWS services (#7417)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-04-02 09:59:08 -04:00
dependabot[bot]
62fbce0b5e chore(deps): bump azure-identity from 1.19.0 to 1.21.0 (#7192)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-04-02 11:16:47 +02:00
Pedro Martín
5a59bb335c fix(resources): add the correct id and names for resources (#7410) 2025-04-01 20:30:37 +02:00
Sergio Garcia
2719991630 fix(report): log as error when Resource ID or Name do not exist (#7411) 2025-04-01 20:24:18 +02:00
Daniel Barranquero
6a3b8c4674 feat(entra): add new check entra_admin_users_cloud_only (#7286) 2025-04-01 19:14:15 +02:00
dependabot[bot]
191fbf0177 chore(deps): bump azure-mgmt-applicationinsights from 4.0.0 to 4.1.0 (#7161)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-04-01 14:55:37 +02:00
Víctor Fernández Poyatos
228dd2952a fix(scans): Handle duplicated scan tasks (#7401) 2025-04-01 11:55:14 +02:00
dependabot[bot]
97db38aa25 chore(deps): bump azure-mgmt-containerregistry from 10.3.0 to 12.0.0 (#7025)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-04-01 10:29:31 +02:00
Pedro Martín
dc953a6e22 docs(python): add annotations about Python version (#7402) 2025-03-31 18:14:59 +02:00
Bogdan A
51e796a48d feat(gcp): add check for dormant (unused) SA keys (#7348)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
2025-03-31 18:14:21 +02:00
Hugo Pereira Brito
024f1425df feat(entra): add new check entra_legacy_authentication_blocked (#7240) 2025-03-31 18:12:26 +02:00
Hugo Pereira Brito
a7ed610da9 feat(entra): add new check entra_users_mfa_enabled (#7228) 2025-03-31 17:54:52 +02:00
Hugo Pereira Brito
7ba99f22cd feat(entra): add new check entra_admin_users_phishing_resistant_mfa_enabled (#7211)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-03-31 17:52:28 +02:00
Hugo Pereira Brito
b8ce09ec34 fix(entra): check name and logic of entra_admin_users_have_mfa_enabled (#7230) 2025-03-31 17:50:51 +02:00
Daniel Barranquero
c243110a49 feat(entra): add new check entra_policy_guest_invite_only_for_admin_roles (#7241)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-03-31 14:53:50 +02:00
Daniel Barranquero
ee27636f32 fix(redshift): validation error for Cluster.multi_az (#7381) 2025-03-31 13:55:48 +02:00
dependabot[bot]
f2f41c9c44 chore(deps): bump azure-mgmt-resource from 23.2.0 to 23.3.0 (#7054)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-03-31 13:29:49 +02:00
Daniel Barranquero
9312890e6a feat(entra): add new check entra_policy_guest_users_access_restrictions (#7234) 2025-03-31 12:45:26 +02:00
Daniel Barranquero
9578281b4f feat(entra): add new check entra_policy_restricts_user_consent_for_apps (#7225) 2025-03-31 12:32:51 +02:00
Víctor Fernández Poyatos
08690068fc feat(findings): Handle muted findings in API and UI (#7378)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-03-31 12:25:58 +02:00
Hugo Pereira Brito
e06a33de84 feat(entra): add new check entra_managed_device_required_for_mfa_registration (#7203)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-31 12:24:47 +02:00
Prowler Bot
6a3db10fda chore(regions_update): Changes in regions for AWS services (#7395)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-31 10:18:53 +02:00
Andoni Alonso
bbed445efa chore(sentry): ignore exception when aws service not available in a region (#7352) 2025-03-31 10:13:19 +02:00
dependabot[bot]
9d65fb0bf2 chore(deps): bump trufflesecurity/trufflehog from 3.88.18 to 3.88.20 (#7394)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 10:12:55 +02:00
Prowler Bot
34f03ca110 chore(regions_update): Changes in regions for AWS services (#7391)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-27 11:10:07 +01:00
Daniel Barranquero
87c038f0c2 fix(rds): hundle Certificate rds-ca-2019 not found (#7383) 2025-03-27 11:09:33 +01:00
dependabot[bot]
b3014f03b1 chore(deps): bump actions/setup-python from 5.4.0 to 5.5.0 (#7390)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 09:13:50 +01:00
Daniel Barranquero
d39598c9fc fix(stepfunctions): Nonetype object has no attribute level (#7386) 2025-03-26 19:39:27 +01:00
Daniel Barranquero
5ea9106259 fix(fms): resource metadata could not be converted to dict (#7379) 2025-03-26 19:25:00 +01:00
Prowler Bot
bcc0b59de1 chore(regions_update): Changes in regions for AWS services (#7382)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-26 12:52:35 +01:00
Daniel Barranquero
5d6ed640f0 fix(vm): handle Nonetype is not iterable for extensions (#7360)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-03-25 12:25:15 +01:00
Sergio Garcia
dd1cc2d025 fix(s3): handle None S3 account public access block (#7350) 2025-03-25 11:39:19 +01:00
Andoni Alonso
52e5cc23e4 fix(storagegateway): describe smb/nfs share per region (#7374) 2025-03-25 10:35:37 +01:00
Pablo Lara
76a8e2be1f chore: tweak for button see findings (#7369) 2025-03-25 09:52:36 +01:00
Andoni Alonso
d989425490 fix(vm): handle NoneType accessing security_profile (#7221) 2025-03-25 09:33:00 +01:00
Hugo Pereira Brito
1e324b7ed2 fix(network): handle Nonetype is not iterable for security groups (#7208) 2025-03-25 09:28:37 +01:00
Sergio Garcia
e68aa62f94 fix(iam): handle none SAML Providers (#7359) 2025-03-25 09:24:32 +01:00
Daniel Barranquero
332b98a1ab fix(iam): handle UnboundLocalError cannot access local variable 'report' (#7361) 2025-03-25 09:22:35 +01:00
Pablo Lara
dd05ef7974 chore(scans): properly enable link to findings when scan is completed (#7368) 2025-03-25 08:45:37 +01:00
dependabot[bot]
d6862766d3 chore(deps): bump github/codeql-action from 3.28.12 to 3.28.13 (#7367)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 12:43:02 +05:45
dependabot[bot]
f52d005e2d chore(deps): bump tj-actions/changed-files from 46.0.1 to 46.0.3 (#7363)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 12:42:50 +05:45
Víctor Fernández Poyatos
bf475234a5 build(api): Force django-allauth==65.4.1 (#7358) 2025-03-24 17:39:47 +01:00
Pablo Lara
cd5985c056 docs: update readme (#7357) 2025-03-24 15:41:35 +01:00
Pablo Lara
ce33dbf823 chore(findings): apply default filter to show failed findings (#7356) 2025-03-24 15:38:09 +01:00
Pablo Lara
0a9d0688a7 docs(changelog): document addition of download column in scans table … (#7354) 2025-03-24 15:28:13 +01:00
Pablo Lara
24784f2ce5 feat(scans): add download button column for completed scans in table (#7353) 2025-03-24 15:22:36 +01:00
Víctor Fernández Poyatos
7a1e611b88 ref(providers): Refactor provider deletion functions (#7349) 2025-03-24 14:39:14 +01:00
Pepe Fagoaga
3073150008 chore(next): Remove x-powered-by header (#7346) 2025-03-24 16:17:18 +05:45
Jonny
9923def4cb chore(awslambda): update obsolete lambda runtimes (#7330)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-24 11:21:01 +01:00
Víctor Fernández Poyatos
a7f612303f feat(compliance): Add endpoint to retrieve compliance overviews metadata (#7333) 2025-03-24 10:34:43 +01:00
Pablo Lara
64c2a2217a docs: update changelog with Next.js security patch (#7339) (#7341) 2025-03-24 09:59:59 +01:00
Pablo Lara
4689d7a952 chore: upgrade Next.js to 14.2.25 to fix auth middleware vulnerability (#7339) 2025-03-24 09:48:41 +01:00
Prowler Bot
87cd143967 chore(regions_update): Changes in regions for AWS services (#7219)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-24 09:46:57 +01:00
Prowler Bot
e37fd05d58 chore(regions_update): Changes in regions for AWS services (#7246)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-24 09:46:26 +01:00
Prowler Bot
acc708bda5 chore(regions_update): Changes in regions for AWS services (#7250)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-24 09:46:08 +01:00
Prowler Bot
c7460bb69c chore(regions_update): Changes in regions for AWS services (#7334)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-24 09:35:47 +01:00
Pepe Fagoaga
84b273dab9 fix(action): Use Poetry v2 (#7329) 2025-03-20 18:49:32 +01:00
Prowler Bot
bb7ce2157e chore(regions_update): Changes in regions for AWS services (#7323)
Co-authored-by: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
2025-03-20 18:10:28 +05:45
Pepe Fagoaga
07b9e1d3a4 chore(api): Update CHANGELOG (#7325) 2025-03-20 15:22:00 +05:45
Pepe Fagoaga
96a879d761 fix(scan_id): Read the ID from the Scan object (#7324) 2025-03-20 15:18:31 +05:45
Pepe Fagoaga
283127c3f4 chore(aws-regions): remove backport to v3 (#7319) 2025-03-19 22:14:41 +05:45
dependabot[bot]
beeee80a0b chore(deps): bump github/codeql-action from 3.28.11 to 3.28.12 (#7321)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 22:14:23 +05:45
Pepe Fagoaga
06b62826b4 chore(dependabot): disable for v3 (#7316) 2025-03-19 21:56:52 +05:45
Pedro Martín
d0736af209 fix(gcp): make provider id mandatory in test_connection (#7296) 2025-03-19 18:33:49 +05:45
Pablo Lara
716c8c1a5f docs: add social login images and update documentation (#7314)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-03-19 17:16:37 +05:45
Pepe Fagoaga
e6cdda1bd9 chore(dependabot): Disable for API and UI (#7300) 2025-03-19 14:46:11 +05:45
Pedro Martín
2747a633bc fix(k8s): remove typos from PCI 4.0 (#7294) 2025-03-19 09:31:40 +01:00
Pepe Fagoaga
74118f5cfe chore(social-login): improve copy when not enabled (#7295) 2025-03-19 13:36:22 +05:45
dependabot[bot]
598bdf28bb chore(deps): bump trufflesecurity/trufflehog from 3.88.17 to 3.88.18 (#7297)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 12:31:52 +05:45
Pepe Fagoaga
d75f681c87 chore(security): Configure HTTP Security Headers (#7220)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-03-18 17:49:12 +01:00
Pepe Fagoaga
c7956ede6a chore(security): Add HTTP Security Headers (#7289) 2025-03-18 17:44:57 +01:00
Pablo Lara
64f5a69e84 fix: prevent SSR mismatch in OAuth URL generation (#7288) 2025-03-18 17:22:29 +01:00
dependabot[bot]
bfb15c34b8 chore(deps): bump azure-mgmt-containerservice from 34.0.0 to 34.1.0 (#6989)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-03-18 17:14:25 +01:00
Pablo Lara
638b3ac0cd chore(providers): change wording when adding a new provider (#7280) 2025-03-18 21:50:56 +05:45
Daniel Barranquero
9d6147a037 fix(route53): solve false positive in route53_public_hosted_zones_cloudwatch_logging_enabled (#7201) 2025-03-18 16:54:49 +01:00
Pepe Fagoaga
802c786ac2 fix(test-connection): Handle provider without secret (#7283) 2025-03-18 21:34:36 +05:45
Pepe Fagoaga
c8be8dbd9a fix(aws-regions): Use @prowler-bot as author (#7285) 2025-03-18 20:27:19 +05:45
Pablo Lara
7053b2bb37 chore: add env vars for social login (#7257)
Co-authored-by: Adrián Jesús Peña Rodríguez <adrianjpr@gmail.com>
2025-03-18 13:43:46 +01:00
Prowler Bot
447bf832cd chore(regions_update): Changes in regions for AWS services (#7281)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-18 17:35:44 +05:45
Pablo Lara
7c4571b55e feat(providers): add component to render a link to the documentation (#7282) 2025-03-18 12:05:38 +01:00
dependabot[bot]
eb7c16aba5 chore(deps): bump azure-mgmt-storage from 21.2.1 to 22.1.1 (#7098)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-03-18 11:06:46 +01:00
Adrián Jesús Peña Rodríguez
b09e83b171 chore: add api reference to download report section (#7243) 2025-03-18 14:54:13 +05:45
Hugo Pereira Brito
bb149a30a7 fix(microsoft365): typo Microsoft365NotTenantIdButClientIdAndClienSecretError (#7244) 2025-03-17 21:16:47 +05:45
Pablo Lara
d5be35af49 chore: Rename keyServer and extract to helper (#7256) 2025-03-17 21:11:27 +05:45
Pedro Martín
f6aa56d92b fix(.env): remove spaces (#7255) 2025-03-17 20:48:55 +05:45
Pedro Martín
6a4df15c47 fix(prowler): change from prowler.py to prowler-cli.py (#7253) 2025-03-17 15:44:15 +01:00
Pablo Lara
72de5fdb1b chore: update git ignore file (#7254) 2025-03-17 14:53:58 +01:00
Pedro Martín
a7f55d06af feat(jira): add basic auth method (#7233) 2025-03-17 14:31:35 +01:00
Pepe Fagoaga
97da78d4e7 fix(backport): Use container tagged version (#7252) 2025-03-17 18:19:43 +05:45
Pepe Fagoaga
c4f6161c73 chore(security): Pin actions to the Full-Length Commit SHA (#7249) 2025-03-17 17:11:28 +05:45
Pablo Lara
db7ffea24d chore: add env var for social login (#7251) 2025-03-17 10:23:01 +01:00
Prowler Bot
489b5abf82 chore(regions_update): Changes in regions for AWS services (#7237)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-17 13:47:56 +05:45
Prowler Bot
3a55c2ee07 chore(regions_update): Changes in regions for AWS services (#7245)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-17 12:34:44 +05:45
Pedro Martín
64d866271c fix(scan): add compliance info inside finding (#5649) 2025-03-17 12:18:00 +05:45
Pablo Lara
1ab2a80eab chore: improve UX when social login is not enabled (#7242) 2025-03-15 12:12:30 +01:00
Pablo Lara
89d4c521ba chore(social-login): disable social login buttons when env vars are not set (#7238) 2025-03-14 11:32:22 +01:00
Pablo Lara
f2e19d377a chore(social-login): rename env.vars for social login (#7232) 2025-03-13 17:07:17 +01:00
Pablo Lara
2b7b887b87 chore: social auth is algo in sign-up page (#7231) 2025-03-13 14:20:09 +01:00
Pablo Lara
44c70b5d01 chore: remove unused regions (#7229) 2025-03-13 13:57:16 +01:00
Pablo Lara
7514484c42 chore: change wording for launching a single scan (#7226) 2025-03-13 13:48:01 +01:00
Adrián Jesús Peña Rodríguez
9594c4c99f fix: add a handled response in case local files are missing (#7183) 2025-03-13 13:47:00 +01:00
Pablo Lara
56445c9753 chore: update changelog (#7223) 2025-03-13 13:39:26 +01:00
Adrián Jesús Peña Rodríguez
07419fd5e1 fix(exports): change the way to remove the local export files after s3 upload (#7172) 2025-03-13 13:37:17 +01:00
Pablo Lara
2e4dd12b41 feat(social-login): social login with Google is working (#7218)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-03-13 12:52:30 +01:00
Víctor Fernández Poyatos
fed2046c49 fix(migrations): add through parameter to integration.providers (#7222) 2025-03-13 12:47:34 +01:00
Pepe Fagoaga
db79db4786 fix(pyproject): Rename prowler.py (#7217) 2025-03-13 16:53:38 +05:45
Víctor Fernández Poyatos
6f027e3c57 feat(integrations): Added new endpoints to allow configuring integrations (#7167) 2025-03-12 19:57:55 +05:45
Daniel Barranquero
bdb877009f feat(entra): add new check entra_admin_mfa_enabled_for_administrative_roles (#7181)
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-12 14:47:29 +01:00
Sergio Garcia
6564ec1ff5 fix(cloudwatch): handle None metric alarms (#7205) 2025-03-12 14:44:36 +01:00
Pedro Martín
443dc067b3 feat(kubernetes): add ISO 27001 2022 compliance framework (#7204) 2025-03-12 14:24:53 +01:00
Hugo Pereira Brito
6221650c5f feat(entra): add new check entra_identity_protection_sign_in_risk_enabled (#7171)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-12 13:53:47 +01:00
Andoni Alonso
034d0fd1f4 refactor(check): add docstrings and improve report handling (#7113) 2025-03-12 13:38:42 +01:00
Hugo Pereira Brito
e617ff0460 feat(docs): add microsoft365 configurable checks (#7200) 2025-03-12 12:52:35 +01:00
Hugo Pereira Brito
4b1ed607a7 feat(entra): add new check entra_identity_protection_user_risk_enabled (#7126)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-12 12:44:31 +01:00
Pepe Fagoaga
137365a670 chore(poetry): Upgrade to v2 (#7112) 2025-03-12 17:28:34 +05:45
Hugo Pereira Brito
1891a1b24f feat(entra): add new check entra_managed_device_required_for_authentication (#7115)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-12 11:34:14 +01:00
Daniel Barranquero
e57e070866 feat(entra): add new check entra_password_hash_sync_enabled (#7061) 2025-03-12 11:31:49 +01:00
dependabot[bot]
66998cd1ad chore(deps): bump google-api-python-client from 2.162.0 to 2.163.0 (#7191)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-12 11:25:24 +01:00
Prowler Bot
c0b1833446 chore(regions_update): Changes in regions for AWS services (#7197)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-12 11:25:06 +01:00
Pablo Lara
329a72c77c chore: update changelog (#7199) 2025-03-12 10:12:33 +01:00
Pablo Lara
2610ee9d0c feat(invitations): Disable editing for accepted invites (#7198) 2025-03-12 10:06:46 +01:00
Pablo Lara
a13ca9034e chore(scans): rename type to trigger (#7196) 2025-03-12 09:47:02 +01:00
Pablo Lara
5d1abb3689 chore: auto refresh if the state is also available (#7195) 2025-03-12 09:33:24 +01:00
Pablo Lara
e1d1c6d154 styles: tweaks styles (#7194) 2025-03-12 09:23:02 +01:00
Pablo Lara
e18e0e7cd4 chore(launch-scan): update wording (#7193) 2025-03-12 08:20:15 +01:00
Pablo Lara
eaf3d07a3f chore: update the changelog (#7190) 2025-03-12 08:15:28 +01:00
Hugo Pereira Brito
c88ae32b7f feat(microsoft365): add new check entra_admin_users_sign_in_frequency_enabled (#7020)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-03-11 19:18:33 +01:00
Pablo Lara
605613e220 feat(scans): allow running a scan once (#7188) 2025-03-11 17:47:47 +01:00
Sergio Garcia
d2772000ec chore(sentry): ignore new exceptions in Sentry (#7187) 2025-03-11 17:46:14 +01:00
Adrián Jesús Peña Rodríguez
42939a79f5 docs: add users, invitations and RBAC (#7109) 2025-03-11 21:59:04 +05:45
Daniel Barranquero
ed17931117 feat(entra): add new check entra_dynamic_group_for_guests_created (#7168)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-03-11 16:21:17 +01:00
Daniel Barranquero
66df5f7a1c chore(providers): enhance Remediation.Code.CLI field from check's metadata (#7094)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
2025-03-11 16:15:58 +01:00
Pedro Martín
fc6e6696e5 feat(gcp): add ISO 27001 2022 compliance framework (#7185) 2025-03-11 15:16:40 +01:00
Sergio Garcia
465748c8a1 chore(sentry): ignore expected errors in GCP API (#7184) 2025-03-11 14:32:37 +01:00
Pedro Martín
e59cd71bbf fix(azure): add remaining checks for reqA.5.25 (#7182) 2025-03-11 14:16:10 +01:00
Daniel Barranquero
8a76fea310 feat(entra): add new check entra_admin_consent_workflow_enabled (#7110) 2025-03-11 13:18:17 +01:00
Adrián Jesús Peña Rodríguez
0e46be54ec docs: add generate_output documentation (#7122)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-03-11 17:23:32 +05:45
Pedro Martín
dc81813fdf fix(ens): remove and change duplicated ids (#7165) 2025-03-11 11:35:31 +01:00
Hugo Pereira Brito
eaa0df16bb refactor(microsoft365): resource metadata assertions (#7169) 2025-03-11 11:30:37 +01:00
Pedro Martín
c23e911028 feat(azure): add ISO 27001 2022 compliance framework (#7170) 2025-03-11 11:29:40 +01:00
dependabot[bot]
06b96a1007 chore(deps): bump tzlocal from 5.3 to 5.3.1 (#7162)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-11 11:17:50 +01:00
Prowler Bot
fa545c591f chore(regions_update): Changes in regions for AWS services (#7177)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-11 11:17:27 +01:00
dependabot[bot]
e828b780c7 chore(deps): bump trufflesecurity/trufflehog from 3.88.15 to 3.88.16 (#7174)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-11 11:16:57 +01:00
Harshit Raj Singh
eca8c5cabd feat(aws): AWS Found Sec Best Practices & PCI DSS v3.2.1 upgrade (#7017)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2025-03-11 09:31:16 +01:00
Pablo Lara
b7bce6008f fix: tweak z-index for custom inputs (#7166) 2025-03-10 11:55:04 +01:00
Pablo Lara
2fdf89883d feat(scans): improve scan launch provider selection (#7164) 2025-03-10 10:05:33 +01:00
dependabot[bot]
6c5d4bbaaa chore(deps): bump django from 5.1.5 to 5.1.7 in /api (#7145)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-10 09:50:09 +01:00
Gary Mclean
cb2f926d4f fix(azure): correct check title for SQL Server Unrestricted (#7123) 2025-03-07 18:24:24 +01:00
ryan-stavella
12c01b437e fix(metadata): typo in ec2_securitygroup_allow_wide_open_public_ipv4 (#7116) 2025-03-07 15:28:08 +01:00
dependabot[bot]
3253a58942 chore(deps-dev): bump mock from 5.1.0 to 5.2.0 (#7099)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 15:01:43 +01:00
Kay Agahd
199f7f14ea fix(doc): event_time has been changed to time_dt but was not documented (#7136) 2025-03-07 14:36:51 +01:00
Andoni Alonso
d42406d765 fix(metadata): match type with check results (#7111) 2025-03-07 14:34:07 +01:00
Kay Agahd
2276ffb1f6 fix(aws): ecs_task_definitions_no_environment_secrets.metadata.json (#7135) 2025-03-07 14:31:03 +01:00
dependabot[bot]
218fb3afb0 chore(deps): bump jinja2 from 3.1.5 to 3.1.6 (#7151)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 14:27:29 +01:00
Prowler Bot
a9fb890979 chore(regions_update): Changes in regions for AWS services (#7108)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-07 14:06:28 +01:00
Prowler Bot
54ebf5b455 chore(regions_update): Changes in regions for AWS services (#7119)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-07 14:04:48 +01:00
dependabot[bot]
c9a0475aa8 chore(deps-dev): bump mkdocs-git-revision-date-localized-plugin from 1.3.0 to 1.4.1 (#7129)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 14:03:44 +01:00
Prowler Bot
5567d9f88c chore(regions_update): Changes in regions for AWS services (#7131)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-07 13:19:08 +01:00
dependabot[bot]
56f3e661ae chore(deps): bump trufflesecurity/trufflehog from 3.88.14 to 3.88.15 (#7127)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-07 13:17:45 +01:00
César Arroba
1aa4479a10 chore: increase release to 5.5.0 (#7143) 2025-03-07 13:16:24 +01:00
Prowler Bot
7b625d0a91 chore(regions_update): Changes in regions for AWS services (#7146)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-07 13:15:51 +01:00
Pablo Lara
fd0529529d chore: update changelog (#7149) 2025-03-07 11:47:23 +01:00
Pablo Lara
af43191954 fix: tweaks for compliance cards (#7147) 2025-03-07 11:32:58 +01:00
Pablo Lara
2ce2ca7c91 feat: add changelog (#7141) 2025-03-06 16:46:55 +01:00
Víctor Fernández Poyatos
a0fc3db665 fix(overviews): manage overview exceptions and use batch_size with bulk (#7140) 2025-03-06 15:35:29 +01:00
César Arroba
feb458027f chore(ui-gha): delete double quotes on prowler version (#7139) 2025-03-06 19:48:53 +05:45
Pablo Lara
e5a5b7af5c fix(groups): display uid if alias is missing (#7137) 2025-03-06 14:37:36 +01:00
Pablo Lara
ad456ae2fe fix(credentials): adjust helper links to fit width (#7133) 2025-03-06 11:42:26 +01:00
Pepe Fagoaga
690cb51f6c revert(findings): change uid from varchar to text (#7132) 2025-03-06 16:24:35 +05:45
dependabot[bot]
14aaa2f376 chore(deps): bump jinja2 from 3.1.5 to 3.1.6 in /api (#7130)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-06 09:39:24 +01:00
César Arroba
6e47ca2c41 chore(ui-gha): add version prefix (#7125) 2025-03-05 21:13:24 +05:45
Víctor Fernández Poyatos
0d99d2be9b fix(reports): Fix task kwargs and result (#7124) 2025-03-05 21:10:44 +05:45
César Arroba
c322ef00e7 chore(ui): add prowler version on build (#7120) 2025-03-05 20:46:16 +05:45
Pablo Lara
3513421225 feat(compliance): new compliance selector (#7118) 2025-03-05 15:12:10 +01:00
Víctor Fernández Poyatos
b0e6bfbefe chore(api): Update changelog (#7090) 2025-03-04 17:44:34 +01:00
dependabot[bot]
f7a918730e chore(deps-dev): bump pytest from 8.3.4 to 8.3.5 (#7097)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-04 09:16:05 +01:00
Pablo Lara
cef33319c5 chore(ui): update label from 'Select a scan job' to 'Select a cloud p… (#7107) 2025-03-04 09:11:39 +01:00
Pablo Lara
2036a59210 fix(roles): show the correct error message (#7089) 2025-03-03 15:46:02 +01:00
Pablo Lara
e5eccb6227 fix: bug with create role and unlimited visibility checkbox (#7088) 2025-03-03 15:45:39 +01:00
Sergio Garcia
48c2c8567c feat(aws): add fixers for threat detection checks (#7085) 2025-03-03 14:20:23 +01:00
Pablo Lara
bbeef0299f feat(version): add prowler version to the sidebar (#7086) 2025-03-03 13:40:09 +01:00
Pablo Lara
bec5584d63 chore: Update the latest table findings with the most recent changes (#7084) 2025-03-03 13:16:30 +01:00
Pablo Lara
bdc759d34c feat(sidebar): sidebar with new functionalities (#7018) 2025-03-03 12:30:28 +01:00
Prowler Bot
8db442d8ba chore(regions_update): Changes in regions for AWS services (#7067)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-03-03 09:29:48 +01:00
Sergio Garcia
9e7a0d4175 fix(threat detection): run single threat detection check (#7065) 2025-02-28 13:51:07 +01:00
Pepe Fagoaga
9c33b3f5a9 refactor(stats): Use Finding instead of Check_Report (#7053)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2025-02-28 10:54:48 +01:00
Pepe Fagoaga
7e7e2c87dc chore(examples): Scan AWS (#7064) 2025-02-28 15:25:10 +05:45
Sergio Garcia
2f741f35a8 chore(gcp): enhance GCP APIs logic (#7046) 2025-02-28 14:55:43 +05:45
dependabot[bot]
c411466df7 chore(deps): bump trufflesecurity/trufflehog from 3.88.13 to 3.88.14 (#7063)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-28 09:10:47 +01:00
Daniel Barranquero
9679939307 feat(m365): add sharepoint service with 4 checks (#7057)
Co-authored-by: MarioRgzLpz <mariorgzlpz1809@gmail.com>
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-27 18:15:17 +01:00
Pedro Martín
8539423b22 feat(docs): add info related with sts assume role and regions (#7062) 2025-02-27 17:40:31 +01:00
Daniel Barranquero
81edafdf09 fix(azure): handle account not supporting Blob (#7060) 2025-02-27 13:20:56 +01:00
Sergio Garcia
e0a262882a fix(ecs): ensure unique finding id in ECS checks (#7059) 2025-02-27 13:02:22 +01:00
Prowler Bot
89237ab99e chore(regions_update): Changes in regions for AWS services (#7056)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-27 11:00:13 +01:00
Hugo Pereira Brito
0f414e451e feat(microsoft365): add new check entra_policy_ensure_default_user_cannot_create_tenants (#6918)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-27 10:31:02 +01:00
Pablo Lara
1180522725 feat(exports): download scan exports (#7006) 2025-02-27 14:08:12 +05:45
Pepe Fagoaga
81c7ebf123 fix(env): UI version must be stable (#7055) 2025-02-27 13:32:53 +05:45
Víctor Fernández Poyatos
258f05e6f4 fix(migrations): Fix migration dependency order (#7051) 2025-02-26 17:26:21 +01:00
Víctor Fernández Poyatos
53efb1c153 feat(labeler): apply label on migration changes (#7052) 2025-02-26 17:03:12 +01:00
Pepe Fagoaga
26014a9705 fix(findings): change uid from varchar to text (#7048) 2025-02-26 21:17:16 +05:45
Víctor Fernández Poyatos
00ef037e45 feat(findings): Add Django management command to populate database with dummy data (#7049) 2025-02-26 16:15:37 +01:00
Adrián Jesús Peña Rodríguez
669ec74e67 feat(export): add API export system (#6878) 2025-02-26 15:49:44 +01:00
dependabot[bot]
c4528200b0 chore(deps-dev): bump black from 24.10.0 to 25.1.0 (#6733)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-26 11:38:09 +01:00
Daniel Barranquero
ba7cd0250a fix(elasticache): improve logic in elasticache_redis_cluster_backup_enabled (#7042) 2025-02-26 10:31:14 +01:00
Rubén De la Torre Vico
c5e97678a1 fix(azure): migrate resource models to avoid using SDK defaults (#6880) 2025-02-26 09:54:53 +01:00
Pedro Martín
337a46cdcc feat(aws): add ISO 27001 2022 compliance framework (#7035)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-26 08:34:08 +01:00
Hugo Pereira Brito
7f74b67f1f chore(iam): enhance iam_role_cross_service_confused_deputy_prevention recommendation (#7023) 2025-02-26 07:37:57 +01:00
Prowler Bot
5dcc48d2e5 chore(regions_update): Changes in regions for AWS services (#7034)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-26 07:30:07 +01:00
Prowler Bot
8b04aab07d chore(regions_update): Changes in regions for AWS services (#7015)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-26 07:29:42 +01:00
dependabot[bot]
eab4f6cf2e chore(deps): bump google-api-python-client from 2.161.0 to 2.162.0 (#7037)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-26 07:25:14 +01:00
Hugo Pereira Brito
7f8d623283 refactor(microsoft365): CheckReportMicrosoft365 and resource metadata (#6952) 2025-02-26 07:24:54 +01:00
Víctor Fernández Poyatos
dbffed8f1f feat(findings): Optimize findings endpoint (#7019) 2025-02-25 12:41:47 +01:00
Pepe Fagoaga
7e3688fdd0 chore(action): Conventional Commit Check (#7033) 2025-02-25 09:51:55 +01:00
dependabot[bot]
2e111e9ad3 chore(deps): bump trufflesecurity/trufflehog from 3.88.12 to 3.88.13 (#7026)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-25 14:34:24 +05:45
Pedro Martín
6d6070ff3f feat(outputs): add sample outputs (#6945) 2025-02-25 14:33:16 +05:45
Pedro Martín
391bbde353 fix(cis): show report table on the CLI (#6979) 2025-02-25 14:28:58 +05:45
Pedro Martín
3c56eb3762 feat(azure): add PCI DSS 4.0 (#6982) 2025-02-25 14:27:50 +05:45
Pedro Martín
7c14ea354b feat(kubernetes): add PCI DSS 4.0 (#7013) 2025-02-25 14:27:14 +05:45
Pedro Martín
c96aad0b77 feat(dashboard): take the latest finding uid by timestamp (#6987) 2025-02-25 14:25:03 +05:45
Víctor Fernández Poyatos
a9dd3e424b feat(tasks): add deletion queue for deletion tasks (#7022) 2025-02-24 18:02:52 +01:00
Pedro Martín
8a144a4046 feat(gcp): add PCI DSS 4.0 (#7010) 2025-02-21 16:19:20 +05:30
Prowler Bot
75f86d7267 chore(regions_update): Changes in regions for AWS services (#7011)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-21 15:37:15 +05:30
dependabot[bot]
bbf875fc2f chore(deps-dev): bump mkdocs-material from 9.6.4 to 9.6.5 (#7007)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-21 14:28:18 +05:30
Raj Chowdhury
59d491f61b fix(typo): solve typo in dashboard.md (#7009) 2025-02-21 14:17:08 +05:30
dependabot[bot]
ed640a1324 chore(deps): bump trufflesecurity/trufflehog from 3.88.11 to 3.88.12 (#7008)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-21 14:16:15 +05:30
César Arroba
e86fbcaef7 feat(api): setup sentry for OSS API (#6874) 2025-02-20 23:08:01 +05:45
Pablo Lara
7f48212054 chore(users): renaming the account now triggers a re-render in the sidebar (#7005) 2025-02-20 16:58:45 +01:00
dependabot[bot]
a2c5c71baf chore(deps): bump python from 3.12.8-alpine3.20 to 3.12.9-alpine3.20 (#6882)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 21:11:45 +05:30
dependabot[bot]
b904f81cb9 chore(deps): bump tzlocal from 5.2 to 5.3 (#6932)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 21:10:46 +05:30
dependabot[bot]
d64fe374dd chore(deps): bump cryptography from 43.0.1 to 44.0.1 in /api (#7001)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 12:55:36 +01:00
Hugo Pereira Brito
fe25e7938e docs(tutorials): update all deprecated poetry shell references (#7002) 2025-02-20 17:04:19 +05:45
Prowler Bot
931df361bf chore(regions_update): Changes in regions for AWS services (#6998)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-20 15:52:36 +05:30
Pedro Martín
d7c45f4aee chore(github): add compliance to PR labeler (#6996) 2025-02-20 14:50:43 +05:30
Pedro Martín
5e5bef581b fix(soc2_aws): remove duplicated checks (#6995) 2025-02-20 14:38:26 +05:30
Hugo Pereira Brito
2d9e95d812 docs(installation): add warning for poetry shell deprecation in README (#6983) 2025-02-20 14:19:35 +05:45
Pablo Lara
e5f979d106 chore(findings): add 'Status Extended' attribute to finding details (#6997) 2025-02-20 09:33:03 +01:00
Sergio Garcia
c7a5815203 fix(deps): update vulnerable cryptography dependency (#6993) 2025-02-20 12:18:15 +05:30
Pedro Martín
03e268722e feat(aws): add PCI DSS 4.0 (#6949) 2025-02-20 11:07:06 +05:30
dependabot[bot]
78a2774329 chore(deps): bump trufflesecurity/trufflehog from 3.88.9 to 3.88.11 (#6988)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 11:04:15 +05:30
dependabot[bot]
c1b5ab7f53 chore(deps): bump kubernetes from 32.0.0 to 32.0.1 (#6992)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-20 10:46:19 +05:30
Sergio Garcia
b861d97ad4 fix(report): remove invalid resources in report (#6852) 2025-02-19 21:27:52 +05:45
Pablo Lara
f3abcc9dd6 feat(scans): update the progress for executing scans (#6972) 2025-02-19 16:10:29 +01:00
César Arroba
cab13fe018 chore(gha): trigger API or UI deployment when push to master (#6946) 2025-02-19 18:08:51 +05:45
Prowler Bot
cc4b19c7ce chore(regions_update): Changes in regions for AWS services (#6978) 2025-02-19 11:04:45 +01:00
Pablo Lara
a754d9aee5 fix(roles): handle empty response in deleteRole and ensure revalidation (#6976) 2025-02-19 09:03:49 +01:00
Pedro Martín
22b54b2d8d feat(aws): add compliance CIS 4.0 (#6937) 2025-02-19 08:23:49 +05:30
dependabot[bot]
d12ca6301a chore(deps-dev): bump flake8 from 7.1.1 to 7.1.2 (#6954)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-19 08:09:58 +05:30
Hugo Pereira Brito
bc1b2ad9ab test(cloudfront): add name retrieval test for cloudfront bucket domains (#6969) 2025-02-19 08:08:55 +05:30
Pepe Fagoaga
1782ab1514 fix(ocsf): Adapt for 1.4.0 (#6971) 2025-02-19 08:06:13 +05:30
Prowler Bot
0384fc50e3 chore(regions_update): Changes in regions for AWS services (#6968)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-18 18:40:01 +05:30
dependabot[bot]
cc46dee9ee chore(deps-dev): bump bandit from 1.8.2 to 1.8.3 (#6955)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-18 18:39:10 +05:30
Hugo Pereira Brito
ed5a0ae45a fix(cloudfront): Incorrect bucket name retrievement (#6947) 2025-02-17 17:08:28 +01:00
Prowler Bot
928ccfefb8 chore(regions_update): Changes in regions for AWS services (#6944)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-17 16:55:15 +01:00
dependabot[bot]
7f6bfb7b3e chore(deps): bump trufflesecurity/trufflehog from 3.88.8 to 3.88.9 (#6943)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-17 16:54:52 +01:00
Rubén De la Torre Vico
bcbc9bf675 fix(gcp): Correct false positive when sslMode=ENCRYPTED_ONLY in CloudSQL (#6936) 2025-02-14 15:16:21 -05:00
dependabot[bot]
0ec4366f4c chore(deps): bump google-api-python-client from 2.160.0 to 2.161.0 (#6933)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-14 10:09:33 -05:00
César Arroba
ff72b7eea1 fix(gha): fix short sha step (#6939) 2025-02-14 19:11:26 +05:45
César Arroba
a32ca19251 chore(gha): add tag for api and ui images on push to master (#6920) 2025-02-14 18:01:22 +05:45
Pablo Lara
b79508956a fix(issue pages): apply sorting by default in issue pages (#6934) 2025-02-14 10:32:34 +01:00
dependabot[bot]
d76c5bd658 chore(deps): bump trufflesecurity/trufflehog from 3.88.7 to 3.88.8 (#6931)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-13 18:17:25 -05:00
Kay Agahd
580e11126c fix(aws): codebuild service threw KeyError for projects type CODEPIPELINE (#6919) 2025-02-13 12:22:09 -05:00
Sergio Garcia
736d40546a fix(gcp): handle DNS Managed Zone with no DNSSEC (#6924) 2025-02-13 12:18:50 -05:00
dependabot[bot]
88810d2bb5 chore(deps-dev): bump mkdocs-material from 9.6.3 to 9.6.4 (#6913)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-13 11:36:07 -05:00
Víctor Fernández Poyatos
3a8f4d2ffb feat(social-login): Add social login integration for Google and Github OAuth providers (#6906) 2025-02-13 16:54:38 +01:00
Sergio Garcia
1fe125a65f chore(docs): external K8s cluster Prowler App credentials (#6921) 2025-02-13 09:46:05 -05:00
Kay Agahd
0ff4df0836 fix(aws): SNS threw IndexError if SubscriptionArn is PendingConfirmation (#6896) 2025-02-13 09:34:48 -05:00
Pedro Martín
16b4775e2d fix(gcp): remove typos on CIS 3.0 (#6917) 2025-02-13 13:48:19 +01:00
dependabot[bot]
c3a13b8a29 chore(deps): bump trufflesecurity/trufflehog from 3.88.6 to 3.88.7 (#6915)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-12 19:15:03 -05:00
Sergio Garcia
d1053375b7 fix(aws): handle AccessDenied when retrieving resource policy (#6908)
Co-authored-by: Pedro Martín <pedromarting3@gmail.com>
2025-02-12 15:31:26 -05:00
César Arroba
0fa4538256 fix(gha): fix test build containers on pull requests actions (#6909) 2025-02-12 23:26:54 +05:45
Ogonna Iwunze
738644f288 fix(kms): Amazon KMS API call error handling (#6843)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-12 10:09:15 -05:00
dependabot[bot]
2f80b055ac chore(deps-dev): bump coverage from 7.6.11 to 7.6.12 (#6897)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-12 10:08:26 -05:00
Prowler Bot
fd62a1df10 chore(regions_update): Changes in regions for AWS services (#6900)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-12 10:06:42 -05:00
César Arroba
a85d0ebd0a chore(api): test build container image on pull request (#6850) 2025-02-12 15:44:05 +05:45
César Arroba
2c06902baa chore(ui): test build container image on pull request (#6849) 2025-02-12 15:43:22 +05:45
Pepe Fagoaga
76ac6429fe chore(version): Update version to 5.4.0 (#6894) 2025-02-11 17:51:08 -05:00
dependabot[bot]
43cae66b0d chore(deps-dev): bump coverage from 7.6.10 to 7.6.11 (#6887)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-10 19:30:36 -05:00
dependabot[bot]
dacddecc7d chore(deps): bump trufflesecurity/trufflehog from 3.88.5 to 3.88.6 (#6888)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-10 18:15:25 -05:00
Mario Rodriguez Lopez
dcb9267c2f feat(microsof365): Add documentation and compliance file (#6195)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
Co-authored-by: Daniel Barranquero <74871504+danibarranqueroo@users.noreply.github.com>
2025-02-10 11:13:06 -05:00
Víctor Fernández Poyatos
ff35fd90fa chore(api): Update changelog and specs (#6876) 2025-02-10 12:06:34 +01:00
Víctor Fernández Poyatos
7469377079 chore: Add needed steps for API in PR template (#6875) 2025-02-10 15:20:09 +05:45
Pepe Fagoaga
c8441f8d38 fix(kubernetes): Change UID validation (#6869)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-02-10 14:55:24 +05:45
Pepe Fagoaga
abf4eb0ffc chore: Rename dashboard table latest findings (#6873)
Co-authored-by: Pablo Lara <larabjj@gmail.com>
2025-02-10 09:55:44 +01:00
dependabot[bot]
93717cc830 chore(deps-dev): bump mkdocs-material from 9.6.2 to 9.6.3 (#6871)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-07 18:24:49 -05:00
Sergio Garcia
b629bc81f8 docs(eks): add documentation about EKS onboarding (#6853)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-02-07 10:59:01 -05:00
Pedro Martín
f628897fe1 fix(dashboard): adjust the bar chart display (#6690) 2025-02-07 10:05:30 -05:00
Prowler Bot
54b82a78e3 chore(regions_update): Changes in regions for AWS services (#6858)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-07 10:02:28 -05:00
Víctor Fernández Poyatos
377faf145f feat(findings): Use ArrayAgg and subqueries on metadata endpoint (#6863)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-02-07 19:36:01 +05:45
Kay Agahd
69e316948f fix(aws): key error for detect-secrets (#6710) 2025-02-07 14:48:16 +01:00
Pablo Lara
62cbff4f53 feat: implement new functionality with inserted_at__gte in findings a… (#6864) 2025-02-07 14:25:25 +01:00
Víctor Fernández Poyatos
5582265e9d docs: Add details about user creation in Prowler app (#6862) 2025-02-07 13:29:25 +01:00
dependabot[bot]
fb5ea3c324 chore(deps): bump microsoft-kiota-abstractions from 1.9.1 to 1.9.2 (#6856)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-07 11:07:43 +01:00
Víctor Fernández Poyatos
9b5f676f50 feat(findings): Require date filters for findings endpoints (#6800) 2025-02-07 13:54:55 +05:45
Pranay Girase
88cfc0fa7e fix(typo): typos in Dashboard and Report in HTML (#6847) 2025-02-06 10:42:31 -05:00
Prowler Bot
665bfa2f13 chore(regions_update): Changes in regions for AWS services (#6848)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-06 08:46:32 -05:00
dependabot[bot]
b89b1a64f4 chore(deps): bump trufflesecurity/trufflehog from 3.88.4 to 3.88.5 (#6844)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-05 18:02:42 -05:00
Sergio Garcia
9ba657c261 fix(kms): handle error in DescribeKey function (#6839) 2025-02-05 14:03:31 -05:00
Mario Rodriguez Lopez
bce958b8e6 feat(entra): add new check entra_thirdparty_integrated_apps_not_allowed (#6357)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-05 12:45:48 -05:00
Daniel Barranquero
914012de2b fix(cloudfront): fix false positive in s3 origins (#6823) 2025-02-05 12:39:49 -05:00
Ogonna Iwunze
8d1c476aed feat(kms): add kms_cmk_not_multi_region AWS check (#6794)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-05 11:20:29 -05:00
Gary Mclean
567c729e9e fix(findings) Spelling mistakes correction (#6822) 2025-02-05 10:26:50 -05:00
Kay Agahd
3f03dd20e4 fix(aws) wording of report.status_extended in awslambda_function_not_publicly_accessible (#6824) 2025-02-05 10:23:52 -05:00
Daniel Barranquero
1c778354da fix(directoryservice): handle ClientException (#6781)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-05 10:22:32 -05:00
Prowler Bot
3a149fa459 chore(regions_update): Changes in regions for AWS services (#6821)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-02-05 09:19:56 -05:00
Mario Rodriguez Lopez
f3b121950d feat(entra): add new entra service for Microsoft365 (#6326)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-04 19:47:14 -05:00
Mario Rodriguez Lopez
43c13b7ba1 feat(microsoft365): add new check admincenter_settings_password_never_expire (#6023)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-04 17:24:11 -05:00
dependabot[bot]
9447b33800 chore(deps): bump kubernetes from 31.0.0 to 32.0.0 (#6678)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-04 17:22:51 -05:00
Hugo Pereira Brito
2934752eeb fix(elasticache): InvalidReplicationGroupStateFault error (#6815)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-04 14:28:31 -05:00
dependabot[bot]
dd6d8c71fd chore(deps-dev): bump moto from 5.0.27 to 5.0.28 (#6804)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-02-04 12:58:48 -05:00
Pablo Lara
80267c389b style(forms): improve spacing consistency (#6814) 2025-02-04 13:20:24 +01:00
Pablo Lara
acfbaf75d5 chore(forms): improvements to the sign-in and sign-up forms (#6813) 2025-02-04 12:46:07 +01:00
Pedro Martín
5f54377407 chore(aws_audit_manager_control_tower_guardrails): add checks to reqs (#6699) 2025-02-03 14:59:08 -05:00
Drew Kerrigan
552aa64741 docs(): add description of changed and new delta values to prowler app tutorial (#6801) 2025-02-03 20:51:03 +01:00
dependabot[bot]
d64f611f51 chore(deps): bump pytz from 2024.2 to 2025.1 (#6765)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 12:48:18 -05:00
dependabot[bot]
a96cc92d77 chore(deps-dev): bump mkdocs-material from 9.5.50 to 9.6.2 (#6799)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 11:37:02 -05:00
dependabot[bot]
3858cccc41 chore(deps-dev): bump pylint from 3.3.3 to 3.3.4 (#6721)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 10:32:42 -05:00
Pedro Martín
072828512a fix(cis_1.5_aws): add checks to needed reqs (#6695)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-02-03 10:32:20 -05:00
Pedro Martín
a73ffe5642 fix(cis_1.4_aws): add checks to needed reqs (#6696)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-02-03 10:32:10 -05:00
Pablo Lara
8e784a5b6d feat(scans): show scan details right after launch (#6791) 2025-02-03 16:08:47 +01:00
dependabot[bot]
1b6f9332f1 chore(deps): bump trufflesecurity/trufflehog from 3.88.2 to 3.88.4 (#6760)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 09:35:53 -05:00
secretcod3r
db8b472729 fix(gcp): fix wrong provider value in check (#6691) 2025-02-03 09:29:08 -05:00
Pedro Martín
867b371522 fix(cis_2.0_aws): add checks to needed reqs (#6694) 2025-02-03 09:28:04 -05:00
dependabot[bot]
c0d7c9fc7d chore(deps): bump google-api-python-client from 2.159.0 to 2.160.0 (#6720)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-03 09:27:17 -05:00
Pablo Lara
bb4685cf90 fix(findings): remove default status filtering (#6784) 2025-02-03 15:20:18 +01:00
Pablo Lara
6a95426749 fix(findings): order findings by inserted_at DESC (#6782) 2025-02-03 11:51:07 +01:00
Víctor Fernández Poyatos
ef6af8e84d feat(schedules): Rework daily schedule to always show the next scan (#6700) 2025-02-03 11:08:27 +01:00
Víctor Fernández Poyatos
763130f253 fix(celery): Kill celery worker process after every task to release memory (#6761) 2025-01-31 19:30:08 +05:45
Hugo Pereira Brito
1256c040e9 fix: microsoft365 mutelist (#6724) 2025-01-31 12:32:39 +01:00
dependabot[bot]
18b7b48a99 chore(deps): bump microsoft-kiota-abstractions from 1.6.8 to 1.9.1 (#6734)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-31 10:07:17 +01:00
Pepe Fagoaga
627c11503f fix(db_event): Handle other events (#6754) 2025-01-30 21:46:43 +05:45
Víctor Fernández Poyatos
712ba84f06 feat(scans): Optimize read queries during scans (#6753) 2025-01-30 20:51:12 +05:45
Pepe Fagoaga
5186e029b3 fix(set_report_color): Add more details to error (#6751) 2025-01-30 20:48:51 +05:45
Pablo Lara
5bfaedf903 fix: Enable hot reloading when using Docker Compose for UI (#6750) 2025-01-30 14:05:39 +01:00
Víctor Fernández Poyatos
5061da6897 feat(findings): Improve /findings/metadata performance (#6748) 2025-01-30 13:31:43 +01:00
Pepe Fagoaga
c159a28016 fix(neptune): correct service name (#6743) 2025-01-30 17:16:18 +05:45
Pepe Fagoaga
82a1b1c921 fix(finding): raise when generating invalid findings (#6738) 2025-01-30 15:59:38 +05:45
Pepe Fagoaga
bf2210d0f4 fix(acm): Key Error DomainName (#6739) 2025-01-30 15:54:31 +05:45
Kay Agahd
8f0772cb94 fix(aws): iam_user_with_temporary_credentials resource in OCSF (#6697)
Co-authored-by: Pepe Fagoaga <pepe@verica.io>
2025-01-30 15:28:21 +05:45
Pepe Fagoaga
5b57079ecd fix(sns): Add region to subscriptions (#6731) 2025-01-30 14:38:21 +05:45
Matt Johnson
350d759517 chore: Update Google Analytics ID across all docs.prowler.com sites. (#6730) 2025-01-30 12:47:01 +05:45
Pablo Lara
edd793c9f5 fix(scans): change label for next scan (#6725) 2025-01-29 10:46:49 +01:00
Víctor Fernández Poyatos
545c2dc685 fix(migrations): Use indexes instead of constraints to define an index (#6722) 2025-01-29 14:24:04 +05:45
Víctor Fernández Poyatos
84955c066c revert: Update Django DB manager to use psycopg3 and connection pooling (#6717) 2025-01-28 22:15:01 +05:45
Víctor Fernández Poyatos
06dd03b170 fix(scan-summaries): Improve efficiency on providers overview (#6716) 2025-01-28 21:56:29 +05:45
Pedro Martín
47bc2ed2dc fix(defender): add field to SecurityContacts (#6693) 2025-01-28 15:52:56 +01:00
Pablo Lara
44281afc54 fix(scans): filters and sorting for scan table (#6713) 2025-01-28 13:26:31 +01:00
Víctor Fernández Poyatos
4d2859d145 fix(scans, findings): Improve API performance ordering by inserted_at instead of id (#6711) 2025-01-28 16:41:58 +05:45
Pablo Lara
45d44a1669 fix: fixed bug when opening finding details while a scan is in progress (#6708) 2025-01-28 06:58:18 +01:00
dependabot[bot]
ddd83b340e chore(deps): bump uuid from 10.0.0 to 11.0.5 in /ui (#6516)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-26 13:39:42 +01:00
Mario Rodriguez Lopez
ccdb54d7c3 feat(m365): add Microsoft 365 provider (#5902)
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com>
Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-24 13:14:17 -05:00
Rubén De la Torre Vico
bcc246d950 fix(cloudsql): add trusted client certificates case for cloudsql_instance_ssl_connections (#6682) 2025-01-24 10:42:45 -05:00
dependabot[bot]
62139e252a chore(deps): bump azure-mgmt-web from 7.3.1 to 8.0.0 (#6680)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-24 12:40:11 +01:00
dependabot[bot]
86950c3a0a chore(deps): bump msgraph-sdk from 1.17.0 to 1.18.0 (#6679)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-24 10:47:09 +01:00
dependabot[bot]
f4865ef68d chore(deps): bump azure-storage-blob from 12.24.0 to 12.24.1 (#6666)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-24 09:44:16 +01:00
Pepe Fagoaga
ea7209e7ae chore: bump for next minor (#6672) 2025-01-23 13:13:08 -05:00
Hugo Pereira Brito
998c551cf3 fix(cloudwatch): NoneType object is not iterable (#6671) 2025-01-23 12:27:07 -05:00
Paolo Frigo
e6f29b0116 docs: update # of checks, services, frameworks and categories (#6528)
Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-23 11:11:03 -05:00
Pepe Fagoaga
eb90bb39dc chore(api): Bump to v1.3.0 (#6670) 2025-01-23 21:25:29 +05:45
Pepe Fagoaga
ad189b35ad chore(scan): Remove ._findings (#6667) 2025-01-23 20:43:02 +05:45
Pablo Lara
7d2989a233 chore: adjust DateWithTime component height when used with InfoField (#6669) 2025-01-23 15:18:24 +01:00
Pablo Lara
862137ae7d chore(scans): improve scan details (#6665) 2025-01-23 13:20:41 +01:00
Pedro Martín
c86e082d9a feat(detect-secrets): get secrets plugins from config.yaml (#6544)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-01-23 17:18:19 +05:45
Sergio Garcia
80fe048f97 feat(resource metadata): add resource metadata to JSON OCSF (#6592)
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2025-01-23 16:06:30 +05:45
dependabot[bot]
f2bffb3ce7 chore(deps): bump azure-mgmt-containerservice from 33.0.0 to 34.0.0 (#6630)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 16:37:07 -05:00
dependabot[bot]
cbe2f9eef8 chore(deps): bump azure-mgmt-compute from 33.1.0 to 34.0.0 (#6628)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 20:00:56 +01:00
Pepe Fagoaga
688f41f570 fix(templates): Customize principals and add validation (#6655) 2025-01-22 21:47:57 +05:45
Anton Rubets
a29197637e chore(helm): Add prowler helm support (#6580)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-22 10:55:26 -05:00
Prowler Bot
7a2712a37f chore(regions_update): Changes in regions for AWS services (#6652)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-22 09:30:03 -05:00
dependabot[bot]
189f5cfd8c chore(deps): bump boto3 from 1.35.94 to 1.35.99 (#6651)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-22 09:29:41 -05:00
Kay Agahd
e509480892 fix: add detector and line number of potential secret (#6654) 2025-01-22 20:13:23 +05:45
Pepe Fagoaga
7f7955351a chore(pre-commit): poetry checks for API and SDK (#6658) 2025-01-22 20:05:26 +05:45
Pepe Fagoaga
46f1db21a8 chore(api): Use prowler from master (#6657) 2025-01-22 20:05:02 +05:45
Pablo Lara
fbe7bc6951 feat(providers): show the cloud formation and terraform template links on the form (#6660) 2025-01-22 14:49:38 +01:00
Pablo Lara
f658507847 feat(providers): make external id field mandatory in the aws role secret form (#6656) 2025-01-22 12:45:31 +01:00
dependabot[bot]
374078683b chore(deps-dev): bump moto from 5.0.16 to 5.0.27 (#6632)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-21 13:56:06 -05:00
dependabot[bot]
114c4e0886 chore(deps): bump botocore from 1.35.94 to 1.35.99 (#6520)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-21 09:17:18 -05:00
Pablo Lara
67c62766d4 fix(filters): fix dynamic filters (#6642) 2025-01-21 13:33:27 +01:00
dependabot[bot]
3f2947158d chore(deps): bump prowler from 5.1.1 to 5.1.4 in /api (#6641)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-21 14:27:59 +05:45
dependabot[bot]
278a7cb356 chore(deps-dev): bump mkdocs-material from 9.5.49 to 9.5.50 (#6631)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-20 18:31:44 -05:00
Rubén De la Torre Vico
890158a79c fix(OCSF): fix OCSF output when timestamp is UNIX format (#6606) 2025-01-20 17:11:28 -05:00
Rubén De la Torre Vico
4dc1602b77 fix: update Azure CIS with existing App checks (#6611) 2025-01-20 15:12:00 -05:00
Kay Agahd
bbba0abac9 fix(aws): list tags for DocumentDB clusters (#6605) 2025-01-20 15:10:58 -05:00
Prowler Bot
d04fd807c6 chore(regions_update): Changes in regions for AWS services (#6599)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-20 15:09:35 -05:00
Pablo Lara
3456df4cf1 fix(snippet-id): improve provider ID readability in tables (#6615) 2025-01-20 17:23:19 +01:00
Pablo Lara
f56aaa791e chore(RBAC): add permission's info (#6612) 2025-01-20 16:14:48 +01:00
Adrián Jesús Peña Rodríguez
465a758770 fix(rbac): remove invalid required permission (#6608) 2025-01-20 15:21:52 +01:00
Pablo Lara
0f7c0c1b2c fix(RBAC): tweaks for edit role form (#6609) 2025-01-20 14:09:16 +01:00
Adrián Jesús Peña Rodríguez
bf8d10b6f6 feat(api): restrict the deletion of users, only the user of the request can be deleted (#6607) 2025-01-20 13:26:47 +01:00
Pablo Lara
20d04553d6 fix(RBAC): restore manage_account permission for roles (#6602) 2025-01-20 11:35:29 +01:00
Daniel Barranquero
b56d62e3c4 fix(sqs): fix flaky test (#6593) 2025-01-17 11:48:39 -05:00
Hugo Pereira Brito
9a332dcba1 chore(services): delete all comment headers (#6585) 2025-01-17 08:21:28 -05:00
Hugo Pereira Brito
166d9f8823 fix(apigatewayv2): managed exception NotFoundException (#6576) 2025-01-17 08:17:51 -05:00
Prowler Bot
42f5eed75f chore(regions_update): Changes in regions for AWS services (#6577)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-17 08:17:00 -05:00
Rubén De la Torre Vico
01a7db18dd fix: add missing Check_Report_Azure parameters (#6583) 2025-01-17 08:16:43 -05:00
Pablo Lara
d4507465a3 fix(providers): update the label and placeholder based on the cloud provider (#6581) 2025-01-17 12:28:38 +01:00
Pablo Lara
3ac92ed10a fix(findings): remove filter delta_in applied by default (#6578) 2025-01-17 11:03:12 +01:00
Pablo Lara
43c76ca85c feat(findings): add first seen in findings details (#6575) 2025-01-17 10:19:10 +01:00
dependabot[bot]
54d87fa96a chore(deps): bump prowler from 5.0.2 to 5.1.1 in /api (#6573)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-17 13:26:07 +05:45
Daniel Barranquero
f041f17268 fix(gcp): fix flaky tests from dns service (#6569) 2025-01-16 14:49:25 -05:00
dependabot[bot]
31c80a6967 chore(deps): bump msgraph-sdk from 1.16.0 to 1.17.0 (#6547)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-16 12:55:30 -05:00
Rubén De la Torre Vico
783ce136f4 feat(network): extract Network resource metadata automated (#6555)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-16 12:41:02 -05:00
Rubén De la Torre Vico
f829145781 feat(storage): extract Storage resource metadata automated (#6563)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-16 11:44:43 -05:00
Rubén De la Torre Vico
389337f8cd feat(vm): extract VM resource metadata automated (#6564) 2025-01-16 11:16:02 -05:00
Pedro Martín
a0713c2d66 fix(cis): add subsections if needed (#6559) 2025-01-16 11:10:54 -05:00
Rubén De la Torre Vico
f94d3cbce4 feat(sqlserver): extract SQL Server resource metadata automated (#6562) 2025-01-16 10:47:21 -05:00
Daniel Barranquero
8d8994b468 feat(aws): include resource metadata to remaining checks (#6551)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-16 10:44:14 -05:00
Rubén De la Torre Vico
784a9097a5 feat(postgresql): extract PostgreSQL resource metadata automated (#6560) 2025-01-16 10:37:55 -05:00
Pedro Martín
b9601626e3 fix(detect_secrets): refactor logic for detect-secrets (#6537) 2025-01-16 21:15:44 +05:45
Rubén De la Torre Vico
dc80b011f2 feat(policy): extract Policy resource metadata automated (#6558) 2025-01-16 10:29:28 -05:00
Rubén De la Torre Vico
ee7d32d460 feat(entra): extract Entra resource metadata automated (#6542)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-16 10:24:53 -05:00
Rubén De la Torre Vico
43fd9ee94e feat(monitor): extract monitor resource metadata automated (#6554)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-16 10:16:19 -05:00
Víctor Fernández Poyatos
8821a91f3f feat(db): Update Django DB manager to use psycopg3 and connection pooling (#6541) 2025-01-16 15:29:02 +01:00
Rubén De la Torre Vico
98d9256f92 feat(mysql): extract MySQL resource metadata automated (#6556) 2025-01-16 09:24:06 -05:00
Rubén De la Torre Vico
b35495eaa7 feat(keyvault): extract KeyVault resource metadata automated (#6553) 2025-01-16 09:17:36 -05:00
Rubén De la Torre Vico
74d6b614b3 feat(iam): extract IAM resource metadata automated (#6552) 2025-01-16 09:05:23 -05:00
Sergio Garcia
dd63c16a74 fix(gcp): iterate through service projects (#6549)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2025-01-16 08:52:52 -05:00
Pablo Lara
4280266a96 fix(dep): address compatibility issues (#6543) 2025-01-16 14:28:49 +01:00
Hugo Pereira Brito
b1f02098ff feat(aws): include resource metadata in services from r* to s* (#6536)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-15 18:10:53 -05:00
Pedro Martín
95189b574a feat(gcp): add resource metadata to report (#6500)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-15 18:09:35 -05:00
Hugo Pereira Brito
c5d23503bf feat(aws): include resource metadata in services from a* to b* (#6504)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-15 18:03:37 -05:00
Daniel Barranquero
77950f6069 chore(aws): add resource metadata to services from t to w (#6546) 2025-01-15 17:22:08 -05:00
Daniel Barranquero
ec5f2b3753 chore(aws): add resource metadata to services from f to o (#6545) 2025-01-15 17:15:50 -05:00
Rubén De la Torre Vico
9e7104fb7f feat(defender): extract Defender resource metadata in automated way (#6538) 2025-01-15 12:14:24 -05:00
Rubén De la Torre Vico
6b3b6ca45e feat(appinsights): extract App Insights resource metadata in automated way (#6540) 2025-01-15 11:45:23 -05:00
Hugo Pereira Brito
20b8b0b24e feat: add resource metadata to emr_cluster_account_public_block_enabled (#6539) 2025-01-15 11:44:51 -05:00
Sergio Garcia
4e11540458 feat(kubernetes): add resource metadata to report (#6479) 2025-01-15 11:36:09 -05:00
Hugo Pereira Brito
ee87f2676d feat(aws): include resource metadata in services from d* to e* (#6532)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-15 10:05:04 -05:00
Daniel Barranquero
74a90aab98 feat(aws): add resource metadata to all services starting with c (#6493) 2025-01-15 09:04:19 -05:00
Rubén De la Torre Vico
48ff9a5100 feat(cosmosdb): extract CosmosDB resource metadata in automated way (#6533) 2025-01-15 08:51:48 -05:00
Rubén De la Torre Vico
3dfd578ee5 feat(containerregistry): extract Container Registry resource metadata in automated way (#6530) 2025-01-15 08:51:16 -05:00
Rubén De la Torre Vico
0db46cdc81 feat(azure-app): extract Web App resource metadata in automated way (#6529) 2025-01-15 08:48:36 -05:00
Prowler Bot
fdac58d031 chore(regions_update): Changes in regions for AWS services (#6526)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-15 08:46:35 -05:00
dependabot[bot]
df9d4ce856 chore(deps): bump google-api-python-client from 2.158.0 to 2.159.0 (#6521)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-15 08:33:47 -05:00
Pedro Martín
e6ae4e97e8 docs(readme): update pr template to add check for readme (#6531) 2025-01-15 12:12:45 +01:00
Adrián Jesús Peña Rodríguez
10a4c28922 feat(finding): add first_seen attribute (#6460) 2025-01-15 11:25:41 +01:00
dependabot[bot]
8a828c6e51 chore(deps): bump django from 5.1.4 to 5.1.5 in /api (#6519)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-15 10:52:11 +01:00
Víctor Fernández Poyatos
d7b40905ff feat(findings): Add resource_tag filters for findings endpoint (#6527) 2025-01-15 10:30:36 +01:00
Adrián Jesús Peña Rodríguez
f9a3b5f3cd feat(provider-secret): make existing external_id field mandatory (#6510) 2025-01-15 10:14:44 +01:00
Pablo Lara
b73b89242f feat(filters): add resource type filter for findings (#6524) 2025-01-15 08:40:53 +01:00
dependabot[bot]
23a0f6e8de chore(deps-dev): bump eslint-config-prettier from 9.1.0 to 10.0.1 in /ui (#6518)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-15 06:55:25 +01:00
Pedro Martín
87967abc3f feat(kubernetes): add CIS 1.10 compliance (#6508)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-14 14:16:00 -05:00
Rubén De la Torre Vico
ce60c286dc feat(aks): use Check_Report_Azure constructor properly in AKS checks (#6509) 2025-01-14 14:14:02 -05:00
Pepe Fagoaga
90fd9b0eb8 chore(version): set next minor (#6511) 2025-01-14 14:06:24 -05:00
Prowler Bot
ca262a6797 chore(regions_update): Changes in regions for AWS services (#6495)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-14 12:43:44 -05:00
Rubén De la Torre Vico
c056d39775 feat(aisearch): use Check_Report_Azure constructor properly in AISearch checks (#6506) 2025-01-14 12:37:01 -05:00
johannes-engler-mw
1c4426ea4b fix(Azure TDE): add filter for master DB (#6351) 2025-01-14 12:34:52 -05:00
Pedro Martín
36520bd7a1 feat(azure): add CIS 3.0 for Azure (#5226) 2025-01-14 12:07:22 -05:00
Pepe Fagoaga
badf0ace76 feat(prowler-role): Add templates to deploy it in AWS (#6499) 2025-01-14 12:04:20 -05:00
Rubén De la Torre Vico
f1f61249e0 feat(azure): include resource metadata in Check_Report_Azure (#6505) 2025-01-14 11:32:40 -05:00
dependabot[bot]
b371cac18c chore(deps): bump jinja2 from 3.1.4 to 3.1.5 (#6457)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 10:03:45 -05:00
Víctor Fernández Poyatos
1846535d8d feat(findings): add /findings/metadata to retrieve dynamic filters information (#6503) 2025-01-14 15:30:03 +01:00
dependabot[bot]
d7d9118b9b chore(deps-dev): bump bandit from 1.8.0 to 1.8.2 (#6485)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 08:49:37 -05:00
Pablo Lara
a65ca72177 chore(groups): Enable updating groups without roles or providers (#6498) 2025-01-14 11:16:13 +01:00
Pablo Lara
1108d90768 chore(roles): prevent capitalization of provider groups and roles (#6497) 2025-01-14 10:41:08 +01:00
Adrián Jesús Peña Rodríguez
6715aa351f fix(rbac): block admin role deletion (#6470) 2025-01-14 10:27:41 +01:00
dependabot[bot]
851497eb0a chore(deps): bump @radix-ui/react-slot from 1.1.0 to 1.1.1 in /ui (#6481)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 10:25:14 +01:00
dependabot[bot]
3bb4663e3e chore(deps-dev): bump eslint-plugin-import from 2.29.1 to 2.31.0 in /ui (#6482)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-14 10:24:31 +01:00
Pablo Lara
6953fcf6b5 chore(rbac): tweaks role permissions (#6496) 2025-01-14 10:23:23 +01:00
Adrián Jesús Peña Rodríguez
ab844eee3f ref(rbac): disable some checks (#6471) 2025-01-14 09:33:15 +01:00
Pedro Martín
708e06aa3b fix(iso27001-2013): add ReqId and ReqDescription in output (#6405) 2025-01-13 13:14:09 -05:00
Prowler Bot
aa8b8bbcae chore(regions_update): Changes in regions for AWS services (#6459)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-13 12:41:11 -05:00
Pablo Lara
0ce1e15c2c styles(invitations): tweak styles for invitation details box (#6475) 2025-01-13 18:32:33 +01:00
Pablo Lara
105a83d946 fix(invitation): correct the URL used to share an invitation (#6472) 2025-01-13 17:27:10 +01:00
Pedro Martín
e9a885a54d feat(compliance): add CIS 3.0 for gcp (#6463) 2025-01-13 10:59:53 -05:00
Pablo Lara
0a8759ee06 chore(manage-groups): tweaks for provider manage groups (#6468) 2025-01-13 16:39:14 +01:00
Prowler Bot
33ec21bbac chore(regions_update): Changes in regions for AWS services (#6458)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-13 10:37:43 -05:00
dependabot[bot]
7c00f65ecc chore(deps): bump @radix-ui/react-toast from 1.2.1 to 1.2.4 in /ui (#6445)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-13 15:55:56 +01:00
Rubén De la Torre Vico
7777c8f135 fix(vpc): add new principal wildcard verification (#6461) 2025-01-13 09:49:10 -05:00
dependabot[bot]
2386490002 chore(deps-dev): bump openapi-schema-validator from 0.6.2 to 0.6.3 (#6454)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-13 09:36:31 -05:00
Pepe Fagoaga
b620f12027 chore(rls): Add tenant_id filters in views and improve querysets (#6211)
Co-authored-by: Víctor Fernández Poyatos <victor@prowler.com>
2025-01-13 11:37:40 +01:00
Rubén De la Torre Vico
00722181ad docs(azure): improve tutorials for Prowler App (#6210) 2025-01-13 09:59:58 +01:00
Sergio Garcia
15e888a939 feat(ec2): include resource metadata in Check_Report (#6440) 2025-01-13 13:04:55 +05:45
dependabot[bot]
43fa600f1c chore(deps): bump date-fns from 3.6.0 to 4.1.0 in /ui (#6444)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-11 08:35:18 +01:00
dependabot[bot]
2e4b5399c9 chore(deps): bump lucide-react from 0.417.0 to 0.471.0 in /ui (#6456)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-11 08:34:47 +01:00
Prowler Bot
62cbb442e8 chore(regions_update): Changes in regions for AWS services (#6448)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-10 11:36:43 -05:00
Pedro Martín
b0fe696935 refactor(mutelist): use jsonschema on mutelist (#6264) 2025-01-10 20:04:20 +05:45
Matt Johnson
42dbefbb31 feat: New gen-ai category for all relevant checks. (#6450) 2025-01-10 08:57:20 -05:00
Daniel Barranquero
f3dbe28681 fix(codeartifact): fix flaky tests (#6449) 2025-01-10 18:16:00 +05:45
Pedro Martín
6a5f1a7839 docs(integrations): add integrations docs (#6269) 2025-01-10 17:00:20 +05:45
Pedro Martín
3b70f9fed4 docs(outputs): add custom outputs formats documentation (#6386) 2025-01-10 16:54:50 +05:45
dependabot[bot]
7eb01aaa5c chore(deps-dev): bump safety from 3.2.3 to 3.2.9 in /api (#6431)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-10 16:31:19 +05:45
dependabot[bot]
1e27e52fba chore(deps-dev): bump vulture from 2.11 to 2.14 in /api (#6426)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-10 15:14:55 +05:45
dependabot[bot]
16d73619e4 chore(deps): bump boto3 from 1.35.93 to 1.35.94 (#6410)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-09 19:29:59 -05:00
dependabot[bot]
bc82696f15 chore(deps): bump google-api-python-client from 2.157.0 to 2.158.0 (#6442)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-09 18:16:23 -05:00
dependabot[bot]
fdb90623fc chore(deps): bump trufflesecurity/trufflehog from 3.88.1 to 3.88.2 (#6446)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-09 17:52:12 -05:00
Prowler Bot
5fa62a9770 chore(regions_update): Changes in regions for AWS services (#6399)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-09 14:57:30 -05:00
Pablo Lara
8f3df7e45d fix(BC: NextUI): fix BC from NextUI, resolve ESLint warnings and optimize hooks dependencies (#6404) 2025-01-09 17:37:33 +01:00
dependabot[bot]
bb417587ae chore(deps-dev): bump @iconify/react from 5.0.1 to 5.2.0 in /ui (#6421)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-09 17:05:11 +01:00
dependabot[bot]
6b6e12cea3 chore(deps): bump jinja2 from 3.1.4 to 3.1.5 in /api (#6316)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-09 20:39:02 +05:45
Pepe Fagoaga
65e70b2ca4 chore(dependabot): Review for API and UI (#6402) 2025-01-09 20:28:26 +05:45
Pepe Fagoaga
94d25f6f6a chore(containers): Build stable for API and UI (#6395) 2025-01-09 20:24:57 +05:45
Sergio Garcia
4bcf036831 fix(iam): handle non existing MFA devices (#6396) 2025-01-09 09:23:05 -05:00
dependabot[bot]
901bc69a7d chore(deps): bump django from 5.1.1 to 5.1.4 in /api (#6376)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-09 13:36:58 +01:00
Adrián Jesús Peña Rodríguez
465217442b fix(api): change the inserted_at.lte unittest (#6403) 2025-01-09 13:12:55 +01:00
Pablo Lara
e6b40358aa feat(update-credentials): add explanation text for the current behavior (#6400) 2025-01-09 11:13:36 +01:00
Daniel Barranquero
9d48f7286a fix(cloudformation): fix flaky tests (#6398) 2025-01-09 15:30:11 +05:45
Prowler Bot
80311d3837 chore(regions_update): Changes in regions for AWS services (#6390)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-08 12:28:24 -05:00
Pedro Martín
f501149068 fix(pre-commit): add api needed excludes (#6393) 2025-01-08 16:34:55 +01:00
dependabot[bot]
750de62828 chore(deps): bump botocore from 1.35.93 to 1.35.94 (#6388)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-08 10:32:34 -05:00
Pablo Lara
d2f338ceb6 feat(scans): add new component - alert bar 2025-01-08 11:01:52 +01:00
dependabot[bot]
e8d66979b3 chore(deps): bump azure-mgmt-network from 28.0.0 to 28.1.0 (#6296)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 16:09:53 -05:00
Sergio Garcia
b5180389f8 feat(aws): add new check cloudformation_stack_cdktoolkit_bootstrap_version (#6323) 2025-01-07 14:52:55 -05:00
dependabot[bot]
fbd5235e15 chore(deps): bump msgraph-sdk from 1.15.0 to 1.16.0 (#6350)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 13:56:02 -05:00
dependabot[bot]
afd2267c26 chore(deps): bump microsoft-kiota-abstractions from 1.6.7 to 1.6.8 (#6347)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 11:40:57 -05:00
dependabot[bot]
9e798ababd chore(deps): bump google-api-python-client from 2.156.0 to 2.157.0 (#6349)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 10:40:20 -05:00
Prowler Bot
e9f2fc8ee1 chore(regions_update): Changes in regions for AWS services (#6382)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-07 10:11:24 -05:00
dependabot[bot]
12198b4f06 chore(deps): bump boto3 from 1.35.87 to 1.35.93 (#6381)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 09:20:20 -05:00
Adrián Jesús Peña Rodríguez
15fae4d8f8 fix(ci): move poetry deprecated command to new one (#6384) 2025-01-07 12:38:33 +01:00
dependabot[bot]
3de3fed858 chore(deps): bump next from 14.2.12 to 14.2.22 in /ui (#6356)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 12:29:06 +01:00
dependabot[bot]
1bf4255d93 chore(deps): bump cookie and next-auth in /ui (#5880)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2025-01-07 12:03:45 +01:00
dependabot[bot]
b91a132e61 chore(deps): bump azure-mgmt-compute from 33.0.0 to 33.1.0 (#6219)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 12:02:47 +01:00
dependabot[bot]
39302c9e93 chore(deps): bump botocore from 1.35.88 to 1.35.93 (#6373)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2025-01-06 22:59:41 -05:00
dependabot[bot]
65e21c4268 chore(deps): bump trufflesecurity/trufflehog from 3.88.0 to 3.88.1 (#6372)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-06 18:06:28 -05:00
Rubén De la Torre Vico
3d6a6a9fec fix(aws): add missing sqs service without subservice (#6352) 2025-01-06 12:48:18 -05:00
Rubén De la Torre Vico
d185902c86 docs: add new format CloudFormation for ResourceType in check metadata (#6353)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2025-01-06 10:25:00 -05:00
Prowler Bot
8ce4ad83ed chore(regions_update): Changes in regions for AWS services (#6329)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2025-01-06 10:16:57 -05:00
dependabot[bot]
89620a96bc chore(deps): bump botocore from 1.35.87 to 1.35.88 (#6321)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-27 12:21:12 -05:00
dependabot[bot]
f1c008f934 chore(deps-dev): bump coverage from 7.6.9 to 7.6.10 (#6322)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-27 09:59:40 -05:00
dependabot[bot]
4d688c9b47 chore(deps): bump boto3 from 1.35.85 to 1.35.87 (#6320)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-26 19:01:01 -05:00
dependabot[bot]
db5481cc9c chore(deps-dev): bump pylint from 3.3.2 to 3.3.3 (#6317)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-26 13:50:20 -05:00
dependabot[bot]
ce9a5e6484 chore(deps): bump botocore from 1.35.85 to 1.35.87 (#6307)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-26 09:18:02 -05:00
Víctor Fernández Poyatos
550165b42b feat(compliance): generate compliance reports for GCP scans using API (#6318) 2024-12-26 13:31:20 +01:00
Prowler Bot
080551132a chore(regions_update): Changes in regions for AWS services (#6299)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2024-12-23 08:35:48 -05:00
dependabot[bot]
0a61848365 chore(deps): bump boto3 from 1.35.83 to 1.35.85 (#6295)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-23 07:41:45 -05:00
dependabot[bot]
fcb9ca7795 chore(deps): bump trufflesecurity/trufflehog from 3.87.2 to 3.88.0 (#6298)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-23 07:41:23 -05:00
Víctor Fernández Poyatos
71c58cee9e fix(migrations): fix django migration order dependency (#6302) 2024-12-23 12:26:00 +01:00
Sergio Garcia
c811b6715d fix(gha): run API and UI tests in correct versions (#6294) 2024-12-23 11:47:51 +01:00
Kay Agahd
231829d8cd fix(aws): disallow child-accounts to overwrite policy for ai_services_opt_out (#6229)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2024-12-20 11:04:42 -05:00
dependabot[bot]
dbd2f8becb chore(deps): bump botocore from 1.35.83 to 1.35.85 (#6276)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-20 09:47:05 -05:00
Prowler Bot
cc04e6614e chore(regions_update): Changes in regions for AWS services (#6282)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2024-12-20 09:46:55 -05:00
Pablo Lara
a5c5ed614c chore(menu): add API reference link to the sidebar (#6287) 2024-12-20 15:04:29 +01:00
Víctor Fernández Poyatos
ea13241317 fix(users): fix /users/me behavior when having more than 1 users in the same tenant (#6284) 2024-12-20 09:01:23 -05:00
Sergio Garcia
a377a9ff6a chore(gha): solve pypi release github action (#6278) 2024-12-20 08:57:29 -05:00
Víctor Fernández Poyatos
f7e510b333 fix(db-utils): fix batch_delete function (#6283) 2024-12-20 08:55:21 -05:00
Pablo Lara
4472b80f1c chore(findings): remove delta new as filter by default in findings (#6280) 2024-12-20 09:36:01 +01:00
dependabot[bot]
577eb3eec9 chore(deps): bump msgraph-sdk from 1.14.0 to 1.15.0 (#6250)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-20 09:34:46 +01:00
dependabot[bot]
1ed6a1a40f chore(deps): bump trufflesecurity/trufflehog from 3.87.1 to 3.87.2 (#6279)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-19 17:51:41 -05:00
Sergio Garcia
fe4cd1cddf fix(aws): add missing region to Backup Recovery Point (#6273) 2024-12-19 16:08:22 -05:00
Pablo Lara
6d7a8c8130 feat(roles): RBAC functionality (#6201) 2024-12-19 18:35:10 +01:00
dependabot[bot]
3057aeeacf chore(deps): bump slack-sdk from 3.33.5 to 3.34.0 (#6254)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-19 12:27:35 -05:00
Sergio Garcia
bb5b63f62f fix(aws): solve None type errors (#6268) 2024-12-19 11:32:33 -05:00
Prowler Bot
58cd944618 chore(regions_update): Changes in regions for AWS services (#6262)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2024-12-19 10:05:09 -05:00
Daniel Barranquero
5964b68c86 feat(codeartifact): add new fixer codeartifact_packages_external_public_publishing_disabled_fixer (#6263) 2024-12-19 10:05:01 -05:00
Pepe Fagoaga
c87aaeba04 chore(api): Use prowler ^5.0 (#6266) 2024-12-19 09:40:51 -05:00
dependabot[bot]
6e361005dc chore(deps): bump trufflesecurity/trufflehog from 3.87.0 to 3.87.1 (#6249)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-19 09:02:44 -05:00
dependabot[bot]
f5ab254bc5 chore(deps): bump microsoft-kiota-abstractions from 1.6.6 to 1.6.7 (#6233)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-19 09:02:01 -05:00
dependabot[bot]
298392b409 chore(deps): bump google-api-python-client from 2.155.0 to 2.156.0 (#6252)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-19 11:10:10 +01:00
Twodragon
74a2bf0721 feat(prowler-docker): Run Prowler docker with AWS SSO (#5867)
Co-authored-by: twodragon114 <twodragon114@gmail.com>
Co-authored-by: pedrooot <pedromarting3@gmail.com>
2024-12-19 10:55:15 +01:00
dependabot[bot]
ddc5dc0316 chore(deps): bump boto3 from 1.35.81 to 1.35.83 (#6253)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-19 09:45:16 +01:00
Pepe Fagoaga
d3af947553 fix(gha): make conditional job for checking the repo (#6255) 2024-12-19 14:19:41 +05:45
Pepe Fagoaga
36bb2509ac docs: add note about platform flag in docker (#6256) 2024-12-19 14:18:16 +05:45
Pepe Fagoaga
e4c2b0c2d3 chore: skip action on .env changes (#6257) 2024-12-19 14:17:56 +05:45
Víctor Fernández Poyatos
ac5260ad43 feat(celery): Add configurable broker visibility timeout setting (#6245) 2024-12-19 00:03:11 +05:45
Adrián Jesús Peña Rodríguez
33857109c9 ref(rbac): enable relationship creation when objects is created (#6238) 2024-12-18 16:45:32 +01:00
Pepe Fagoaga
8cc8f76204 fix(.env): remove comment (#6230) 2024-12-18 20:36:03 +05:45
Pedro Martín
8f3229928e chore(config): set default values for empty config fields (#6225) 2024-12-18 09:48:32 -05:00
Pedro Martín
2551992fd8 fix(docs): change typo from provideruid in k8s (#6239)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2024-12-18 09:02:44 -05:00
Prowler Bot
eb1decfce1 chore(regions_update): Changes in regions for AWS services (#6237)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2024-12-18 08:51:22 -05:00
Pepe Fagoaga
fd5e7b809f docs: add note about containers arch (#6236) 2024-12-18 11:09:35 +01:00
dependabot[bot]
1ac681226d chore(deps): bump botocore from 1.35.81 to 1.35.83 (#6232)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-17 18:52:46 -05:00
dependabot[bot]
366940298d chore(deps): bump trufflesecurity/trufflehog from 3.86.1 to 3.87.0 (#6234)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-17 18:51:32 -05:00
Adrián Jesús Peña Rodríguez
fa400ded7d ref(rbac): improve rbac implementation for views (#6226) 2024-12-17 18:11:48 +01:00
dependabot[bot]
ec9455ff75 chore(deps): bump boto3 from 1.35.80 to 1.35.81 (#6218)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-17 11:32:30 -05:00
Daniel Barranquero
2183f31ff5 feat(ec2): add new fixers for internet exposed ports (#6223) 2024-12-17 10:04:00 -05:00
Prowler Bot
67257a4212 chore(regions_update): Changes in regions for AWS services (#6222)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2024-12-17 10:00:52 -05:00
Pedro Martín
001fa60a11 feat(mutelist): add description field (#6221)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2024-12-17 15:13:55 +01:00
Víctor Fernández Poyatos
0ec3ed8be7 feat(services): Add GET /overviews/services to API (#6029) 2024-12-17 08:47:44 +01:00
dependabot[bot]
3ed0b8a464 chore(deps-dev): bump mkdocs-material from 9.5.48 to 9.5.49 (#6217)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-17 08:42:55 +01:00
Pedro Martín
fd610d44c0 refactor(gcp): use always <client>.region for checks (#6206) 2024-12-16 18:21:42 -05:00
Adrián Jesús Peña Rodríguez
b8cc4b4f0f feat(stepfunctions): add stepfunctions service and check stepfunctions_statemachine_logging_enabled (#5466)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
Co-authored-by: Rubén De la Torre Vico <rubendltv22@gmail.com>
2024-12-16 11:34:02 -05:00
Pedro Martín
396e51c27d feat(gcp): add service account credentials (#6165) 2024-12-16 10:11:32 -05:00
Daniel Barranquero
36e61cb7a2 feat(ec2): add new fixer ec2_ami_public_fixer (#6177) 2024-12-16 10:09:14 -05:00
Daniel Barranquero
78c6484ddb feat(cloudtrail): add new fixer cloudtrail_logs_s3_bucket_is_not_publicly_accessible_fixer (#6174) 2024-12-16 10:05:34 -05:00
Daniel Barranquero
3f1e90a5b3 feat(s3): add new fixer s3_bucket_policy_public_write_access_fixer (#6173) 2024-12-16 10:01:38 -05:00
dependabot[bot]
e1bfec898f chore(deps): bump botocore from 1.35.80 to 1.35.81 (#6199)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-16 09:57:03 -05:00
dependabot[bot]
b5b816dac9 chore(deps): bump boto3 from 1.35.79 to 1.35.80 (#6198)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-16 07:51:44 -05:00
Pepe Fagoaga
57854f23b7 chore(rls): rename tenant_transaction to rls_transaction (#6202) 2024-12-16 12:27:55 +01:00
Rubén De la Torre Vico
9d7499b74f fix(azure): custom Prowler Role for Azure assignableScopes (#6149) 2024-12-16 08:34:17 +01:00
dependabot[bot]
5b0b85c0f8 chore(deps): bump actions/setup-node from 3 to 4 (#5893)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-13 14:57:27 +01:00
Pedro Martín
f7e8df618b chore(labeler): add provider github (#6194) 2024-12-13 09:43:49 -04:00
Adrián Jesús Peña Rodríguez
d00d254c90 feat(api): RBAC system (#6114) 2024-12-13 14:14:40 +01:00
dependabot[bot]
f9fbde6637 chore(deps): bump botocore from 1.35.79 to 1.35.80 (#6172)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-13 13:20:40 +01:00
Sergio Garcia
7b1a0474db fix(aws): set unique resource IDs (#6152) 2024-12-13 13:00:38 +01:00
Pepe Fagoaga
da4f9b8e5f fix(RLS): enforce config security (#6066) 2024-12-13 12:55:09 +01:00
Pepe Fagoaga
32f69d24b6 fix: dependabot syntax (#6181) 2024-12-13 12:20:43 +01:00
Pepe Fagoaga
d032a61a9e chore(dependabot): Add docker (#6180) 2024-12-13 12:13:53 +01:00
dependabot[bot]
07e0dc2ef5 chore(deps): bump cross-spawn from 7.0.3 to 7.0.6 in /ui (#5881)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2024-12-13 08:25:57 +01:00
dependabot[bot]
9e175e8504 chore(deps): bump nanoid from 3.3.7 to 3.3.8 in /ui (#6110)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-13 07:59:50 +01:00
dependabot[bot]
6b8a434cda chore(deps): bump boto3 from 1.35.78 to 1.35.79 (#6171)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-13 07:58:58 +01:00
Pepe Fagoaga
554491a642 chore(gha): build and push OSS UI (#6168) 2024-12-12 19:10:44 +01:00
Pedro Martín
dc4e2f3c85 feat(GHA): build containers for API (#6032)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2024-12-12 19:05:25 +01:00
Daniel Barranquero
7d2c50991b feat(s3): add new fixer s3_bucket_public_access_fixer (#6164)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2024-12-12 12:17:41 -04:00
Pedro Martín
83c204e010 fix(rds): add invalid SG to status_extended (#6157) 2024-12-12 11:51:09 -04:00
dependabot[bot]
316eb049dd chore(deps): bump botocore from 1.35.78 to 1.35.79 (#6153)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-12 11:29:23 -04:00
Daniel Barranquero
be347b2428 feat(ec2): add new check ec2_launch_template_imdsv2_required (#6139)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2024-12-12 11:27:20 -04:00
Daniel Barranquero
a90c772827 feat(s3): add new fixer s3_bucket_public_list_acl_fixer (#6166) 2024-12-12 11:16:46 -04:00
Daniel Barranquero
26c70976c0 feat(s3): add new fixer s3_bucket_public_write_acl_fixer (#5855) 2024-12-12 11:10:43 -04:00
dependabot[bot]
657310dc25 chore(deps): bump boto3 from 1.35.77 to 1.35.78 (#6154)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-12 10:39:22 -04:00
Daniel Barranquero
6e595eaf92 feat(ec2): add new fixer ec2_instance_port_cifs_exposed_to_internet_fixer (#6159) 2024-12-12 09:22:56 -04:00
Prowler Bot
997831e33d chore(regions_update): Changes in regions for AWS services (#6158)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2024-12-12 09:10:46 -04:00
dependabot[bot]
5920cdc48f chore(deps): bump trufflesecurity/trufflehog from 3.86.0 to 3.86.1 (#6156)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-12 09:10:20 -04:00
dependabot[bot]
971e73f9cb chore(deps): bump google-api-python-client from 2.154.0 to 2.155.0 (#6155)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-12 09:09:51 -04:00
Mads Brouer Lundholm
bd9673c9de fix(aurora): Add default ports to the check of using non default ports (#5821)
Co-authored-by: Mads Rantala Lundholm <mao@bankdata.dk>
Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
2024-12-11 13:01:45 -04:00
johannes-engler-mw
eded97d735 feat(azure): check for minimal TLS version for Azure SQL server (#5745)
Co-authored-by: Rubén De la Torre Vico <ruben@prowler.com>
2024-12-11 16:37:53 +01:00
Daniel Barranquero
fdb1956b0b feat(opensearch): add new fixer opensearch_service_domains_not_publicly_accessible_fixer (#5926) 2024-12-11 11:29:48 -04:00
Daniel Barranquero
a915c04e9e fix(autoscaling): autoscaling_group_launch_configuration_requires_imdsv2 fails if Launch Template is used (#6111)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2024-12-11 11:18:30 -04:00
Daniel Barranquero
07178ac69a feat(glacier): add new fixer glacier_vaults_policy_public_access_fixer (#5950) 2024-12-11 11:10:12 -04:00
Daniel Barranquero
9b434d4856 feat(ecr): add new fixer ecr_repositories_not_publicly_accessible_fixer (#5923) 2024-12-11 10:42:11 -04:00
dependabot[bot]
0758e97628 chore(deps): bump botocore from 1.35.77 to 1.35.78 (#6132)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-11 10:19:37 -04:00
Sergio Garcia
b486007f95 fix(README): show latest release (#6145) 2024-12-11 10:19:06 -04:00
dependabot[bot]
0c0887afef chore(deps): bump trufflesecurity/trufflehog from 3.85.0 to 3.86.0 (#6130)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-11 09:29:14 -04:00
dependabot[bot]
805ed81031 chore(deps): bump boto3 from 1.35.76 to 1.35.77 (#6131)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-11 09:26:07 -04:00
Prowler Bot
ec3fddf5b1 chore(regions_update): Changes in regions for AWS services (#6136)
Co-authored-by: MrCloudSec <38561120+MrCloudSec@users.noreply.github.com>
2024-12-11 09:25:17 -04:00
Rubén De la Torre Vico
d7b0bc02ba feat(app): add support for TLS 1.3 to Web Apps check (#6004) 2024-12-11 13:14:29 +01:00
Pablo Lara
4d1c8eae8f feat(users): user detail can be edited now properly (#6135) 2024-12-11 10:05:30 +01:00
Sergio Garcia
989ccf4ae3 fix(iam): set unique resource id for each user access key (#6128) 2024-12-11 09:13:49 +01:00
Pedro Martín
9c089756c3 fix(compliance_tables): add correct values for findings (#6122)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2024-12-10 15:40:45 -04:00
Hugo Pereira Brito
8d4b0914a8 fix(aws): get firewall manager managed rule groups (#6119) 2024-12-10 15:34:22 -04:00
Hugo Pereira Brito
1ae3f89aab fix(aws): check AWS Owned keys in firehose_stream_encrypted_at_rest (#6108) 2024-12-10 13:42:13 -04:00
Daniel Barranquero
b984f0423a feat(sqs): add new fixer sqs_queues_not_publicly_accessible_fixer (#5911)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
2024-12-10 12:26:42 -04:00
Sergio Garcia
f2f196cfcd fix(aws): set IAM identity as resource in threat detection (#6048) 2024-12-10 17:03:01 +01:00
dependabot[bot]
6471d936bb chore(deps): bump msgraph-sdk from 1.12.0 to 1.14.0 (#5957)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-10 11:42:40 -04:00
Adrián Jesús Peña Rodríguez
21bbdccc41 fix(deploy): temporal fix for the alpine-python segmentation fault (#6109) 2024-12-10 16:27:52 +01:00
Sergio Garcia
48946fa4f7 fix(gcp): make sure default project is active (#6097) 2024-12-10 11:06:48 -04:00
dependabot[bot]
9312dda7c2 chore(deps): bump microsoft-kiota-abstractions from 1.6.2 to 1.6.6 (#6038)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-10 10:37:04 -04:00
dependabot[bot]
e3013329ee chore(deps): bump botocore from 1.35.76 to 1.35.77 (#6098)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-10 09:26:36 -04:00
Sergio Garcia
38a0d2d740 fix(aws): set same severity for EC2 IMDSv2 checks (#6046) 2024-12-10 08:55:41 +01:00
Mario Rodriguez Lopez
5c2adf1e14 docs(unitesting): Make some fixes to the documentation (#6102) 2024-12-10 08:51:19 +01:00
Daniel Barranquero
7ddd2c04c8 feat(awslambda): add new fixer awslambda_function_not_publicly_accessible_fixer (#5840) 2024-12-09 12:28:42 -04:00
Pepe Fagoaga
9a55632d8e fix(backport): more than one backport tag is allowed (#6090) 2024-12-09 17:19:33 +01:00
dependabot[bot]
f8b4427505 chore(deps-dev): bump vulture from 2.13 to 2.14 (#6068)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-09 11:10:41 -04:00
Sergio Garcia
f1efc1456d chore(dependabot): change interval of PRs (#6086) 2024-12-09 15:46:28 +01:00
Sergio Garcia
2ea5851b67 docs(api): add commands to run API scheduler (#6085) 2024-12-09 10:34:02 -04:00
dependabot[bot]
a3051bc4e3 chore(deps-dev): bump mkdocs-material from 9.5.47 to 9.5.48 (#6073)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-09 10:14:08 -04:00
Pepe Fagoaga
d454427b8b fix(backport): remove v from branch prefix (#6081) 2024-12-09 10:13:20 -04:00
Pepe Fagoaga
4b41bd6adf chore(containers): support for v4.6 branch (#6063)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
2024-12-09 09:23:06 -04:00
Pepe Fagoaga
cdd044d120 chore(dependabot): Update for UI and v4 (#6062) 2024-12-09 09:15:03 -04:00
Pepe Fagoaga
213a793fbc chore(actions): standardize names (#6059) 2024-12-09 09:14:06 -04:00
Pepe Fagoaga
a8a567c588 docs: Prowler SaaS -> Cloud and add missing compliance (#6061) 2024-12-09 09:12:54 -04:00
Pepe Fagoaga
fefe89a1ed fix(backport): Add action to detect labels (#5270) 2024-12-09 09:12:08 -04:00
Sergio Garcia
493fe2d523 docs(env): move warning about env files (#6049) 2024-12-09 11:11:05 +01:00
dependabot[bot]
d8fc830f1d chore(deps): bump boto3 from 1.35.71 to 1.35.76 (#6054)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-09 10:11:51 +01:00
Pepe Fagoaga
b6c3ba0f0d chore: delete unneeded requirements file (#6056) 2024-12-09 09:07:10 +01:00
dependabot[bot]
32cd39d158 chore(deps-dev): bump coverage from 7.6.8 to 7.6.9 (#6053)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-06 20:29:06 -04:00
dependabot[bot]
203275817f chore(deps-dev): bump pytest from 8.3.3 to 8.3.4 (#5992)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-06 12:53:11 -04:00
dependabot[bot]
c05c3396b5 chore(deps-dev): bump mkdocs-material from 9.5.46 to 9.5.47 (#5988)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-06 11:56:37 -04:00
dependabot[bot]
8f172aec8a chore(deps-dev): bump pylint from 3.3.1 to 3.3.2 (#5993)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-06 11:04:28 -04:00
dependabot[bot]
263a7e2134 chore(deps): bump botocore from 1.35.71 to 1.35.76 (#6037) 2024-12-06 09:41:57 -04:00
dependabot[bot]
a2ea216604 chore(deps): bump slack-sdk from 3.33.4 to 3.33.5 (#6039)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-06 08:44:00 -04:00
dependabot[bot]
77c572f990 chore(deps): bump trufflesecurity/trufflehog from 3.84.1 to 3.85.0 (#6040)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-06 08:38:14 -04:00
Prowler Bot
bb0c346c4d chore(regions_update): Changes in regions for AWS services (#6041)
Co-authored-by: sergargar <38561120+sergargar@users.noreply.github.com>
2024-12-06 08:38:03 -04:00
Daniel Barranquero
2ce8e1fd21 fix(backup): modify list recovery points call (#5996) 2024-12-06 08:35:29 -04:00
Pepe Fagoaga
ecfd94aeb1 fix(codecov): create components (#6028) 2024-12-05 16:35:56 +01:00
Pedro Martín
eddc672264 chore(version): update prowler version (#6027) 2024-12-05 13:51:13 +01:00
Pedro Martín
8c71a39487 docs(prowler-app): add link to https://api.prowler.com/api/v1/docs (#6016) 2024-12-05 11:01:51 +01:00
Pedro Martín
ff0ac27723 docs(index): update index with images (#6015) 2024-12-05 11:01:42 +01:00
Víctor Fernández Poyatos
ad7134d283 fix(tenant): fix delete tenants behavior (#6013) 2024-12-04 13:57:16 +01:00
Pablo Lara
58723ae52e fix(invitations): remove wrong url (#6005) 2024-12-03 21:08:31 +01:00
3486 changed files with 338798 additions and 43846 deletions

75
.env
View File

@@ -3,16 +3,20 @@
# For production, it is recommended to use a secure method to store these variables and change the default secret keys.
#### Prowler UI Configuration ####
PROWLER_UI_VERSION="latest"
SITE_URL=http://localhost:3000
PROWLER_UI_VERSION="stable"
AUTH_URL=http://localhost:3000
API_BASE_URL=http://prowler-api:8080/api/v1
NEXT_PUBLIC_API_DOCS_URL=http://prowler-api:8080/api/v1/docs
AUTH_TRUST_HOST=true
UI_PORT=3000
# openssl rand -base64 32
AUTH_SECRET="N/c6mnaS5+SWq81+819OrzQZlmx1Vxtp/orjttJSmw8="
# Google Tag Manager ID
NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID=""
#### Prowler API Configuration ####
PROWLER_API_VERSION="latest"
PROWLER_API_VERSION="stable"
# PostgreSQL settings
# If running Django and celery on host, use 'localhost', else use 'postgres-db'
POSTGRES_HOST=postgres-db
@@ -23,12 +27,40 @@ POSTGRES_USER=prowler
POSTGRES_PASSWORD=postgres
POSTGRES_DB=prowler_db
# Celery-Prowler task settings
TASK_RETRY_DELAY_SECONDS=0.1
TASK_RETRY_ATTEMPTS=5
# Valkey settings
# If running Valkey and celery on host, use localhost, else use 'valkey'
VALKEY_HOST=valkey
VALKEY_PORT=6379
VALKEY_DB=0
# API scan settings
# The path to the directory where scan output should be stored
DJANGO_TMP_OUTPUT_DIRECTORY="/tmp/prowler_api_output"
# The maximum number of findings to process in a single batch
DJANGO_FINDINGS_BATCH_SIZE=1000
# The AWS access key to be used when uploading scan output to an S3 bucket
# If left empty, default AWS credentials resolution behavior will be used
DJANGO_OUTPUT_S3_AWS_ACCESS_KEY_ID=""
# The AWS secret key to be used when uploading scan output to an S3 bucket
DJANGO_OUTPUT_S3_AWS_SECRET_ACCESS_KEY=""
# An optional AWS session token
DJANGO_OUTPUT_S3_AWS_SESSION_TOKEN=""
# The AWS region where your S3 bucket is located (e.g., "us-east-1")
DJANGO_OUTPUT_S3_AWS_DEFAULT_REGION=""
# The name of the S3 bucket where scan output should be stored
DJANGO_OUTPUT_S3_AWS_OUTPUT_BUCKET=""
# Django settings
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,prowler-api
DJANGO_BIND_ADDRESS=0.0.0.0
@@ -40,9 +72,12 @@ DJANGO_LOGGING_FORMATTER=human_readable
# Select one of [DEBUG|INFO|WARNING|ERROR|CRITICAL]
# Applies to both Django and Celery Workers
DJANGO_LOGGING_LEVEL=INFO
DJANGO_WORKERS=4 # Defaults to the maximum available based on CPU cores if not set.
DJANGO_ACCESS_TOKEN_LIFETIME=30 # Token lifetime is in minutes
DJANGO_REFRESH_TOKEN_LIFETIME=1440 # Token lifetime is in minutes
# Defaults to the maximum available based on CPU cores if not set.
DJANGO_WORKERS=4
# Token lifetime is in minutes
DJANGO_ACCESS_TOKEN_LIFETIME=30
# Token lifetime is in minutes
DJANGO_REFRESH_TOKEN_LIFETIME=1440
DJANGO_CACHE_MAX_AGE=3600
DJANGO_STALE_WHILE_REVALIDATE=60
DJANGO_MANAGE_DB_PARTITIONS=True
@@ -87,3 +122,31 @@ jQIDAQAB
-----END PUBLIC KEY-----"
# openssl rand -base64 32
DJANGO_SECRETS_ENCRYPTION_KEY="oE/ltOhp/n1TdbHjVmzcjDPLcLA41CVI/4Rk+UB5ESc="
DJANGO_BROKER_VISIBILITY_TIMEOUT=86400
DJANGO_SENTRY_DSN=
# Sentry settings
SENTRY_ENVIRONMENT=local
SENTRY_RELEASE=local
#### Prowler release version ####
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v5.6.0
# Social login credentials
SOCIAL_GOOGLE_OAUTH_CALLBACK_URL="${AUTH_URL}/api/auth/callback/google"
SOCIAL_GOOGLE_OAUTH_CLIENT_ID=""
SOCIAL_GOOGLE_OAUTH_CLIENT_SECRET=""
SOCIAL_GITHUB_OAUTH_CALLBACK_URL="${AUTH_URL}/api/auth/callback/github"
SOCIAL_GITHUB_OAUTH_CLIENT_ID=""
SOCIAL_GITHUB_OAUTH_CLIENT_SECRET=""
# Single Sign-On (SSO)
SAML_PUBLIC_CERT=""
SAML_PRIVATE_KEY=""
# Lighthouse tracing
LANGSMITH_TRACING=false
LANGSMITH_ENDPOINT="https://api.smith.langchain.com"
LANGSMITH_API_KEY=""
LANGCHAIN_PROJECT=""

View File

@@ -1,3 +1,3 @@
name: "Custom CodeQL Config for API"
name: "API - CodeQL Config"
paths:
- 'api/'
- "api/"

View File

@@ -1,4 +0,0 @@
name: "Custom CodeQL Config"
paths-ignore:
- 'api/'
- 'ui/'

4
.github/codeql/sdk-codeql-config.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
name: "SDK - CodeQL Config"
paths-ignore:
- "api/"
- "ui/"

View File

@@ -1,3 +1,3 @@
name: "Custom CodeQL Config for UI"
name: "UI - CodeQL Config"
paths:
- "ui/"

114
.github/dependabot.yml vendored
View File

@@ -5,42 +5,116 @@
version: 2
updates:
# v5
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
interval: "monthly"
open-pull-requests-limit: 25
target-branch: master
labels:
- "dependencies"
- "pip"
# Dependabot Updates are temporary disabled - 2025/03/19
# - package-ecosystem: "pip"
# directory: "/api"
# schedule:
# interval: "daily"
# open-pull-requests-limit: 10
# target-branch: master
# labels:
# - "dependencies"
# - "pip"
# - "component/api"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
interval: "monthly"
open-pull-requests-limit: 25
target-branch: master
labels:
- "dependencies"
- "github_actions"
- package-ecosystem: "pip"
# Dependabot Updates are temporary disabled - 2025/03/19
# - package-ecosystem: "npm"
# directory: "/ui"
# schedule:
# interval: "daily"
# open-pull-requests-limit: 10
# target-branch: master
# labels:
# - "dependencies"
# - "npm"
# - "component/ui"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
target-branch: v3
interval: "monthly"
open-pull-requests-limit: 25
target-branch: master
labels:
- "dependencies"
- "pip"
- "v3"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
target-branch: v3
labels:
- "dependencies"
- "github_actions"
- "v3"
- "docker"
# Dependabot Updates are temporary disabled - 2025/04/15
# v4.6
# - package-ecosystem: "pip"
# directory: "/"
# schedule:
# interval: "weekly"
# open-pull-requests-limit: 10
# target-branch: v4.6
# labels:
# - "dependencies"
# - "pip"
# - "v4"
# - package-ecosystem: "github-actions"
# directory: "/"
# schedule:
# interval: "weekly"
# open-pull-requests-limit: 10
# target-branch: v4.6
# labels:
# - "dependencies"
# - "github_actions"
# - "v4"
# - package-ecosystem: "docker"
# directory: "/"
# schedule:
# interval: "weekly"
# open-pull-requests-limit: 10
# target-branch: v4.6
# labels:
# - "dependencies"
# - "docker"
# - "v4"
# Dependabot Updates are temporary disabled - 2025/03/19
# v3
# - package-ecosystem: "pip"
# directory: "/"
# schedule:
# interval: "monthly"
# open-pull-requests-limit: 10
# target-branch: v3
# labels:
# - "dependencies"
# - "pip"
# - "v3"
# - package-ecosystem: "github-actions"
# directory: "/"
# schedule:
# interval: "monthly"
# open-pull-requests-limit: 10
# target-branch: v3
# labels:
# - "dependencies"
# - "github_actions"
# - "v3"

20
.github/labeler.yml vendored
View File

@@ -22,6 +22,16 @@ provider/kubernetes:
- any-glob-to-any-file: "prowler/providers/kubernetes/**"
- any-glob-to-any-file: "tests/providers/kubernetes/**"
provider/github:
- changed-files:
- any-glob-to-any-file: "prowler/providers/github/**"
- any-glob-to-any-file: "tests/providers/github/**"
provider/iac:
- changed-files:
- any-glob-to-any-file: "prowler/providers/iac/**"
- any-glob-to-any-file: "tests/providers/iac/**"
github_actions:
- changed-files:
- any-glob-to-any-file: ".github/workflows/*"
@@ -87,3 +97,13 @@ component/api:
component/ui:
- changed-files:
- any-glob-to-any-file: "ui/**"
compliance:
- changed-files:
- any-glob-to-any-file: "prowler/compliance/**"
- any-glob-to-any-file: "prowler/lib/outputs/compliance/**"
- any-glob-to-any-file: "tests/lib/outputs/compliance/**"
review-django-migrations:
- changed-files:
- any-glob-to-any-file: "api/src/backend/api/migrations/**"

View File

@@ -15,7 +15,14 @@ Please include a summary of the change and which issue is fixed. List any depend
- [ ] Review if the code is being covered by tests.
- [ ] Review if code is being documented following this specification https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings
- [ ] Review if backport is needed.
- [ ] Review if is needed to change the [Readme.md](https://github.com/prowler-cloud/prowler/blob/master/README.md)
- [ ] Ensure new entries are added to [CHANGELOG.md](https://github.com/prowler-cloud/prowler/blob/master/prowler/CHANGELOG.md), if applicable.
#### API
- [ ] Verify if API specs need to be regenerated.
- [ ] Check if version updates are required (e.g., specs, Poetry, etc.).
- [ ] Ensure new entries are added to [CHANGELOG.md](https://github.com/prowler-cloud/prowler/blob/master/api/CHANGELOG.md), if applicable.
### License
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

View File

@@ -0,0 +1,114 @@
name: API - Build and Push containers
on:
push:
branches:
- "master"
paths:
- "api/**"
- ".github/workflows/api-build-lint-push-containers.yml"
# Uncomment the code below to test this action on PRs
# pull_request:
# branches:
# - "master"
# paths:
# - "api/**"
# - ".github/workflows/api-build-lint-push-containers.yml"
release:
types: [published]
env:
# Tags
LATEST_TAG: latest
RELEASE_TAG: ${{ github.event.release.tag_name }}
STABLE_TAG: stable
WORKING_DIRECTORY: ./api
# Container Registries
PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud
PROWLERCLOUD_DOCKERHUB_IMAGE: prowler-api
jobs:
repository-check:
name: Repository check
runs-on: ubuntu-latest
outputs:
is_repo: ${{ steps.repository_check.outputs.is_repo }}
steps:
- name: Repository check
id: repository_check
working-directory: /tmp
run: |
if [[ ${{ github.repository }} == "prowler-cloud/prowler" ]]
then
echo "is_repo=true" >> "${GITHUB_OUTPUT}"
else
echo "This action only runs for prowler-cloud/prowler"
echo "is_repo=false" >> "${GITHUB_OUTPUT}"
fi
# Build Prowler OSS container
container-build-push:
needs: repository-check
if: needs.repository-check.outputs.is_repo == 'true'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ env.WORKING_DIRECTORY }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set short git commit SHA
id: vars
run: |
shortSha=$(git rev-parse --short ${{ github.sha }})
echo "SHORT_SHA=${shortSha}" >> $GITHUB_ENV
- name: Login to DockerHub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Build and push container image (latest)
# Comment the following line for testing
if: github.event_name == 'push'
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: ${{ env.WORKING_DIRECTORY }}
# Set push: false for testing
push: true
tags: |
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }}
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.SHORT_SHA }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and push container image (release)
if: github.event_name == 'release'
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: ${{ env.WORKING_DIRECTORY }}
push: true
tags: |
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.RELEASE_TAG }}
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.STABLE_TAG }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Trigger deployment
if: github.event_name == 'push'
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0
with:
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
repository: ${{ secrets.CLOUD_DISPATCH }}
event-type: prowler-api-deploy
client-payload: '{"sha": "${{ github.sha }}", "short_sha": "${{ env.SHORT_SHA }}"}'

View File

@@ -9,22 +9,18 @@
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "API - CodeQL"
name: API - CodeQL
on:
push:
branches:
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
paths:
- "api/**"
pull_request:
branches:
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
paths:
- "api/**"
@@ -48,16 +44,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/api-codeql-config.yml
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
category: "/language:${{matrix.language}}"

View File

@@ -1,18 +1,20 @@
name: "API - Pull Request"
name: API - Pull Request
on:
push:
branches:
- "master"
- "v5.*"
paths:
- ".github/workflows/api-pull-request.yml"
- "api/**"
pull_request:
branches:
- "master"
- "v5.*"
paths:
- "api/**"
env:
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
@@ -24,7 +26,12 @@ env:
VALKEY_HOST: localhost
VALKEY_PORT: 6379
VALKEY_DB: 0
API_WORKING_DIR: ./api
IMAGE_NAME: prowler-api
IGNORE_FILES: |
api/docs/**
api/README.md
api/CHANGELOG.md
jobs:
test:
@@ -68,35 +75,54 @@ jobs:
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Test if changes are in not ignored paths
id: are-non-ignored-files-changed
uses: tj-actions/changed-files@v45
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: api/**
files_ignore: |
api/.github/**
api/docs/**
api/permissions/**
api/README.md
api/mkdocs.yml
files_ignore: ${{ env.IGNORE_FILES }}
- name: Replace @master with current branch in pyproject.toml
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
BRANCH_NAME="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}"
echo "Using branch: $BRANCH_NAME"
sed -i "s|@master|@$BRANCH_NAME|g" pyproject.toml
- name: Install poetry
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
python -m pip install --upgrade pip
pipx install poetry
pipx install poetry==2.1.1
- name: Update poetry.lock after the branch name change
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry lock
- name: Set up Python ${{ matrix.python-version }}
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
cache: "poetry"
- name: Install system dependencies for xmlsec
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
sudo apt-get update
sudo apt-get install -y libxml2-dev libxmlsec1-dev libxmlsec1-openssl pkg-config
- name: Install dependencies
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry install
poetry install --no-root
poetry run pip list
VERSION=$(curl --silent "https://api.github.com/repos/hadolint/hadolint/releases/latest" | \
grep '"tag_name":' | \
@@ -108,49 +134,91 @@ jobs:
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry lock --check
poetry check --lock
- name: Prevents known compatibility error between lxml and libxml2/libxmlsec versions - https://github.com/xmlsec/python-xmlsec/issues/320
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run pip install --force-reinstall --no-binary lxml lxml
- name: Lint with ruff
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run ruff check . --exclude contrib
- name: Check Format with ruff
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run ruff format --check . --exclude contrib
- name: Lint with pylint
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run pylint --disable=W,C,R,E -j 0 -rn -sn src/
- name: Bandit
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run bandit -q -lll -x '*_test.py,./contrib/' -r .
- name: Safety
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
# 76352 and 76353 come from SDK, but they cannot upgrade it yet. It does not affect API
run: |
poetry run safety check --ignore 70612,66963
poetry run safety check --ignore 70612,66963,74429,76352,76353
- name: Vulture
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run vulture --exclude "contrib,tests,conftest.py" --min-confidence 100 .
- name: Hadolint
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
/tmp/hadolint Dockerfile --ignore=DL3013
- name: Test with pytest
working-directory: ./api
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run pytest --cov=./src/backend --cov-report=xml src/backend
- name: Upload coverage reports to Codecov
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
flags: api
test-container-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Test if changes are in not ignored paths
id: are-non-ignored-files-changed
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: api/**
files_ignore: ${{ env.IGNORE_FILES }}
- name: Set up Docker Buildx
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Build Container
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: ${{ env.API_WORKING_DIR }}
push: false
tags: ${{ env.IMAGE_NAME }}:latest
outputs: type=docker
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -1,42 +1,47 @@
name: Automatic Backport
name: Prowler - Automatic Backport
on:
pull_request_target:
branches: ['master']
types: ['labeled', 'closed']
env:
# The prefix of the label that triggers the backport must not contain the branch name
# so, for example, if the branch is 'master', the label should be 'backport-to-<branch>'
BACKPORT_LABEL_PREFIX: backport-to-
BACKPORT_LABEL_IGNORE: was-backported
jobs:
backport:
name: Backport PR
if: github.event.pull_request.merged == true && !(contains(github.event.pull_request.labels.*.name, 'backport'))
if: github.event.pull_request.merged == true && !(contains(github.event.pull_request.labels.*.name, 'backport')) && !(contains(github.event.pull_request.labels.*.name, 'was-backported'))
runs-on: ubuntu-latest
permissions:
id-token: write
pull-requests: write
contents: write
steps:
# Workaround not to fail the workflow if the PR does not need a backport
# https://github.com/sorenlouv/backport-github-action/issues/127#issuecomment-2258561266
- name: Check for backport labels
id: check_labels
run: |-
labels='${{ toJSON(github.event.pull_request.labels.*.name) }}'
echo "$labels"
matched=$(echo "${labels}" | jq '. | map(select(startswith("backport-to-"))) | length')
echo "matched=$matched"
echo "matched=$matched" >> $GITHUB_OUTPUT
- name: Check labels
id: preview_label_check
uses: agilepathway/label-checker@c3d16ad512e7cea5961df85ff2486bb774caf3c5 # v1.6.65
with:
allow_failure: true
prefix_mode: true
any_of: ${{ env.BACKPORT_LABEL_PREFIX }}
none_of: ${{ env.BACKPORT_LABEL_IGNORE }}
repo_token: ${{ secrets.GITHUB_TOKEN }}
- name: Backport Action
if: fromJSON(steps.check_labels.outputs.matched) > 0
uses: sorenlouv/backport-github-action@v9.5.1
if: steps.preview_label_check.outputs.label_check == 'success'
uses: sorenlouv/backport-github-action@ad888e978060bc1b2798690dd9d03c4036560947 # v9.5.1
with:
github_token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
auto_backport_label_prefix: backport-to-
auto_backport_label_prefix: ${{ env.BACKPORT_LABEL_PREFIX }}
- name: Info log
if: ${{ success() && fromJSON(steps.check_labels.outputs.matched) > 0 }}
if: ${{ success() && steps.preview_label_check.outputs.label_check == 'success' }}
run: cat ~/.backport/backport.info.log
- name: Debug log
if: ${{ failure() && fromJSON(steps.check_labels.outputs.matched) > 0 }}
if: ${{ failure() && steps.preview_label_check.outputs.label_check == 'success' }}
run: cat ~/.backport/backport.debug.log

View File

@@ -1,4 +1,4 @@
name: Pull Request Documentation Link
name: Prowler - Pull Request Documentation Link
on:
pull_request:
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Leave PR comment with the Prowler Documentation URI
uses: peter-evans/create-or-update-comment@v4
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
with:
issue-number: ${{ env.PR_NUMBER }}
body: |

View File

@@ -0,0 +1,23 @@
name: Prowler - Conventional Commit
on:
pull_request:
types:
- "opened"
- "edited"
- "synchronize"
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
jobs:
conventional-commit-check:
runs-on: ubuntu-latest
steps:
- name: conventional-commit-check
id: conventional-commit-check
uses: agenthunt/conventional-commit-checker-action@9e552d650d0e205553ec7792d447929fc78e012b # v2.0.0
with:
pr-title-regex: '^([^\s(]+)(?:\(([^)]+)\))?: (.+)'

View File

@@ -0,0 +1,67 @@
name: Create Backport Label
on:
release:
types: [published]
jobs:
create_label:
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
steps:
- name: Create backport label
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
OWNER_REPO: ${{ github.repository }}
run: |
VERSION_ONLY=${RELEASE_TAG#v} # Remove 'v' prefix if present (e.g., v3.2.0 -> 3.2.0)
# Check if it's a minor version (X.Y.0)
if [[ "$VERSION_ONLY" =~ ^[0-9]+\.[0-9]+\.0$ ]]; then
echo "Release ${RELEASE_TAG} (version ${VERSION_ONLY}) is a minor version. Proceeding to create backport label."
TWO_DIGIT_VERSION=${VERSION_ONLY%.0} # Extract X.Y from X.Y.0 (e.g., 5.6 from 5.6.0)
FINAL_LABEL_NAME="backport-to-v${TWO_DIGIT_VERSION}"
FINAL_DESCRIPTION="Backport PR to the v${TWO_DIGIT_VERSION} branch"
echo "Effective label name will be: ${FINAL_LABEL_NAME}"
echo "Effective description will be: ${FINAL_DESCRIPTION}"
# Check if the label already exists
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token ${GITHUB_TOKEN}" "https://api.github.com/repos/${OWNER_REPO}/labels/${FINAL_LABEL_NAME}")
if [ "${STATUS_CODE}" -eq 200 ]; then
echo "Label '${FINAL_LABEL_NAME}' already exists."
elif [ "${STATUS_CODE}" -eq 404 ]; then
echo "Label '${FINAL_LABEL_NAME}' does not exist. Creating it..."
# Prepare JSON data payload
JSON_DATA=$(printf '{"name":"%s","description":"%s","color":"B60205"}' "${FINAL_LABEL_NAME}" "${FINAL_DESCRIPTION}")
CREATE_STATUS_CODE=$(curl -s -o /tmp/curl_create_response.json -w "%{http_code}" -X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token ${GITHUB_TOKEN}" \
--data "${JSON_DATA}" \
"https://api.github.com/repos/${OWNER_REPO}/labels")
CREATE_RESPONSE_BODY=$(cat /tmp/curl_create_response.json)
rm -f /tmp/curl_create_response.json
if [ "$CREATE_STATUS_CODE" -eq 201 ]; then
echo "Label '${FINAL_LABEL_NAME}' created successfully."
else
echo "Error creating label '${FINAL_LABEL_NAME}'. Status: $CREATE_STATUS_CODE"
echo "Response: $CREATE_RESPONSE_BODY"
exit 1
fi
else
echo "Error checking for label '${FINAL_LABEL_NAME}'. HTTP Status: ${STATUS_CODE}"
exit 1
fi
else
echo "Release ${RELEASE_TAG} (version ${VERSION_ONLY}) is not a minor version. Skipping backport label creation."
exit 0
fi

View File

@@ -1,4 +1,4 @@
name: Find secrets
name: Prowler - Find secrets
on: pull_request
@@ -7,13 +7,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: TruffleHog OSS
uses: trufflesecurity/trufflehog@v3.84.1
uses: trufflesecurity/trufflehog@90694bf9af66e7536abc5824e7a87246dbf933cb # v3.88.35
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
extra_args: --only-verified
extra_args: --only-verified

View File

@@ -1,4 +1,4 @@
name: "Pull Request Labeler"
name: Prowler - PR Labeler
on:
pull_request_target:
@@ -14,4 +14,4 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0

View File

@@ -0,0 +1,83 @@
name: Check Changelog
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
jobs:
check-changelog:
if: contains(github.event.pull_request.labels.*.name, 'no-changelog') == false
runs-on: ubuntu-latest
permissions:
pull-requests: write
env:
MONITORED_FOLDERS: "api ui prowler"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Get list of changed files
id: changed_files
run: |
git fetch origin ${{ github.base_ref }}
git diff --name-only origin/${{ github.base_ref }}...HEAD > changed_files.txt
cat changed_files.txt
- name: Check for folder changes and changelog presence
id: check_folders
run: |
missing_changelogs=""
for folder in $MONITORED_FOLDERS; do
if grep -q "^${folder}/" changed_files.txt; then
echo "Detected changes in ${folder}/"
if ! grep -q "^${folder}/CHANGELOG.md$" changed_files.txt; then
echo "No changelog update found for ${folder}/"
missing_changelogs="${missing_changelogs}- \`${folder}\`\n"
fi
fi
done
echo "missing_changelogs<<EOF" >> $GITHUB_OUTPUT
echo -e "${missing_changelogs}" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Find existing changelog comment
id: find_comment
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e #v3.1.0
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: '<!-- changelog-check -->'
- name: Comment on PR if changelog is missing
if: steps.check_folders.outputs.missing_changelogs != ''
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.find_comment.outputs.comment-id }}
body: |
<!-- changelog-check -->
⚠️ **Changes detected in the following folders without a corresponding update to the `CHANGELOG.md`:**
${{ steps.check_folders.outputs.missing_changelogs }}
Please add an entry to the corresponding `CHANGELOG.md` file to maintain a clear history of changes.
- name: Comment on PR if all changelogs are present
if: steps.check_folders.outputs.missing_changelogs == ''
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.find_comment.outputs.comment-id }}
body: |
<!-- changelog-check -->
✅ All necessary `CHANGELOG.md` files have been updated. Great job! 🎉
- name: Fail if changelog is missing
if: steps.check_folders.outputs.missing_changelogs != ''
run: |
echo "ERROR: Missing changelog updates in some folders."
exit 1

View File

@@ -0,0 +1,37 @@
name: Prowler - Merged Pull Request
on:
pull_request_target:
branches: ['master']
types: ['closed']
jobs:
trigger-cloud-pull-request:
name: Trigger Cloud Pull Request
if: github.event.pull_request.merged == true && github.repository == 'prowler-cloud/prowler'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.merge_commit_sha }}
- name: Set short git commit SHA
id: vars
run: |
shortSha=$(git rev-parse --short ${{ github.event.pull_request.merge_commit_sha }})
echo "SHORT_SHA=${shortSha}" >> $GITHUB_ENV
- name: Trigger pull request
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0
with:
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
repository: ${{ secrets.CLOUD_DISPATCH }}
event-type: prowler-pull-request-merged
client-payload: '{
"PROWLER_COMMIT_SHA": "${{ github.event.pull_request.merge_commit_sha }}",
"PROWLER_COMMIT_SHORT_SHA": "${{ env.SHORT_SHA }}",
"PROWLER_PR_TITLE": "${{ github.event.pull_request.title }}",
"PROWLER_PR_LABELS": ${{ toJson(github.event.pull_request.labels.*.name) }},
"PROWLER_PR_BODY": ${{ toJson(github.event.pull_request.body) }},
"PROWLER_PR_URL":${{ toJson(github.event.pull_request.html_url) }}
}'

View File

@@ -1,100 +0,0 @@
name: "Pull Request"
on:
push:
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
pull_request:
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Test if changes are in not ignored paths
id: are-non-ignored-files-changed
uses: tj-actions/changed-files@v45
with:
files: ./**
files_ignore: |
.github/**
docs/**
permissions/**
api/**
ui/**
README.md
mkdocs.yml
.backportrc.json
- name: Install poetry
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
python -m pip install --upgrade pip
pipx install poetry
- name: Set up Python ${{ matrix.python-version }}
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "poetry"
- name: Install dependencies
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry install
poetry run pip list
VERSION=$(curl --silent "https://api.github.com/repos/hadolint/hadolint/releases/latest" | \
grep '"tag_name":' | \
sed -E 's/.*"v([^"]+)".*/\1/' \
) && curl -L -o /tmp/hadolint "https://github.com/hadolint/hadolint/releases/download/v${VERSION}/hadolint-Linux-x86_64" \
&& chmod +x /tmp/hadolint
- name: Poetry check
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry lock --check
- name: Lint with flake8
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib,ui,api
- name: Checking format with black
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run black --exclude api ui --check .
- name: Lint with pylint
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run pylint --disable=W,C,R,E -j 0 -rn -sn prowler/
- name: Bandit
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run bandit -q -lll -x '*_test.py,./contrib/,./api/,./ui' -r .
- name: Safety
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run safety check --ignore 70612 -r pyproject.toml
- name: Vulture
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run vulture --exclude "contrib,api,ui" --min-confidence 100 .
- name: Hadolint
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
/tmp/hadolint Dockerfile --ignore=DL3013
- name: Test with pytest
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler --cov-report=xml tests
- name: Upload coverage reports to Codecov
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -1,9 +1,13 @@
name: Build and Push containers
name: SDK - Build and Push containers
on:
push:
branches:
# For `v3-latest`
- "v3"
# For `v4-latest`
- "v4.6"
# For `latest`
- "master"
paths-ignore:
- ".github/**"
@@ -55,16 +59,16 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install Poetry
run: |
pipx install poetry
pipx install poetry==2.*
pipx inject poetry poetry-bumpversion
- name: Get Prowler version
@@ -85,8 +89,8 @@ jobs:
echo "STABLE_TAG=v3-stable" >> "${GITHUB_ENV}"
;;
4)
4)
echo "LATEST_TAG=v4-latest" >> "${GITHUB_ENV}"
echo "STABLE_TAG=v4-stable" >> "${GITHUB_ENV}"
;;
@@ -104,13 +108,13 @@ jobs:
esac
- name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Public ECR
uses: docker/login-action@v3
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: public.ecr.aws
username: ${{ secrets.PUBLIC_ECR_AWS_ACCESS_KEY_ID }}
@@ -119,11 +123,11 @@ jobs:
AWS_REGION: ${{ env.AWS_REGION }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Build and push container image (latest)
if: github.event_name == 'push'
uses: docker/build-push-action@v6
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
push: true
tags: |
@@ -136,7 +140,7 @@ jobs:
- name: Build and push container image (release)
if: github.event_name == 'release'
uses: docker/build-push-action@v6
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
# Use local context to get changes
# https://github.com/docker/build-push-action#path-context

145
.github/workflows/sdk-bump-version.yml vendored Normal file
View File

@@ -0,0 +1,145 @@
name: SDK - Bump Version
on:
release:
types: [published]
env:
PROWLER_VERSION: ${{ github.event.release.tag_name }}
BASE_BRANCH: master
jobs:
bump-version:
name: Bump Version
if: github.repository == 'prowler-cloud/prowler'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get Prowler version
shell: bash
run: |
if [[ $PROWLER_VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
MAJOR_VERSION=${BASH_REMATCH[1]}
MINOR_VERSION=${BASH_REMATCH[2]}
FIX_VERSION=${BASH_REMATCH[3]}
# Export version components to GitHub environment
echo "MAJOR_VERSION=${MAJOR_VERSION}" >> "${GITHUB_ENV}"
echo "MINOR_VERSION=${MINOR_VERSION}" >> "${GITHUB_ENV}"
echo "FIX_VERSION=${FIX_VERSION}" >> "${GITHUB_ENV}"
if (( MAJOR_VERSION == 5 )); then
if (( FIX_VERSION == 0 )); then
echo "Minor Release: $PROWLER_VERSION"
# Set up next minor version for master
BUMP_VERSION_TO=${MAJOR_VERSION}.$((MINOR_VERSION + 1)).${FIX_VERSION}
echo "BUMP_VERSION_TO=${BUMP_VERSION_TO}" >> "${GITHUB_ENV}"
TARGET_BRANCH=${BASE_BRANCH}
echo "TARGET_BRANCH=${TARGET_BRANCH}" >> "${GITHUB_ENV}"
# Set up patch version for version branch
PATCH_VERSION_TO=${MAJOR_VERSION}.${MINOR_VERSION}.1
echo "PATCH_VERSION_TO=${PATCH_VERSION_TO}" >> "${GITHUB_ENV}"
VERSION_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION}
echo "VERSION_BRANCH=${VERSION_BRANCH}" >> "${GITHUB_ENV}"
echo "Bumping to next minor version: ${BUMP_VERSION_TO} in branch ${TARGET_BRANCH}"
echo "Bumping to next patch version: ${PATCH_VERSION_TO} in branch ${VERSION_BRANCH}"
else
echo "Patch Release: $PROWLER_VERSION"
BUMP_VERSION_TO=${MAJOR_VERSION}.${MINOR_VERSION}.$((FIX_VERSION + 1))
echo "BUMP_VERSION_TO=${BUMP_VERSION_TO}" >> "${GITHUB_ENV}"
TARGET_BRANCH=v${MAJOR_VERSION}.${MINOR_VERSION}
echo "TARGET_BRANCH=${TARGET_BRANCH}" >> "${GITHUB_ENV}"
echo "Bumping to next patch version: ${BUMP_VERSION_TO} in branch ${TARGET_BRANCH}"
fi
else
echo "Releasing another Prowler major version, aborting..."
exit 1
fi
else
echo "Invalid version syntax: '$PROWLER_VERSION' (must be N.N.N)" >&2
exit 1
fi
- name: Bump versions in files
run: |
echo "Using PROWLER_VERSION=$PROWLER_VERSION"
echo "Using BUMP_VERSION_TO=$BUMP_VERSION_TO"
set -e
echo "Bumping version in pyproject.toml ..."
sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${BUMP_VERSION_TO}\"|" pyproject.toml
echo "Bumping version in prowler/config/config.py ..."
sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${BUMP_VERSION_TO}\"|" prowler/config/config.py
echo "Bumping version in .env ..."
sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${BUMP_VERSION_TO}|" .env
git --no-pager diff
- name: Create Pull Request
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
base: ${{ env.TARGET_BRANCH }}
commit-message: "chore(release): Bump version to v${{ env.BUMP_VERSION_TO }}"
branch: "version-bump-to-v${{ env.BUMP_VERSION_TO }}"
title: "chore(release): Bump version to v${{ env.BUMP_VERSION_TO }}"
body: |
### Description
Bump Prowler version to v${{ env.BUMP_VERSION_TO }}
### License
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
- name: Handle patch version for minor release
if: env.FIX_VERSION == '0'
run: |
echo "Using PROWLER_VERSION=$PROWLER_VERSION"
echo "Using PATCH_VERSION_TO=$PATCH_VERSION_TO"
set -e
echo "Bumping version in pyproject.toml ..."
sed -i "s|version = \"${PROWLER_VERSION}\"|version = \"${PATCH_VERSION_TO}\"|" pyproject.toml
echo "Bumping version in prowler/config/config.py ..."
sed -i "s|prowler_version = \"${PROWLER_VERSION}\"|prowler_version = \"${PATCH_VERSION_TO}\"|" prowler/config/config.py
echo "Bumping version in .env ..."
sed -i "s|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PROWLER_VERSION}|NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${PATCH_VERSION_TO}|" .env
git --no-pager diff
- name: Create Pull Request for patch version
if: env.FIX_VERSION == '0'
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
base: ${{ env.VERSION_BRANCH }}
commit-message: "chore(release): Bump version to v${{ env.PATCH_VERSION_TO }}"
branch: "version-bump-to-v${{ env.PATCH_VERSION_TO }}"
title: "chore(release): Bump version to v${{ env.PATCH_VERSION_TO }}"
body: |
### Description
Bump Prowler version to v${{ env.PATCH_VERSION_TO }}
### License
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

View File

@@ -9,25 +9,29 @@
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
name: SDK - CodeQL
on:
push:
branches:
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
paths-ignore:
- 'ui/**'
- 'api/**'
- '.github/**'
pull_request:
branches:
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
paths-ignore:
- 'ui/**'
- 'api/**'
- '.github/**'
schedule:
- cron: '00 12 * * *'
@@ -48,16 +52,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
config-file: ./.github/codeql/sdk-codeql-config.yml
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
category: "/language:${{matrix.language}}"

249
.github/workflows/sdk-pull-request.yml vendored Normal file
View File

@@ -0,0 +1,249 @@
name: SDK - Pull Request
on:
push:
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
pull_request:
branches:
- "master"
- "v3"
- "v4.*"
- "v5.*"
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Test if changes are in not ignored paths
id: are-non-ignored-files-changed
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: ./**
files_ignore: |
.github/**
docs/**
permissions/**
api/**
ui/**
prowler/CHANGELOG.md
README.md
mkdocs.yml
.backportrc.json
.env
docker-compose*
examples/**
.gitignore
- name: Install poetry
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
python -m pip install --upgrade pip
pipx install poetry==2.1.1
- name: Set up Python ${{ matrix.python-version }}
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
cache: "poetry"
- name: Install dependencies
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry install --no-root
poetry run pip list
VERSION=$(curl --silent "https://api.github.com/repos/hadolint/hadolint/releases/latest" | \
grep '"tag_name":' | \
sed -E 's/.*"v([^"]+)".*/\1/' \
) && curl -L -o /tmp/hadolint "https://github.com/hadolint/hadolint/releases/download/v${VERSION}/hadolint-Linux-x86_64" \
&& chmod +x /tmp/hadolint
- name: Poetry check
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry check --lock
- name: Lint with flake8
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib,ui,api
- name: Checking format with black
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run black --exclude api ui --check .
- name: Lint with pylint
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run pylint --disable=W,C,R,E -j 0 -rn -sn prowler/
- name: Bandit
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run bandit -q -lll -x '*_test.py,./contrib/,./api/,./ui' -r .
- name: Safety
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run safety check --ignore 70612 -r pyproject.toml
- name: Vulture
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run vulture --exclude "contrib,api,ui" --min-confidence 100 .
- name: Hadolint
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
/tmp/hadolint Dockerfile --ignore=DL3013
# Test AWS
- name: AWS - Check if any file has changed
id: aws-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/aws/**
./tests/providers/aws/**
.poetry.lock
- name: AWS - Test
if: steps.aws-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml tests/providers/aws
# Test Azure
- name: Azure - Check if any file has changed
id: azure-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/azure/**
./tests/providers/azure/**
.poetry.lock
- name: Azure - Test
if: steps.azure-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/azure --cov-report=xml:azure_coverage.xml tests/providers/azure
# Test GCP
- name: GCP - Check if any file has changed
id: gcp-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/gcp/**
./tests/providers/gcp/**
.poetry.lock
- name: GCP - Test
if: steps.gcp-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/gcp --cov-report=xml:gcp_coverage.xml tests/providers/gcp
# Test Kubernetes
- name: Kubernetes - Check if any file has changed
id: kubernetes-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/kubernetes/**
./tests/providers/kubernetes/**
.poetry.lock
- name: Kubernetes - Test
if: steps.kubernetes-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/kubernetes --cov-report=xml:kubernetes_coverage.xml tests/providers/kubernetes
# Test GitHub
- name: GitHub - Check if any file has changed
id: github-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/github/**
./tests/providers/github/**
.poetry.lock
- name: GitHub - Test
if: steps.github-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/github --cov-report=xml:github_coverage.xml tests/providers/github
# Test NHN
- name: NHN - Check if any file has changed
id: nhn-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/nhn/**
./tests/providers/nhn/**
.poetry.lock
- name: NHN - Test
if: steps.nhn-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/nhn --cov-report=xml:nhn_coverage.xml tests/providers/nhn
# Test M365
- name: M365 - Check if any file has changed
id: m365-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/m365/**
./tests/providers/m365/**
.poetry.lock
- name: M365 - Test
if: steps.m365-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/m365 --cov-report=xml:m365_coverage.xml tests/providers/m365
# Test IaC
- name: IaC - Check if any file has changed
id: iac-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/iac/**
./tests/providers/iac/**
.poetry.lock
- name: IaC - Test
if: steps.iac-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/iac --cov-report=xml:iac_coverage.xml tests/providers/iac
# Common Tests
- name: Lib - Test
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/lib --cov-report=xml:lib_coverage.xml tests/lib
- name: Config - Test
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/config --cov-report=xml:config_coverage.xml tests/config
# Codecov
- name: Upload coverage reports to Codecov
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
flags: prowler
files: ./aws_coverage.xml,./azure_coverage.xml,./gcp_coverage.xml,./kubernetes_coverage.xml,./github_coverage.xml,./nhn_coverage.xml,./m365_coverage.xml,./lib_coverage.xml,./config_coverage.xml

View File

@@ -1,4 +1,4 @@
name: PyPI release
name: SDK - PyPI release
on:
release:
@@ -7,15 +7,43 @@ on:
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
PYTHON_VERSION: 3.11
CACHE: "poetry"
# CACHE: "poetry"
jobs:
repository-check:
name: Repository check
runs-on: ubuntu-latest
outputs:
is_repo: ${{ steps.repository_check.outputs.is_repo }}
steps:
- name: Repository check
id: repository_check
working-directory: /tmp
run: |
if [[ ${{ github.repository }} == "prowler-cloud/prowler" ]]
then
echo "is_repo=true" >> "${GITHUB_OUTPUT}"
else
echo "This action only runs for prowler-cloud/prowler"
echo "is_repo=false" >> "${GITHUB_OUTPUT}"
fi
release-prowler-job:
runs-on: ubuntu-latest
needs: repository-check
if: needs.repository-check.outputs.is_repo == 'true'
env:
POETRY_VIRTUALENVS_CREATE: "false"
name: Release Prowler to PyPI
steps:
- name: Repository check
working-directory: /tmp
run: |
if [[ "${{ github.repository }}" != "prowler-cloud/prowler" ]]; then
echo "This action only runs for prowler-cloud/prowler"
exit 1
fi
- name: Get Prowler version
run: |
PROWLER_VERSION="${{ env.RELEASE_TAG }}"
@@ -36,17 +64,17 @@ jobs:
;;
esac
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install dependencies
run: |
pipx install poetry
pipx install poetry==2.1.1
- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: ${{ env.CACHE }}
# cache: ${{ env.CACHE }}
- name: Build Prowler package
run: |

View File

@@ -1,10 +1,10 @@
# This is a basic workflow to help you get started with Actions
name: Refresh regions of AWS services
name: SDK - Refresh AWS services' regions
on:
schedule:
- cron: "0 9 * * *" #runs at 09:00 UTC everyday
- cron: "0 9 * * 1" # runs at 09:00 UTC every Monday
env:
GITHUB_BRANCH: "master"
@@ -23,12 +23,12 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ env.GITHUB_BRANCH }}
- name: setup python
uses: actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: 3.9 #install the python needed
@@ -38,7 +38,7 @@ jobs:
pip install boto3
- name: Configure AWS Credentials -- DEV
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1
with:
aws-region: ${{ env.AWS_REGION_DEV }}
role-to-assume: ${{ secrets.DEV_IAM_ROLE_ARN }}
@@ -50,12 +50,13 @@ jobs:
# Create pull request
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
author: prowler-bot <179230569+prowler-bot@users.noreply.github.com>
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
commit-message: "feat(regions_update): Update regions for AWS services"
branch: "aws-services-regions-updated-${{ github.sha }}"
labels: "status/waiting-for-revision, severity/low, provider/aws, backport-to-v3"
labels: "status/waiting-for-revision, severity/low, provider/aws"
title: "chore(regions_update): Changes in regions for AWS services"
body: |
### Description

View File

@@ -0,0 +1,118 @@
name: UI - Build and Push containers
on:
push:
branches:
- "master"
paths:
- "ui/**"
- ".github/workflows/ui-build-lint-push-containers.yml"
# Uncomment the below code to test this action on PRs
# pull_request:
# branches:
# - "master"
# paths:
# - "ui/**"
# - ".github/workflows/ui-build-lint-push-containers.yml"
release:
types: [published]
env:
# Tags
LATEST_TAG: latest
RELEASE_TAG: ${{ github.event.release.tag_name }}
STABLE_TAG: stable
WORKING_DIRECTORY: ./ui
# Container Registries
PROWLERCLOUD_DOCKERHUB_REPOSITORY: prowlercloud
PROWLERCLOUD_DOCKERHUB_IMAGE: prowler-ui
jobs:
repository-check:
name: Repository check
runs-on: ubuntu-latest
outputs:
is_repo: ${{ steps.repository_check.outputs.is_repo }}
steps:
- name: Repository check
id: repository_check
working-directory: /tmp
run: |
if [[ ${{ github.repository }} == "prowler-cloud/prowler" ]]
then
echo "is_repo=true" >> "${GITHUB_OUTPUT}"
else
echo "This action only runs for prowler-cloud/prowler"
echo "is_repo=false" >> "${GITHUB_OUTPUT}"
fi
# Build Prowler OSS container
container-build-push:
needs: repository-check
if: needs.repository-check.outputs.is_repo == 'true'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ env.WORKING_DIRECTORY }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set short git commit SHA
id: vars
run: |
shortSha=$(git rev-parse --short ${{ github.sha }})
echo "SHORT_SHA=${shortSha}" >> $GITHUB_ENV
- name: Login to DockerHub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Build and push container image (latest)
# Comment the following line for testing
if: github.event_name == 'push'
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: ${{ env.WORKING_DIRECTORY }}
build-args: |
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=${{ env.SHORT_SHA }}
# Set push: false for testing
push: true
tags: |
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.LATEST_TAG }}
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.SHORT_SHA }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and push container image (release)
if: github.event_name == 'release'
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: ${{ env.WORKING_DIRECTORY }}
build-args: |
NEXT_PUBLIC_PROWLER_RELEASE_VERSION=v${{ env.RELEASE_TAG }}
push: true
tags: |
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.RELEASE_TAG }}
${{ env.PROWLERCLOUD_DOCKERHUB_REPOSITORY }}/${{ env.PROWLERCLOUD_DOCKERHUB_IMAGE }}:${{ env.STABLE_TAG }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Trigger deployment
if: github.event_name == 'push'
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0
with:
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
repository: ${{ secrets.CLOUD_DISPATCH }}
event-type: prowler-ui-deploy
client-payload: '{"sha": "${{ github.sha }}", "short_sha": "${{ env.SHORT_SHA }}"}'

View File

@@ -1,34 +0,0 @@
name: "UI - Pull Request"
on:
pull_request:
branches:
- master
paths:
- 'ui/**'
jobs:
test-and-coverage:
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest]
node-version: [20.x]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
working-directory: ./ui
run: npm install
- name: Run Healthcheck
working-directory: ./ui
run: npm run healthcheck
- name: Build the application
working-directory: ./ui
run: npm run build

View File

@@ -9,20 +9,18 @@
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "UI - CodeQL"
name: UI - CodeQL
on:
push:
branches:
- "master"
- "v4.*"
- "v5.*"
paths:
- "ui/**"
pull_request:
branches:
- "master"
- "v4.*"
- "v5.*"
paths:
- "ui/**"
@@ -46,16 +44,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/ui-codeql-config.yml
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
category: "/language:${{matrix.language}}"

82
.github/workflows/ui-end2end.yml vendored Normal file
View File

@@ -0,0 +1,82 @@
name: UI - E2E Tests
on:
pull_request:
branches:
- master
- "v5.*"
paths:
- 'ui/**'
env:
# Temporary secret for CI test runs only replace with GitHub Secret later
AUTH_SECRET: "N/c6mnaS5+SWq81+819OrzQZlmx1Vxtp/orjttJSmw8="
API_BASE_URL: "http://localhost:8080/api/v1"
SERVICES_TO_START: "api-dev postgres valkey worker-beat worker-dev"
DOCKER_COMPOSE_FILE: "docker-compose-dev.yml"
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: './ui/package-lock.json'
# - name: Cache Playwright Browsers
# uses: actions/cache@v4
# with:
# path: ~/.cache/ms-playwright
# key: playwright-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
# restore-keys: |
# playwright-${{ runner.os }}-
- name: Install dependencies
run: npm ci
working-directory: ./ui
- name: Install Playwright Browsers
run: npx playwright install --with-deps
working-directory: ./ui
- name: Set up Docker Compose
uses: docker/setup-compose-action@364cc21a5de5b1ee4a7f5f9d3fa374ce0ccde746 #v1.2.0
- name: Start Docker Compose
run: docker compose -f ${DOCKER_COMPOSE_FILE} up -d ${SERVICES_TO_START}
- name: Wait for API to be ready
run: |
for i in {1..30}; do
if curl -s http://localhost:8000/api/v1; then
echo "API is up!"
break
fi
echo "Waiting for API..."
sleep 5
done
- name: Run Playwright tests
run: npx playwright test
working-directory: ./ui
- name: Upload Playwright report
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: ./ui/playwright-report
- name: Upload Playwright videos
uses: actions/upload-artifact@v4
with:
name: test-videos
path: ./ui/test-results/**/*.webm
- name: Docker Compose Down
if: always()
run: docker compose -f ${DOCKER_COMPOSE_FILE} down

62
.github/workflows/ui-pull-request.yml vendored Normal file
View File

@@ -0,0 +1,62 @@
name: UI - Pull Request
on:
push:
branches:
- "master"
- "v5.*"
paths:
- ".github/workflows/ui-pull-request.yml"
- "ui/**"
pull_request:
branches:
- master
- "v5.*"
paths:
- 'ui/**'
env:
UI_WORKING_DIR: ./ui
IMAGE_NAME: prowler-ui
jobs:
test-and-coverage:
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest]
node-version: [20.x]
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
working-directory: ./ui
run: npm install
- name: Run Healthcheck
working-directory: ./ui
run: npm run healthcheck
- name: Build the application
working-directory: ./ui
run: npm run build
test-container-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Build Container
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: ${{ env.UI_WORKING_DIR }}
# Always build using `prod` target
target: prod
push: false
tags: ${{ env.IMAGE_NAME }}:latest
outputs: type=docker
build-args: |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_51LwpXXXX

7
.gitignore vendored
View File

@@ -31,7 +31,7 @@ tags
*.DS_Store
# Prowler output
output/
/output
# Prowler found secrets
secrets-*/
@@ -42,13 +42,18 @@ junit-reports/
# VSCode files
.vscode/
# Cursor files
.cursorignore
# Terraform
.terraform*
*.tfstate
*.tfstate.*
# .env
ui/.env*
api/.env*
.env.local
# Coverage
.coverage*

View File

@@ -27,6 +27,7 @@ repos:
hooks:
- id: shellcheck
exclude: contrib
## PYTHON
- repo: https://github.com/myint/autoflake
rev: v2.3.1
@@ -58,11 +59,28 @@ repos:
args: ["--ignore=E266,W503,E203,E501,W605"]
- repo: https://github.com/python-poetry/poetry
rev: 1.8.0
rev: 2.1.1
hooks:
- id: poetry-check
name: API - poetry-check
args: ["--directory=./api"]
pass_filenames: false
- id: poetry-lock
args: ["--no-update"]
name: API - poetry-lock
args: ["--directory=./api"]
pass_filenames: false
- id: poetry-check
name: SDK - poetry-check
args: ["--directory=./"]
pass_filenames: false
- id: poetry-lock
name: SDK - poetry-lock
args: ["--directory=./"]
pass_filenames: false
- repo: https://github.com/hadolint/hadolint
rev: v2.13.0-beta
@@ -90,20 +108,19 @@ repos:
- id: bandit
name: bandit
description: "Bandit is a tool for finding common security issues in Python code"
entry: bash -c 'bandit -q -lll -x '*_test.py,./contrib/' -r .'
entry: bash -c 'bandit -q -lll -x '*_test.py,./contrib/,./.venv/' -r .'
language: system
files: '.*\.py'
- id: safety
name: safety
description: "Safety is a tool that checks your installed dependencies for known security vulnerabilities"
entry: bash -c 'safety check --ignore 70612,66963'
entry: bash -c 'safety check --ignore 70612,66963,74429,76352,76353'
language: system
- id: vulture
name: vulture
description: "Vulture finds unused code in Python programs."
entry: bash -c 'vulture --exclude "contrib" --min-confidence 100 .'
exclude: 'api/src/backend/'
entry: bash -c 'vulture --exclude "contrib,.venv,api/src/backend/api/tests/,api/src/backend/conftest.py,api/src/backend/tasks/tests/" --min-confidence 100 .'
language: system
files: '.*\.py'

View File

@@ -1,38 +1,64 @@
FROM python:3.12-alpine
FROM python:3.12.10-slim-bookworm AS build
LABEL maintainer="https://github.com/prowler-cloud/prowler"
LABEL org.opencontainers.image.source="https://github.com/prowler-cloud/prowler"
# Update system dependencies and install essential tools
#hadolint ignore=DL3018
RUN apk --no-cache upgrade && apk --no-cache add curl git
ARG POWERSHELL_VERSION=7.5.0
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends wget libicu72 \
&& rm -rf /var/lib/apt/lists/*
# Install PowerShell
RUN ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then \
wget --progress=dot:giga https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell-${POWERSHELL_VERSION}-linux-x64.tar.gz -O /tmp/powershell.tar.gz ; \
elif [ "$ARCH" = "aarch64" ]; then \
wget --progress=dot:giga https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell-${POWERSHELL_VERSION}-linux-arm64.tar.gz -O /tmp/powershell.tar.gz ; \
else \
echo "Unsupported architecture: $ARCH" && exit 1 ; \
fi && \
mkdir -p /opt/microsoft/powershell/7 && \
tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && \
chmod +x /opt/microsoft/powershell/7/pwsh && \
ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && \
rm /tmp/powershell.tar.gz
# Add prowler user
RUN addgroup --gid 1000 prowler && \
adduser --uid 1000 --gid 1000 --disabled-password --gecos "" prowler
# Create non-root user
RUN mkdir -p /home/prowler && \
echo 'prowler:x:1000:1000:prowler:/home/prowler:' > /etc/passwd && \
echo 'prowler:x:1000:' > /etc/group && \
chown -R prowler:prowler /home/prowler
USER prowler
# Copy necessary files
WORKDIR /home/prowler
# Copy necessary files
COPY prowler/ /home/prowler/prowler/
COPY dashboard/ /home/prowler/dashboard/
COPY pyproject.toml /home/prowler
COPY README.md /home/prowler
COPY README.md /home/prowler/
COPY prowler/providers/m365/lib/powershell/m365_powershell.py /home/prowler/prowler/providers/m365/lib/powershell/m365_powershell.py
# Install Python dependencies
ENV HOME='/home/prowler'
ENV PATH="$HOME/.local/bin:$PATH"
RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \
pip install --no-cache-dir .
ENV PATH="${HOME}/.local/bin:${PATH}"
#hadolint ignore=DL3013
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir poetry
# By default poetry does not compile Python source files to bytecode during installation.
# This speeds up the installation process, but the first execution may take a little more
# time because Python then compiles source files to bytecode automatically. If you want to
# compile source files to bytecode during installation, you can use the --compile option
RUN poetry install --compile && \
rm -rf ~/.cache/pip
# Install PowerShell modules
RUN poetry run python prowler/providers/m365/lib/powershell/m365_powershell.py
# Remove deprecated dash dependencies
RUN pip uninstall dash-html-components -y && \
pip uninstall dash-core-components -y
# Remove Prowler directory and build files
USER 0
RUN rm -rf /home/prowler/prowler /home/prowler/pyproject.toml /home/prowler/README.md /home/prowler/build /home/prowler/prowler.egg-info
USER prowler
ENTRYPOINT ["prowler"]
ENTRYPOINT ["poetry", "run", "prowler"]

192
README.md
View File

@@ -3,7 +3,7 @@
<img align="center" src="https://github.com/prowler-cloud/prowler/blob/master/docs/img/prowler-logo-white.png#gh-dark-mode-only" width="50%" height="50%">
</p>
<p align="center">
<b><i>Prowler SaaS </b> and <b>Prowler Open Source</b> are as dynamic and adaptable as the environment theyre meant to protect. Trusted by the leaders in security.
<b><i>Prowler</b> 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.
</p>
<p align="center">
<b>Learn more at <a href="https://prowler.com">prowler.com</i></b>
@@ -29,7 +29,7 @@
<p align="center">
<a href="https://github.com/prowler-cloud/prowler"><img alt="Repo size" src="https://img.shields.io/github/repo-size/prowler-cloud/prowler"></a>
<a href="https://github.com/prowler-cloud/prowler/issues"><img alt="Issues" src="https://img.shields.io/github/issues/prowler-cloud/prowler"></a>
<a href="https://github.com/prowler-cloud/prowler/releases"><img alt="Version" src="https://img.shields.io/github/v/release/prowler-cloud/prowler?include_prereleases"></a>
<a href="https://github.com/prowler-cloud/prowler/releases"><img alt="Version" src="https://img.shields.io/github/v/release/prowler-cloud/prowler"></a>
<a href="https://github.com/prowler-cloud/prowler/releases"><img alt="Version" src="https://img.shields.io/github/release-date/prowler-cloud/prowler"></a>
<a href="https://github.com/prowler-cloud/prowler"><img alt="Contributors" src="https://img.shields.io/github/contributors-anon/prowler-cloud/prowler"></a>
<a href="https://github.com/prowler-cloud/prowler"><img alt="License" src="https://img.shields.io/github/license/prowler-cloud/prowler"></a>
@@ -43,15 +43,29 @@
# Description
**Prowler** is an Open Source security tool to perform AWS, Azure, Google Cloud and Kubernetes security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness, and also remediations! We have Prowler CLI (Command Line Interface) that we call Prowler Open Source and a service on top of it that we call <a href="https://prowler.com">Prowler SaaS</a>.
**Prowler** is an open-source security tool designed to assess and enforce security best practices across AWS, Azure, Google Cloud, and Kubernetes. It supports tasks such as security audits, incident response, continuous monitoring, system hardening, forensic readiness, and remediation processes.
Prowler includes hundreds of built-in controls to ensure compliance with standards and frameworks, including:
- **Industry Standards:** CIS, NIST 800, NIST CSF, and CISA
- **Regulatory Compliance and Governance:** RBI, FedRAMP, and PCI-DSS
- **Frameworks for Sensitive Data and Privacy:** GDPR, HIPAA, and FFIEC
- **Frameworks for Organizational Governance and Quality Control:** SOC2 and GXP
- **AWS-Specific Frameworks:** AWS Foundational Technical Review (FTR) and AWS Well-Architected Framework (Security Pillar)
- **National Security Standards:** ENS (Spanish National Security Scheme)
- **Custom Security Frameworks:** Tailored to your needs
## Prowler CLI and Prowler Cloud
Prowler offers a Command Line Interface (CLI), known as Prowler Open Source, and an additional service built on top of it, called <a href="https://prowler.com">Prowler Cloud</a>.
## Prowler App
Prowler App is a web application that allows you to run Prowler in your cloud provider accounts and visualize the results in a user-friendly interface.
Prowler App 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 App](docs/img/overview.png)
>More details at [Prowler App Documentation](https://docs.prowler.com/projects/prowler-open-source/en/latest/#prowler-app-installation)
>For more details, refer to the [Prowler App Documentation](https://docs.prowler.com/projects/prowler-open-source/en/latest/#prowler-app-installation)
## Prowler CLI
@@ -60,6 +74,7 @@ prowler <provider>
```
![Prowler CLI Execution](docs/img/short-display.png)
## Prowler Dashboard
```console
@@ -67,22 +82,34 @@ prowler dashboard
```
![Prowler Dashboard](docs/img/dashboard.png)
It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, FedRAMP, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, AWS Well-Architected Framework Security Pillar, AWS Foundational Technical Review (FTR), ENS (Spanish National Security Scheme) and your custom security frameworks.
# Prowler at a Glance
| 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) |
|---|---|---|---|---|
| AWS | 561 | 81 -> `prowler aws --list-services` | 30 -> `prowler aws --list-compliance` | 9 -> `prowler aws --list-categories` |
| GCP | 77 | 13 -> `prowler gcp --list-services` | 3 -> `prowler gcp --list-compliance` | 2 -> `prowler gcp --list-categories`|
| Azure | 139 | 18 -> `prowler azure --list-services` | 4 -> `prowler azure --list-compliance` | 2 -> `prowler azure --list-categories` |
| Kubernetes | 83 | 7 -> `prowler kubernetes --list-services` | 1 -> `prowler kubernetes --list-compliance` | 7 -> `prowler kubernetes --list-categories` |
| AWS | 567 | 82 | 36 | 10 |
| GCP | 79 | 13 | 10 | 3 |
| Azure | 142 | 18 | 10 | 3 |
| Kubernetes | 83 | 7 | 5 | 7 |
| GitHub | 16 | 2 | 1 | 0 |
| M365 | 69 | 7 | 3 | 2 |
| NHN (Unofficial) | 6 | 2 | 1 | 0 |
> [!Note]
> The numbers in the table are updated periodically.
> [!Tip]
> For the most accurate and up-to-date information about checks, services, frameworks, and categories, visit [**Prowler Hub**](https://hub.prowler.com).
> [!Note]
> Use the following commands to list Prowler's available checks, services, compliance frameworks, and categories: `prowler <provider> --list-checks`, `prowler <provider> --list-services`, `prowler <provider> --list-compliance` and `prowler <provider> --list-categories`.
# 💻 Installation
## Prowler App
Prowler App can be installed in different ways, depending on your environment:
Prowler App offers flexible installation methods tailored to various environments:
> See how to use Prowler App in the [Prowler App Usage Guide](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/prowler-app/).
> 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/).
### Docker Compose
@@ -98,14 +125,23 @@ curl -LO https://raw.githubusercontent.com/prowler-cloud/prowler/refs/heads/mast
docker compose up -d
```
> Enjoy Prowler App at http://localhost:3000 by signing up with your email and password.
> Containers are built for `linux/amd64`.
### Configuring Your Workstation for Prowler App
If your workstation's architecture is incompatible, you can resolve this by:
- **Setting the environment variable**: `DOCKER_DEFAULT_PLATFORM=linux/amd64`
- **Using the following flag in your Docker command**: `--platform linux/amd64`
> Once configured, access the Prowler App at http://localhost:3000. Sign up using your email and password to get started.
### From GitHub
**Requirements**
* `git` installed.
* `poetry` installed: [poetry installation](https://python-poetry.org/docs/#installation).
* `poetry` v2 installed: [poetry installation](https://python-poetry.org/docs/#installation).
* `npm` installed: [npm installation](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
* `Docker Compose` installed: https://docs.docker.com/compose/install/.
@@ -115,7 +151,7 @@ docker compose up -d
git clone https://github.com/prowler-cloud/prowler
cd prowler/api
poetry install
poetry shell
eval $(poetry env activate)
set -a
source .env
docker compose up postgres valkey -d
@@ -123,8 +159,13 @@ cd src/backend
python manage.py migrate --database admin
gunicorn -c config/guniconf.py config.wsgi:application
```
> [!IMPORTANT]
> As of Poetry v2.0.0, the `poetry shell` command has been deprecated. Use `poetry env activate` instead for environment activation.
>
> If your Poetry version is below v2.0.0, continue using `poetry shell` to activate your environment.
> For further guidance, refer to the Poetry Environment Activation Guide https://python-poetry.org/docs/managing-environments/#activating-the-environment.
> Now, you can access the API documentation at http://localhost:8080/api/v1/docs.
> After completing the setup, access the API documentation at http://localhost:8080/api/v1/docs.
**Commands to run the API Worker**
@@ -132,13 +173,26 @@ gunicorn -c config/guniconf.py config.wsgi:application
git clone https://github.com/prowler-cloud/prowler
cd prowler/api
poetry install
poetry shell
eval $(poetry env activate)
set -a
source .env
cd src/backend
python -m celery -A config.celery worker -l info -E
```
**Commands to run the API Scheduler**
``` console
git clone https://github.com/prowler-cloud/prowler
cd prowler/api
poetry install
eval $(poetry env activate)
set -a
source .env
cd src/backend
python -m celery -A config.celery beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
```
**Commands to run the UI**
``` console
@@ -149,29 +203,31 @@ npm run build
npm start
```
> Enjoy Prowler App at http://localhost:3000 by signing up with your email and password.
> Once configured, access the Prowler App at http://localhost:3000. Sign up using your email and password to get started.
## Prowler CLI
### Pip package
Prowler CLI is available as a project in [PyPI](https://pypi.org/project/prowler-cloud/), thus can be installed using pip with Python >= 3.9, < 3.13:
Prowler CLI is available as a project in [PyPI](https://pypi.org/project/prowler-cloud/). Consequently, it can be installed using pip with Python >3.9.1, <3.13:
```console
pip install prowler
prowler -v
```
>More details at [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/projects/prowler-open-source/en/latest/#prowler-cli-installation)
### Containers
The available versions of Prowler CLI are the following:
**Available Versions of Prowler CLI**
- `latest`: in sync with `master` branch (bear in mind that it is not a stable version)
- `v4-latest`: in sync with `v4` branch (bear in mind that it is not a stable version)
- `v3-latest`: in sync with `v3` branch (bear in mind that it is not a stable version)
- `<x.y.z>` (release): you can find the releases [here](https://github.com/prowler-cloud/prowler/releases), those are stable releases.
- `stable`: this tag always point to the latest release.
- `v4-stable`: this tag always point to the latest release for v4.
- `v3-stable`: this tag always point to the latest release for v3.
The following versions of Prowler CLI are available, depending on your requirements:
- `latest`: Synchronizes with the `master` branch. Note that this version is not stable.
- `v4-latest`: Synchronizes with the `v4` branch. Note that this version is not stable.
- `v3-latest`: Synchronizes with the `v3` branch. Note that this version is not stable.
- `<x.y.z>` (release): Stable releases corresponding to specific versions. You can find the complete list of releases [here](https://github.com/prowler-cloud/prowler/releases).
- `stable`: Always points to the latest release.
- `v4-stable`: Always points to the latest release for v4.
- `v3-stable`: Always points to the latest release for v3.
The container images are available here:
- Prowler CLI:
@@ -183,29 +239,56 @@ The container images are available here:
### From GitHub
Python >= 3.9, < 3.13 is required with pip and poetry:
Python >3.9.1, <3.13 is required with pip and Poetry:
``` console
git clone https://github.com/prowler-cloud/prowler
cd prowler
poetry shell
eval $(poetry env activate)
poetry install
python prowler.py -v
python prowler-cli.py -v
```
> If you want to clone Prowler from Windows, use `git config core.longpaths true` to allow long file paths.
# 📐✏️ High level architecture
> [!IMPORTANT]
> To clone Prowler on Windows, configure Git to support long file paths by running the following command: `git config core.longpaths true`.
> [!IMPORTANT]
> As of Poetry v2.0.0, the `poetry shell` command has been deprecated. Use `poetry env activate` instead for environment activation.
>
> If your Poetry version is below v2.0.0, continue using `poetry shell` to activate your environment.
> For further guidance, refer to the Poetry Environment Activation Guide https://python-poetry.org/docs/managing-environments/#activating-the-environment.
# ✏️ High level architecture
## Prowler App
The **Prowler App** consists of three main components:
**Prowler App** is composed of three key components:
- **Prowler UI**: A user-friendly web interface for running Prowler and viewing results, powered by Next.js.
- **Prowler API**: The backend API that executes Prowler scans and stores the results, built with Django REST Framework.
- **Prowler SDK**: A Python SDK that integrates with the Prowler CLI for advanced functionality.
- **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 App Architecture](docs/img/prowler-app-architecture.png)
## Prowler CLI
You can run Prowler from your workstation, a Kubernetes Job, a Google Compute Engine, an Azure VM, an EC2 instance, Fargate or any other container, CloudShell and many more.
**Running Prowler**
Prowler can be executed across various environments, offering flexibility to meet your needs. It can be run from:
- Your own workstation
- A Kubernetes Job
- Google Compute Engine
- Azure Virtual Machines (VMs)
- Amazon EC2 instances
- AWS Fargate or other container platforms
- CloudShell
And many more environments.
![Architecture](docs/img/architecture.png)
@@ -213,23 +296,36 @@ You can run Prowler from your workstation, a Kubernetes Job, a Google Compute En
## General
- `Allowlist` now is called `Mutelist`.
- The `--quiet` option has been deprecated, now use the `--status` flag to select the finding's status you want to get from PASS, FAIL or MANUAL.
- All `INFO` finding's status has changed to `MANUAL`.
- The CSV output format is common for all the providers.
- The `--quiet` option has been deprecated. Use the `--status` flag to filter findings based on their status: PASS, FAIL, or MANUAL.
- All findings with an `INFO` status have been reclassified as `MANUAL`.
- The CSV output format is standardized across all providers.
We have deprecated some of our outputs formats:
- The native JSON is replaced for the JSON [OCSF](https://schema.ocsf.io/) v1.1.0, common for all the providers.
**Deprecated Output Formats**
The following formats are now deprecated:
- Native JSON has been replaced with JSON in [OCSF] v1.1.0 format, which is standardized across all providers (https://schema.ocsf.io/).
## AWS
- Deprecate the AWS flag --sts-endpoint-region since we use AWS STS regional tokens.
- To send only FAILS to AWS Security Hub, now use either `--send-sh-only-fails` or `--security-hub --status FAIL`.
**AWS Flag Deprecation**
The flag --sts-endpoint-region has been deprecated due to the adoption of AWS STS regional tokens.
**Sending FAIL Results to AWS Security Hub**
- To send only FAILS to AWS Security Hub, use one of the following options: `--send-sh-only-fails` or `--security-hub --status FAIL`.
# 📖 Documentation
Install, Usage, Tutorials and Developer Guide is at https://docs.prowler.com/
**Documentation Resources**
For installation instructions, usage details, tutorials, and the Developer Guide, visit https://docs.prowler.com/
# 📃 License
Prowler is licensed as Apache License 2.0 as specified in each file. You may obtain a copy of the License at
<http://www.apache.org/licenses/LICENSE-2.0>
**Prowler License Information**
Prowler is licensed under the Apache License 2.0, as indicated in each file within the repository. Obtaining a Copy of the License
A copy of the License is available at <http://www.apache.org/licenses/LICENSE-2.0>

View File

@@ -22,6 +22,8 @@ DJANGO_SECRETS_ENCRYPTION_KEY=""
# Decide whether to allow Django manage database table partitions
DJANGO_MANAGE_DB_PARTITIONS=[True|False]
DJANGO_CELERY_DEADLOCK_ATTEMPTS=5
DJANGO_BROKER_VISIBILITY_TIMEOUT=86400
DJANGO_SENTRY_DSN=
# PostgreSQL settings
# If running django and celery on host, use 'localhost', else use 'postgres-db'
@@ -38,3 +40,19 @@ POSTGRES_DB=prowler_db
VALKEY_HOST=[localhost|valkey]
VALKEY_PORT=6379
VALKEY_DB=0
# Sentry settings
SENTRY_ENVIRONMENT=local
SENTRY_RELEASE=local
# Social login credentials
DJANGO_GOOGLE_OAUTH_CLIENT_ID=""
DJANGO_GOOGLE_OAUTH_CLIENT_SECRET=""
DJANGO_GOOGLE_OAUTH_CALLBACK_URL=""
DJANGO_GITHUB_OAUTH_CLIENT_ID=""
DJANGO_GITHUB_OAUTH_CLIENT_SECRET=""
DJANGO_GITHUB_OAUTH_CALLBACK_URL=""
# Deletion Task Batch Size
DJANGO_DELETION_BATCH_SIZE=5000

168
api/.gitignore vendored
View File

@@ -1,168 +0,0 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.pyc
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
/_data/
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
*.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
# VSCode
.vscode/

View File

@@ -1,91 +0,0 @@
repos:
## GENERAL
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-merge-conflict
- id: check-yaml
args: ["--unsafe"]
- id: check-json
- id: end-of-file-fixer
- id: trailing-whitespace
- id: no-commit-to-branch
- id: pretty-format-json
args: ["--autofix", "--no-sort-keys", "--no-ensure-ascii"]
exclude: 'src/backend/api/fixtures/dev/.*\.json$'
## TOML
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.13.0
hooks:
- id: pretty-format-toml
args: [--autofix]
files: pyproject.toml
## BASH
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.10.0
hooks:
- id: shellcheck
exclude: contrib
## PYTHON
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.5.0
hooks:
# Run the linter.
- id: ruff
args: [ --fix ]
# Run the formatter.
- id: ruff-format
- repo: https://github.com/python-poetry/poetry
rev: 1.8.0
hooks:
- id: poetry-check
args: ["--directory=src"]
- id: poetry-lock
args: ["--no-update", "--directory=src"]
- repo: https://github.com/hadolint/hadolint
rev: v2.13.0-beta
hooks:
- id: hadolint
args: ["--ignore=DL3013", "Dockerfile"]
- repo: local
hooks:
- id: pylint
name: pylint
entry: bash -c 'poetry run pylint --disable=W,C,R,E -j 0 -rn -sn src/'
language: system
files: '.*\.py'
- id: trufflehog
name: TruffleHog
description: Detect secrets in your data.
entry: bash -c 'trufflehog --no-update git file://. --only-verified --fail'
# For running trufflehog in docker, use the following entry instead:
# entry: bash -c 'docker run -v "$(pwd):/workdir" -i --rm trufflesecurity/trufflehog:latest git file:///workdir --only-verified --fail'
language: system
stages: ["commit", "push"]
- id: bandit
name: bandit
description: "Bandit is a tool for finding common security issues in Python code"
entry: bash -c 'poetry run bandit -q -lll -x '*_test.py,./contrib/,./.venv/' -r .'
language: system
files: '.*\.py'
- id: safety
name: safety
description: "Safety is a tool that checks your installed dependencies for known security vulnerabilities"
entry: bash -c 'poetry run safety check --ignore 70612,66963'
language: system
- id: vulture
name: vulture
description: "Vulture finds unused code in Python programs."
entry: bash -c 'poetry run vulture --exclude "contrib,.venv,tests,conftest.py" --min-confidence 100 .'
language: system
files: '.*\.py'

149
api/CHANGELOG.md Normal file
View File

@@ -0,0 +1,149 @@
# Prowler API Changelog
All notable changes to the **Prowler API** are documented in this file.
## [v1.9.0] (Prowler UNRELEASED)
### Added
- SSO with SAML support [(#7822)](https://github.com/prowler-cloud/prowler/pull/7822)
- Support GCP Service Account key [(#7824)](https://github.com/prowler-cloud/prowler/pull/7824)
- `GET /compliance-overviews` endpoints to retrieve compliance metadata and specific requirements statuses [(#7877)](https://github.com/prowler-cloud/prowler/pull/7877)
- Lighthouse configuration support [(#7848)](https://github.com/prowler-cloud/prowler/pull/7848)
### Changed
- Reworked `GET /compliance-overviews` to return proper requirement metrics [(#7877)](https://github.com/prowler-cloud/prowler/pull/7877)
---
## [v1.8.5] (Prowler v5.7.5)
### Fixed
- Normalize provider UID to ensure safe and unique export directory paths [(#8007)](https://github.com/prowler-cloud/prowler/pull/8007).
- Blank resource types in `/metadata` endpoints [(#8027)](https://github.com/prowler-cloud/prowler/pull/8027)
---
## [v1.8.4] (Prowler v5.7.4)
### Removed
- Reverted RLS transaction handling and DB custom backend [(#7994)](https://github.com/prowler-cloud/prowler/pull/7994)
---
## [v1.8.3] (Prowler v5.7.3)
### Added
- Database backend to handle already closed connections [(#7935)](https://github.com/prowler-cloud/prowler/pull/7935)
### Changed
- Renamed field encrypted_password to password for M365 provider [(#7784)](https://github.com/prowler-cloud/prowler/pull/7784)
### Fixed
- Transaction persistence with RLS operations [(#7916)](https://github.com/prowler-cloud/prowler/pull/7916)
- Reverted the change `get_with_retry` to use the original `get` method for retrieving tasks [(#7932)](https://github.com/prowler-cloud/prowler/pull/7932)
---
## [v1.8.2] (Prowler v5.7.2)
### Fixed
- Task lookup to use task_kwargs instead of task_args for scan report resolution [(#7830)](https://github.com/prowler-cloud/prowler/pull/7830)
- Kubernetes UID validation to allow valid context names [(#7871)](https://github.com/prowler-cloud/prowler/pull/7871)
- Connection status verification before launching a scan [(#7831)](https://github.com/prowler-cloud/prowler/pull/7831)
- Race condition when creating background tasks [(#7876)](https://github.com/prowler-cloud/prowler/pull/7876)
- Error when modifying or retrieving tenants due to missing user UUID in transaction context [(#7890)](https://github.com/prowler-cloud/prowler/pull/7890)
---
## [v1.8.1] (Prowler v5.7.1)
### Fixed
- Added database index to improve performance on finding lookup [(#7800)](https://github.com/prowler-cloud/prowler/pull/7800)
---
## [v1.8.0] (Prowler v5.7.0)
### Added
- Huge improvements to `/findings/metadata` and resource related filters for findings [(#7690)](https://github.com/prowler-cloud/prowler/pull/7690)
- Improvements to `/overviews` endpoints [(#7690)](https://github.com/prowler-cloud/prowler/pull/7690)
- Queue to perform backfill background tasks [(#7690)](https://github.com/prowler-cloud/prowler/pull/7690)
- New endpoints to retrieve latest findings and metadata [(#7743)](https://github.com/prowler-cloud/prowler/pull/7743)
- Export support for Prowler ThreatScore in M365 [(7783)](https://github.com/prowler-cloud/prowler/pull/7783)
---
## [v1.7.0] (Prowler v5.6.0)
### Added
- M365 as a new provider [(#7563)](https://github.com/prowler-cloud/prowler/pull/7563)
- `compliance/` folder and ZIPexport functionality for all compliance reports [(#7653)](https://github.com/prowler-cloud/prowler/pull/7653)
- API endpoint to fetch and download any specific compliance file by name [(#7653)](https://github.com/prowler-cloud/prowler/pull/7653)
---
## [v1.6.0] (Prowler v5.5.0)
### Added
- Support for developing new integrations [(#7167)](https://github.com/prowler-cloud/prowler/pull/7167)
- HTTP Security Headers [(#7289)](https://github.com/prowler-cloud/prowler/pull/7289)
- New endpoint to get the compliance overviews metadata [(#7333)](https://github.com/prowler-cloud/prowler/pull/7333)
- Support for muted findings [(#7378)](https://github.com/prowler-cloud/prowler/pull/7378)
- Missing fields to API findings and resources [(#7318)](https://github.com/prowler-cloud/prowler/pull/7318)
---
## [v1.5.4] (Prowler v5.4.4)
### Fixed
- Bug with periodic tasks when trying to delete a provider [(#7466)](https://github.com/prowler-cloud/prowler/pull/7466)
---
## [v1.5.3] (Prowler v5.4.3)
### Fixed
- Duplicated scheduled scans handling [(#7401)](https://github.com/prowler-cloud/prowler/pull/7401)
- Environment variable to configure the deletion task batch size [(#7423)](https://github.com/prowler-cloud/prowler/pull/7423)
---
## [v1.5.2] (Prowler v5.4.2)
### Changed
- Refactored deletion logic and implemented retry mechanism for deletion tasks [(#7349)](https://github.com/prowler-cloud/prowler/pull/7349)
---
## [v1.5.1] (Prowler v5.4.1)
### Fixed
- Handle response in case local files are missing [(#7183)](https://github.com/prowler-cloud/prowler/pull/7183)
- Race condition when deleting export files after the S3 upload [(#7172)](https://github.com/prowler-cloud/prowler/pull/7172)
- Handle exception when a provider has no secret in test connection [(#7283)](https://github.com/prowler-cloud/prowler/pull/7283)
---
## [v1.5.0] (Prowler v5.4.0)
### Added
- Social login integration with Google and GitHub [(#6906)](https://github.com/prowler-cloud/prowler/pull/6906)
- API scan report system, now all scans launched from the API will generate a compressed file with the report in OCSF, CSV and HTML formats [(#6878)](https://github.com/prowler-cloud/prowler/pull/6878)
- Configurable Sentry integration [(#6874)](https://github.com/prowler-cloud/prowler/pull/6874)
### Changed
- Optimized `GET /findings` endpoint to improve response time and size [(#7019)](https://github.com/prowler-cloud/prowler/pull/7019)
---
## [v1.4.0] (Prowler v5.3.0)
### Changed
- Daily scheduled scan instances are now created beforehand with `SCHEDULED` state [(#6700)](https://github.com/prowler-cloud/prowler/pull/6700)
- Findings endpoints now require at least one date filter [(#6800)](https://github.com/prowler-cloud/prowler/pull/6800)
- Findings metadata endpoint received a performance improvement [(#6863)](https://github.com/prowler-cloud/prowler/pull/6863)
- Increased the allowed length of the provider UID for Kubernetes providers [(#6869)](https://github.com/prowler-cloud/prowler/pull/6869)
---

View File

@@ -1,13 +1,45 @@
FROM python:3.12-alpine AS build
FROM python:3.12.10-slim-bookworm AS build
LABEL maintainer="https://github.com/prowler-cloud/api"
# hadolint ignore=DL3018
RUN apk --no-cache add gcc python3-dev musl-dev linux-headers curl-dev
ARG POWERSHELL_VERSION=7.5.0
ENV POWERSHELL_VERSION=${POWERSHELL_VERSION}
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
wget \
libicu72 \
gcc \
g++ \
make \
libxml2-dev \
libxmlsec1-dev \
libxmlsec1-openssl \
pkg-config \
libtool \
libxslt1-dev \
python3-dev \
&& rm -rf /var/lib/apt/lists/*
# Install PowerShell
RUN ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then \
wget --progress=dot:giga https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell-${POWERSHELL_VERSION}-linux-x64.tar.gz -O /tmp/powershell.tar.gz ; \
elif [ "$ARCH" = "aarch64" ]; then \
wget --progress=dot:giga https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell-${POWERSHELL_VERSION}-linux-arm64.tar.gz -O /tmp/powershell.tar.gz ; \
else \
echo "Unsupported architecture: $ARCH" && exit 1 ; \
fi && \
mkdir -p /opt/microsoft/powershell/7 && \
tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && \
chmod +x /opt/microsoft/powershell/7/pwsh && \
ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && \
rm /tmp/powershell.tar.gz
# Add prowler user
RUN addgroup --gid 1000 prowler && \
adduser --uid 1000 --gid 1000 --disabled-password --gecos "" prowler
RUN apk --no-cache upgrade && \
addgroup -g 1000 prowler && \
adduser -D -u 1000 -G prowler prowler
USER prowler
WORKDIR /home/prowler
@@ -17,27 +49,26 @@ COPY pyproject.toml ./
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir poetry
COPY src/backend/ ./backend/
ENV PATH="/home/prowler/.local/bin:$PATH"
RUN poetry install && \
# Add `--no-root` to avoid installing the current project as a package
RUN poetry install --no-root && \
rm -rf ~/.cache/pip
RUN poetry run python "$(poetry env info --path)/src/prowler/prowler/providers/m365/lib/powershell/m365_powershell.py"
# Prevents known compatibility error between lxml and libxml2/libxmlsec versions.
# See: https://github.com/xmlsec/python-xmlsec/issues/320
RUN poetry run pip install --force-reinstall --no-binary lxml lxml
COPY src/backend/ ./backend/
COPY docker-entrypoint.sh ./docker-entrypoint.sh
WORKDIR /home/prowler/backend
# Development image
# hadolint ignore=DL3006
FROM build AS dev
USER 0
# hadolint ignore=DL3018
RUN apk --no-cache add curl vim
USER prowler
ENTRYPOINT ["../docker-entrypoint.sh", "dev"]
# Production image

View File

@@ -235,6 +235,7 @@ To view the logs for any component (e.g., Django, Celery worker), you can use th
```console
docker logs -f $(docker ps --format "{{.Names}}" | grep 'api-')
```
## Applying migrations
@@ -269,3 +270,66 @@ poetry shell
cd src/backend
pytest
```
# Custom commands
Django provides a way to create custom commands that can be run from the command line.
> These commands can be found in: ```prowler/api/src/backend/api/management/commands```
To run a custom command, you need to be in the `prowler/api/src/backend` directory and run:
```console
poetry shell
python manage.py <command_name>
```
## Generate dummy data
```console
python manage.py findings --tenant
<TENANT_ID> --findings <NUM_FINDINGS> --re
sources <NUM_RESOURCES> --batch <TRANSACTION_BATCH_SIZE> --alias <ALIAS>
```
This command creates, for a given tenant, a provider, scan and a set of findings and resources related altogether.
> Scan progress and state are updated in real time.
> - 0-33%: Create resources.
> - 33-66%: Create findings.
> - 66%: Create resource-finding mapping.
>
> The last step is required to access the findings details, since the UI needs that to print all the information.
### Example
```console
~/backend $ poetry run python manage.py findings --tenant
fffb1893-3fc7-4623-a5d9-fae47da1c528 --findings 25000 --re
sources 1000 --batch 5000 --alias test-script
Starting data population
Tenant: fffb1893-3fc7-4623-a5d9-fae47da1c528
Alias: test-script
Resources: 1000
Findings: 25000
Batch size: 5000
Creating resources...
100%|███████████████████████| 1/1 [00:00<00:00, 7.72it/s]
Resources created successfully.
Creating findings...
100%|███████████████████████| 5/5 [00:05<00:00, 1.09s/it]
Findings created successfully.
Creating resource-finding mappings...
100%|███████████████████████| 5/5 [00:02<00:00, 1.81it/s]
Resource-finding mappings created successfully.
Successfully populated test data.
```

View File

@@ -1,125 +0,0 @@
services:
api:
build:
dockerfile: Dockerfile
image: prowler-api
env_file:
- path: ./.env
required: false
ports:
- "${DJANGO_PORT:-8000}:${DJANGO_PORT:-8000}"
profiles:
- prod
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
entrypoint:
- "../docker-entrypoint.sh"
- "prod"
api-dev:
build:
dockerfile: Dockerfile
target: dev
image: prowler-api-dev
environment:
- DJANGO_SETTINGS_MODULE=config.django.devel
- DJANGO_LOGGING_FORMATTER=human_readable
env_file:
- path: ./.env
required: false
ports:
- "${DJANGO_PORT:-8080}:${DJANGO_PORT:-8080}"
volumes:
- "./src/backend:/home/prowler/backend"
- "./pyproject.toml:/home/prowler/pyproject.toml"
profiles:
- dev
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
entrypoint:
- "../docker-entrypoint.sh"
- "dev"
postgres:
image: postgres:16.3-alpine
ports:
- "${POSTGRES_PORT:-5432}:${POSTGRES_PORT:-5432}"
hostname: "postgres-db"
volumes:
- ./_data/postgres:/var/lib/postgresql/data
environment:
- POSTGRES_USER=${POSTGRES_ADMIN_USER:-prowler}
- POSTGRES_PASSWORD=${POSTGRES_ADMIN_PASSWORD:-S3cret}
- POSTGRES_DB=${POSTGRES_DB:-prowler_db}
env_file:
- path: ./.env
required: false
healthcheck:
test: ["CMD-SHELL", "sh -c 'pg_isready -U ${POSTGRES_ADMIN_USER:-prowler} -d ${POSTGRES_DB:-prowler_db}'"]
interval: 5s
timeout: 5s
retries: 5
valkey:
image: valkey/valkey:7-alpine3.19
ports:
- "${VALKEY_PORT:-6379}:6379"
hostname: "valkey"
volumes:
- ./_data/valkey:/data
env_file:
- path: ./.env
required: false
healthcheck:
test: ["CMD-SHELL", "sh -c 'valkey-cli ping'"]
interval: 10s
timeout: 5s
retries: 3
worker:
build:
dockerfile: Dockerfile
image: prowler-worker
environment:
- DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE:-config.django.production}
env_file:
- path: ./.env
required: false
profiles:
- dev
- prod
depends_on:
valkey:
condition: service_healthy
postgres:
condition: service_healthy
entrypoint:
- "../docker-entrypoint.sh"
- "worker"
worker-beat:
build:
dockerfile: Dockerfile
image: prowler-worker
environment:
- DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE:-config.django.production}
env_file:
- path: ./.env
required: false
profiles:
- dev
- prod
depends_on:
valkey:
condition: service_healthy
postgres:
condition: service_healthy
entrypoint:
- "../docker-entrypoint.sh"
- "beat"

View File

@@ -3,6 +3,10 @@
apply_migrations() {
echo "Applying database migrations..."
# Fix Inconsistent migration history after adding sites app
poetry run python manage.py check_and_fix_socialaccount_sites_migration --database admin
poetry run python manage.py migrate --database admin
}
@@ -28,7 +32,7 @@ start_prod_server() {
start_worker() {
echo "Starting the worker..."
poetry run python -m celery -A config.celery worker -l "${DJANGO_LOGGING_LEVEL:-info}" -Q celery,scans -E
poetry run python -m celery -A config.celery worker -l "${DJANGO_LOGGING_LEVEL:-info}" -Q celery,scans,scan-reports,deletion,backfill -E --max-tasks-per-child 1
}
start_worker_beat() {

3982
api/poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,43 +2,52 @@
build-backend = "poetry.core.masonry.api"
requires = ["poetry-core"]
[tool.poetry]
authors = ["Prowler Team"]
[project]
authors = [{name = "Prowler Engineering", email = "engineering@prowler.com"}]
dependencies = [
"celery[pytest] (>=5.4.0,<6.0.0)",
"dj-rest-auth[with_social,jwt] (==7.0.1)",
"django==5.1.10",
"django-allauth[saml] (>=65.8.0,<66.0.0)",
"django-celery-beat (>=2.7.0,<3.0.0)",
"django-celery-results (>=2.5.1,<3.0.0)",
"django-cors-headers==4.4.0",
"django-environ==0.11.2",
"django-filter==24.3",
"django-guid==3.5.0",
"django-postgres-extra (>=2.0.8,<3.0.0)",
"djangorestframework==3.15.2",
"djangorestframework-jsonapi==7.0.2",
"djangorestframework-simplejwt (>=5.3.1,<6.0.0)",
"drf-nested-routers (>=0.94.1,<1.0.0)",
"drf-spectacular==0.27.2",
"drf-spectacular-jsonapi==0.5.1",
"gunicorn==23.0.0",
"prowler @ git+https://github.com/prowler-cloud/prowler.git@master",
"psycopg2-binary==2.9.9",
"pytest-celery[redis] (>=1.0.1,<2.0.0)",
"sentry-sdk[django] (>=2.20.0,<3.0.0)",
"uuid6==2024.7.10",
"openai (>=1.82.0,<2.0.0)"
]
description = "Prowler's API (Django/DRF)"
license = "Apache-2.0"
name = "prowler-api"
package-mode = false
version = "1.0.0"
# Needed for the SDK compatibility
requires-python = ">=3.11,<3.13"
version = "1.9.0"
[tool.poetry.dependencies]
celery = {extras = ["pytest"], version = "^5.4.0"}
django = "5.1.1"
django-celery-beat = "^2.7.0"
django-celery-results = "^2.5.1"
django-cors-headers = "4.4.0"
django-environ = "0.11.2"
django-filter = "24.3"
django-guid = "3.5.0"
django-postgres-extra = "^2.0.8"
djangorestframework = "3.15.2"
djangorestframework-jsonapi = "7.0.2"
djangorestframework-simplejwt = "^5.3.1"
drf-nested-routers = "^0.94.1"
drf-spectacular = "0.27.2"
drf-spectacular-jsonapi = "0.5.1"
gunicorn = "23.0.0"
prowler = {git = "https://github.com/prowler-cloud/prowler.git", branch = "master"}
psycopg2-binary = "2.9.9"
pytest-celery = {extras = ["redis"], version = "^1.0.1"}
# Needed for prowler compatibility
python = ">=3.11,<3.13"
uuid6 = "2024.7.10"
[project.scripts]
celery = "src.backend.config.settings.celery"
[tool.poetry.group.dev.dependencies]
bandit = "1.7.9"
coverage = "7.5.4"
django-silk = "5.3.2"
docker = "7.1.0"
freezegun = "1.5.1"
marshmallow = ">=3.15.0,<4.0.0"
mypy = "1.10.1"
pylint = "3.2.5"
pytest = "8.2.2"
@@ -48,8 +57,6 @@ pytest-env = "1.1.3"
pytest-randomly = "3.15.0"
pytest-xdist = "3.6.1"
ruff = "0.5.0"
safety = "3.2.3"
vulture = "2.11"
[tool.poetry.scripts]
celery = "src.backend.config.settings.celery"
safety = "3.2.9"
tqdm = "4.67.1"
vulture = "2.14"

View File

@@ -0,0 +1,123 @@
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from django.db import transaction
from api.db_router import MainRouter
from api.db_utils import rls_transaction
from api.models import (
Membership,
Role,
SAMLConfiguration,
Tenant,
User,
UserRoleRelationship,
)
class ProwlerSocialAccountAdapter(DefaultSocialAccountAdapter):
@staticmethod
def get_user_by_email(email: str):
try:
return User.objects.get(email=email)
except User.DoesNotExist:
return None
def pre_social_login(self, request, sociallogin):
# Link existing accounts with the same email address
email = sociallogin.account.extra_data.get("email")
if sociallogin.account.provider == "saml":
email = sociallogin.user.email
if email:
existing_user = self.get_user_by_email(email)
if existing_user:
sociallogin.connect(request, existing_user)
def save_user(self, request, sociallogin, form=None):
"""
Called after the user data is fully populated from the provider
and is about to be saved to the DB for the first time.
"""
with transaction.atomic(using=MainRouter.admin_db):
user = super().save_user(request, sociallogin, form)
provider = sociallogin.account.provider
extra = sociallogin.account.extra_data
if provider == "saml":
# Handle SAML-specific logic
user.first_name = extra.get("firstName", [""])[0]
user.last_name = extra.get("lastName", [""])[0]
user.company_name = extra.get("organization", [""])[0]
user.name = f"{user.first_name} {user.last_name}".strip()
user.save(using=MainRouter.admin_db)
email_domain = user.email.split("@")[-1]
tenant = (
SAMLConfiguration.objects.using(MainRouter.admin_db)
.get(email_domain=email_domain)
.tenant
)
with rls_transaction(str(tenant.id)):
role_name = extra.get("userType", ["saml_default_role"])[0].strip()
try:
role = Role.objects.using(MainRouter.admin_db).get(
name=role_name, tenant_id=tenant.id
)
except Role.DoesNotExist:
role = Role.objects.using(MainRouter.admin_db).create(
name=role_name,
tenant_id=tenant.id,
manage_users=False,
manage_account=False,
manage_billing=False,
manage_providers=False,
manage_integrations=False,
manage_scans=False,
unlimited_visibility=False,
)
Membership.objects.using(MainRouter.admin_db).create(
user=user,
tenant=tenant,
role=Membership.RoleChoices.MEMBER,
)
UserRoleRelationship.objects.using(MainRouter.admin_db).create(
user=user,
role=role,
tenant_id=tenant.id,
)
else:
# Handle other providers (e.g., GitHub, Google)
user.save(using=MainRouter.admin_db)
social_account_name = extra.get("name")
if social_account_name:
user.name = social_account_name
user.save(using=MainRouter.admin_db)
tenant = Tenant.objects.using(MainRouter.admin_db).create(
name=f"{user.email.split('@')[0]} default tenant"
)
with rls_transaction(str(tenant.id)):
Membership.objects.using(MainRouter.admin_db).create(
user=user, tenant=tenant, role=Membership.RoleChoices.OWNER
)
role = Role.objects.using(MainRouter.admin_db).create(
name="admin",
tenant_id=tenant.id,
manage_users=True,
manage_account=True,
manage_billing=True,
manage_providers=True,
manage_integrations=True,
manage_scans=True,
unlimited_visibility=True,
)
UserRoleRelationship.objects.using(MainRouter.admin_db).create(
user=user,
role=role,
tenant_id=tenant.id,
)
return user

View File

@@ -1,20 +1,23 @@
import uuid
from django.db import transaction, connection
from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from rest_framework import permissions
from rest_framework.exceptions import NotAuthenticated
from rest_framework.filters import SearchFilter
from rest_framework_json_api import filters
from rest_framework_json_api.serializers import ValidationError
from rest_framework_json_api.views import ModelViewSet
from rest_framework_simplejwt.authentication import JWTAuthentication
from api.db_router import MainRouter
from api.db_utils import POSTGRES_USER_VAR, rls_transaction
from api.filters import CustomDjangoFilterBackend
from api.models import Role, Tenant
from api.rbac.permissions import HasPermissions
class BaseViewSet(ModelViewSet):
authentication_classes = [JWTAuthentication]
permission_classes = [permissions.IsAuthenticated]
required_permissions = []
permission_classes = [permissions.IsAuthenticated, HasPermissions]
filter_backends = [
filters.QueryParameterValidationFilter,
filters.OrderingFilter,
@@ -28,6 +31,17 @@ class BaseViewSet(ModelViewSet):
ordering_fields = "__all__"
ordering = ["id"]
def initial(self, request, *args, **kwargs):
"""
Sets required_permissions before permissions are checked.
"""
self.set_required_permissions()
super().initial(request, *args, **kwargs)
def set_required_permissions(self):
"""This is an abstract method that must be implemented by subclasses."""
NotImplemented
def get_queryset(self):
raise NotImplementedError
@@ -47,13 +61,7 @@ class BaseRLSViewSet(BaseViewSet):
if tenant_id is None:
raise NotAuthenticated("Tenant ID is not present in token")
try:
uuid.UUID(tenant_id)
except ValueError:
raise ValidationError("Tenant ID must be a valid UUID")
with connection.cursor() as cursor:
cursor.execute(f"SELECT set_config('api.tenant_id', '{tenant_id}', TRUE);")
with rls_transaction(tenant_id):
self.request.tenant_id = tenant_id
return super().initial(request, *args, **kwargs)
@@ -66,13 +74,50 @@ class BaseRLSViewSet(BaseViewSet):
class BaseTenantViewset(BaseViewSet):
def dispatch(self, request, *args, **kwargs):
with transaction.atomic():
return super().dispatch(request, *args, **kwargs)
tenant = super().dispatch(request, *args, **kwargs)
try:
# If the request is a POST, create the admin role
if request.method == "POST":
isinstance(tenant, dict) and self._create_admin_role(tenant.data["id"])
except Exception as e:
self._handle_creation_error(e, tenant)
raise
return tenant
def _create_admin_role(self, tenant_id):
Role.objects.using(MainRouter.admin_db).create(
name="admin",
tenant_id=tenant_id,
manage_users=True,
manage_account=True,
manage_billing=True,
manage_providers=True,
manage_integrations=True,
manage_scans=True,
unlimited_visibility=True,
)
def _handle_creation_error(self, error, tenant):
if tenant.data.get("id"):
try:
Tenant.objects.using(MainRouter.admin_db).filter(
id=tenant.data["id"]
).delete()
except ObjectDoesNotExist:
pass # Tenant might not exist, handle gracefully
def initial(self, request, *args, **kwargs):
user_id = str(request.user.id)
if request.auth is None:
raise NotAuthenticated
with connection.cursor() as cursor:
cursor.execute(f"SELECT set_config('api.user_id', '{user_id}', TRUE);")
tenant_id = request.auth.get("tenant_id")
if tenant_id is None:
raise NotAuthenticated("Tenant ID is not present in token")
user_id = str(request.user.id)
with rls_transaction(value=user_id, parameter=POSTGRES_USER_VAR):
return super().initial(request, *args, **kwargs)
@@ -92,12 +137,6 @@ class BaseUserViewset(BaseViewSet):
if tenant_id is None:
raise NotAuthenticated("Tenant ID is not present in token")
try:
uuid.UUID(tenant_id)
except ValueError:
raise ValidationError("Tenant ID must be a valid UUID")
with connection.cursor() as cursor:
cursor.execute(f"SELECT set_config('api.tenant_id', '{tenant_id}', TRUE);")
with rls_transaction(tenant_id):
self.request.tenant_id = tenant_id
return super().initial(request, *args, **kwargs)

View File

@@ -1,12 +1,38 @@
from types import MappingProxyType
from api.models import Provider
from prowler.config.config import get_available_compliance_frameworks
from prowler.lib.check.compliance_models import Compliance
from prowler.lib.check.models import CheckMetadata
from api.models import Provider
PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE = {}
PROWLER_CHECKS = {}
AVAILABLE_COMPLIANCE_FRAMEWORKS = {}
def get_compliance_frameworks(provider_type: Provider.ProviderChoices) -> list[str]:
"""
Retrieve and cache the list of available compliance frameworks for a specific cloud provider.
This function lazily loads and caches the available compliance frameworks (e.g., CIS, MITRE, ISO)
for each provider type (AWS, Azure, GCP, etc.) on first access. Subsequent calls for the same
provider will return the cached result.
Args:
provider_type (Provider.ProviderChoices): The cloud provider type for which to retrieve
available compliance frameworks (e.g., "aws", "azure", "gcp", "m365").
Returns:
list[str]: A list of framework identifiers (e.g., "cis_1.4_aws", "mitre_attack_azure") available
for the given provider.
"""
global AVAILABLE_COMPLIANCE_FRAMEWORKS
if provider_type not in AVAILABLE_COMPLIANCE_FRAMEWORKS:
AVAILABLE_COMPLIANCE_FRAMEWORKS[provider_type] = (
get_available_compliance_frameworks(provider_type)
)
return AVAILABLE_COMPLIANCE_FRAMEWORKS[provider_type]
def get_prowler_provider_checks(provider_type: Provider.ProviderChoices):
@@ -164,10 +190,16 @@ def generate_compliance_overview_template(prowler_compliance: dict):
total_checks = len(requirement.Checks)
checks_dict = {check: None for check in requirement.Checks}
req_status_val = "MANUAL" if total_checks == 0 else "PASS"
# Build requirement dictionary
requirement_dict = {
"name": requirement.Name or requirement.Id,
"description": requirement.Description,
"tactics": getattr(requirement, "Tactics", []),
"subtechniques": getattr(requirement, "SubTechniques", []),
"platforms": getattr(requirement, "Platforms", []),
"technique_url": getattr(requirement, "TechniqueURL", ""),
"attributes": [
dict(attribute) for attribute in requirement.Attributes
],
@@ -178,20 +210,18 @@ def generate_compliance_overview_template(prowler_compliance: dict):
"manual": 0,
"total": total_checks,
},
"status": "PASS",
"status": req_status_val,
}
# Update requirements status
if total_checks == 0:
# Update requirements status counts for the framework
if req_status_val == "MANUAL":
requirements_status["manual"] += 1
elif req_status_val == "PASS":
requirements_status["passed"] += 1
# Add requirement to compliance requirements
compliance_requirements[requirement.Id] = requirement_dict
# Calculate pending requirements
pending_requirements = total_requirements - requirements_status["manual"]
requirements_status["passed"] = pending_requirements
# Build compliance dictionary
compliance_dict = {
"framework": compliance_data.Framework,

View File

@@ -1,18 +1,29 @@
ALLOWED_APPS = ("django", "socialaccount", "account", "authtoken", "silk")
class MainRouter:
default_db = "default"
admin_db = "admin"
def db_for_read(self, model, **hints): # noqa: F841
model_table_name = model._meta.db_table
if model_table_name.startswith("django_"):
if model_table_name.startswith("django_") or any(
model_table_name.startswith(f"{app}_") for app in ALLOWED_APPS
):
return self.admin_db
return None
def db_for_write(self, model, **hints): # noqa: F841
model_table_name = model._meta.db_table
if model_table_name.startswith("django_"):
if any(model_table_name.startswith(f"{app}_") for app in ALLOWED_APPS):
return self.admin_db
return None
def allow_migrate(self, db, app_label, model_name=None, **hints): # noqa: F841
return db == self.admin_db
def allow_relation(self, obj1, obj2, **hints): # noqa: F841
# Allow relations if both objects are in either "default" or "admin" db connectors
if {obj1._state.db, obj2._state.db} <= {self.default_db, self.admin_db}:
return True
return None

View File

@@ -1,13 +1,16 @@
import re
import secrets
import uuid
from contextlib import contextmanager
from datetime import datetime, timedelta, timezone
from django.conf import settings
from django.contrib.auth.models import BaseUserManager
from django.core.paginator import Paginator
from django.db import connection, models, transaction
from django_celery_beat.models import PeriodicTask
from psycopg2 import connect as psycopg2_connect
from psycopg2.extensions import AsIs, new_type, register_adapter, register_type
from rest_framework_json_api.serializers import ValidationError
DB_USER = settings.DATABASES["default"]["USER"] if not settings.TESTING else "test"
DB_PASSWORD = (
@@ -23,6 +26,8 @@ TASK_RUNNER_DB_TABLE = "django_celery_results_taskresult"
POSTGRES_TENANT_VAR = "api.tenant_id"
POSTGRES_USER_VAR = "api.user_id"
SET_CONFIG_QUERY = "SELECT set_config(%s, %s::text, TRUE);"
@contextmanager
def psycopg_connection(database_alias: str):
@@ -44,10 +49,23 @@ def psycopg_connection(database_alias: str):
@contextmanager
def tenant_transaction(tenant_id: str):
def rls_transaction(value: str, parameter: str = POSTGRES_TENANT_VAR):
"""
Creates a new database transaction setting the given configuration value for Postgres RLS. It validates the
if the value is a valid UUID.
Args:
value (str): Database configuration parameter value.
parameter (str): Database configuration parameter name, by default is 'api.tenant_id'.
"""
with transaction.atomic():
with connection.cursor() as cursor:
cursor.execute(f"SELECT set_config('api.tenant_id', '{tenant_id}', TRUE);")
try:
# just in case the value is an UUID object
uuid.UUID(str(value))
except ValueError:
raise ValidationError("Must be a valid UUID")
cursor.execute(SET_CONFIG_QUERY, [parameter, value])
yield cursor
@@ -89,11 +107,12 @@ def generate_random_token(length: int = 14, symbols: str | None = None) -> str:
return "".join(secrets.choice(symbols or _symbols) for _ in range(length))
def batch_delete(queryset, batch_size=5000):
def batch_delete(tenant_id, queryset, batch_size=settings.DJANGO_DELETION_BATCH_SIZE):
"""
Deletes objects in batches and returns the total number of deletions and a summary.
Args:
tenant_id (str): Tenant ID the queryset belongs to.
queryset (QuerySet): The queryset of objects to delete.
batch_size (int): The number of objects to delete in each batch.
@@ -103,21 +122,59 @@ def batch_delete(queryset, batch_size=5000):
total_deleted = 0
deletion_summary = {}
paginator = Paginator(queryset.order_by("id").only("id"), batch_size)
while True:
with rls_transaction(tenant_id, POSTGRES_TENANT_VAR):
# Get a batch of IDs to delete
batch_ids = set(
queryset.values_list("id", flat=True).order_by("id")[:batch_size]
)
if not batch_ids:
# No more objects to delete
break
for page_num in paginator.page_range:
batch_ids = [obj.id for obj in paginator.page(page_num).object_list]
deleted_count, deleted_info = queryset.filter(id__in=batch_ids).delete()
deleted_count, deleted_info = queryset.filter(id__in=batch_ids).delete()
total_deleted += deleted_count
for model_label, count in deleted_info.items():
deletion_summary[model_label] = deletion_summary.get(model_label, 0) + count
return total_deleted, deletion_summary
def delete_related_daily_task(provider_id: str):
"""
Deletes the periodic task associated with a specific provider.
Args:
provider_id (str): The unique identifier for the provider
whose related periodic task should be deleted.
"""
task_name = f"scan-perform-scheduled-{provider_id}"
PeriodicTask.objects.filter(name=task_name).delete()
def create_objects_in_batches(
tenant_id: str, model, objects: list, batch_size: int = 500
):
"""
Bulk-create model instances in repeated, per-tenant RLS transactions.
All chunks execute in their own transaction, so no single transaction
grows too large.
Args:
tenant_id (str): UUID string of the tenant under which to set RLS.
model: Django model class whose `.objects.bulk_create()` will be called.
objects (list): List of model instances (unsaved) to bulk-create.
batch_size (int): Maximum number of objects per bulk_create call.
"""
total = len(objects)
for i in range(0, total, batch_size):
chunk = objects[i : i + batch_size]
with rls_transaction(value=tenant_id, parameter=POSTGRES_TENANT_VAR):
model.objects.bulk_create(chunk, batch_size)
# Postgres Enums
@@ -193,6 +250,167 @@ def register_enum(apps, schema_editor, enum_class): # noqa: F841
register_adapter(enum_class, enum_adapter)
def _should_create_index_on_partition(
partition_name: str, all_partitions: bool = False
) -> bool:
"""
Determine if we should create an index on this partition.
Args:
partition_name: The name of the partition (e.g., "findings_2025_aug", "findings_default")
all_partitions: If True, create on all partitions. If False, only current/future partitions.
Returns:
bool: True if index should be created on this partition, False otherwise.
"""
if all_partitions:
return True
# Extract date from partition name if it follows the pattern
# Partition names look like: findings_2025_aug, findings_2025_jul, etc.
date_pattern = r"(\d{4})_([a-z]{3})$"
match = re.search(date_pattern, partition_name)
if not match:
# If we can't parse the date, include it to be safe (e.g., default partition)
return True
try:
year_str, month_abbr = match.groups()
year = int(year_str)
# Map month abbreviations to numbers
month_map = {
"jan": 1,
"feb": 2,
"mar": 3,
"apr": 4,
"may": 5,
"jun": 6,
"jul": 7,
"aug": 8,
"sep": 9,
"oct": 10,
"nov": 11,
"dec": 12,
}
month = month_map.get(month_abbr.lower())
if month is None:
# Unknown month abbreviation, include it to be safe
return True
partition_date = datetime(year, month, 1, tzinfo=timezone.utc)
# Get current month start
now = datetime.now(timezone.utc)
current_month_start = now.replace(
day=1, hour=0, minute=0, second=0, microsecond=0
)
# Include current month and future partitions
return partition_date >= current_month_start
except (ValueError, TypeError):
# If date parsing fails, include it to be safe
return True
def create_index_on_partitions(
apps, # noqa: F841
schema_editor,
parent_table: str,
index_name: str,
columns: str,
method: str = "BTREE",
where: str = "",
all_partitions: bool = True,
):
"""
Create an index on existing partitions of `parent_table`.
Args:
parent_table: The name of the root table (e.g. "findings").
index_name: A short name for the index (will be prefixed per-partition).
columns: The parenthesized column list, e.g. "tenant_id, scan_id, status".
method: The index method—BTREE, GIN, etc. Defaults to BTREE.
where: Optional WHERE clause (without the leading "WHERE"), e.g. "status = 'FAIL'".
all_partitions: Whether to create indexes on all partitions or just current/future ones.
Defaults to False (current/future only) to avoid maintenance overhead
on old partitions where the index may not be needed.
Examples:
# Create index only on current and future partitions (recommended for new indexes)
create_index_on_partitions(
apps, schema_editor,
parent_table="findings",
index_name="new_performance_idx",
columns="tenant_id, status, severity",
all_partitions=False # Default behavior
)
# Create index on all partitions (use when migrating existing critical indexes)
create_index_on_partitions(
apps, schema_editor,
parent_table="findings",
index_name="critical_existing_idx",
columns="tenant_id, scan_id",
all_partitions=True
)
"""
with connection.cursor() as cursor:
cursor.execute(
"""
SELECT inhrelid::regclass::text
FROM pg_inherits
WHERE inhparent = %s::regclass
""",
[parent_table],
)
partitions = [row[0] for row in cursor.fetchall()]
where_sql = f" WHERE {where}" if where else ""
for partition in partitions:
if _should_create_index_on_partition(partition, all_partitions):
idx_name = f"{partition.replace('.', '_')}_{index_name}"
sql = (
f"CREATE INDEX CONCURRENTLY IF NOT EXISTS {idx_name} "
f"ON {partition} USING {method} ({columns})"
f"{where_sql};"
)
schema_editor.execute(sql)
def drop_index_on_partitions(
apps, # noqa: F841
schema_editor,
parent_table: str,
index_name: str,
):
"""
Drop the per-partition indexes that were created by create_index_on_partitions.
Args:
parent_table: The name of the root table (e.g. "findings").
index_name: The same short name used when creating them.
"""
with connection.cursor() as cursor:
cursor.execute(
"""
SELECT inhrelid::regclass::text
FROM pg_inherits
WHERE inhparent = %s::regclass
""",
[parent_table],
)
partitions = [row[0] for row in cursor.fetchall()]
for partition in partitions:
idx_name = f"{partition.replace('.', '_')}_{index_name}"
sql = f"DROP INDEX CONCURRENTLY IF EXISTS {idx_name};"
schema_editor.execute(sql)
# Postgres enum definition for member role
@@ -299,3 +517,15 @@ class InvitationStateEnum(EnumType):
class InvitationStateEnumField(PostgresEnumField):
def __init__(self, *args, **kwargs):
super().__init__("invitation_state", *args, **kwargs)
# Postgres enum definition for Integration type
class IntegrationTypeEnum(EnumType):
enum_type_name = "integration_type"
class IntegrationTypeEnumField(PostgresEnumField):
def __init__(self, *args, **kwargs):
super().__init__("integration_type", *args, **kwargs)

View File

@@ -1,9 +1,13 @@
import uuid
from functools import wraps
from django.db import connection, transaction
from rest_framework_json_api.serializers import ValidationError
from api.db_utils import POSTGRES_TENANT_VAR, SET_CONFIG_QUERY
def set_tenant(func):
def set_tenant(func=None, *, keep_tenant=False):
"""
Decorator to set the tenant context for a Celery task based on the provided tenant_id.
@@ -31,22 +35,34 @@ def set_tenant(func):
pass
# When calling the task
some_task.delay(arg1, tenant_id="1234-abcd-5678")
some_task.delay(arg1, tenant_id="8db7ca86-03cc-4d42-99f6-5e480baf6ab5")
# The tenant context will be set before the task logic executes.
"""
@wraps(func)
@transaction.atomic
def wrapper(*args, **kwargs):
try:
tenant_id = kwargs.pop("tenant_id")
except KeyError:
raise KeyError("This task requires the tenant_id")
def decorator(func):
@wraps(func)
@transaction.atomic
def wrapper(*args, **kwargs):
try:
if not keep_tenant:
tenant_id = kwargs.pop("tenant_id")
else:
tenant_id = kwargs["tenant_id"]
except KeyError:
raise KeyError("This task requires the tenant_id")
try:
uuid.UUID(tenant_id)
except ValueError:
raise ValidationError("Tenant ID must be a valid UUID")
with connection.cursor() as cursor:
cursor.execute(SET_CONFIG_QUERY, [POSTGRES_TENANT_VAR, tenant_id])
with connection.cursor() as cursor:
cursor.execute(f"SELECT set_config('api.tenant_id', '{tenant_id}', TRUE);")
return func(*args, **kwargs)
return func(*args, **kwargs)
return wrapper
return wrapper
if func is None:
return decorator
else:
return decorator(func)

View File

@@ -3,7 +3,7 @@ from rest_framework import status
from rest_framework.exceptions import APIException
from rest_framework_json_api.exceptions import exception_handler
from rest_framework_json_api.serializers import ValidationError
from rest_framework_simplejwt.exceptions import TokenError, InvalidToken
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
class ModelValidationError(ValidationError):
@@ -32,6 +32,31 @@ class InvitationTokenExpiredException(APIException):
default_code = "token_expired"
# Task Management Exceptions (non-HTTP)
class TaskManagementError(Exception):
"""Base exception for task management errors."""
def __init__(self, task=None):
self.task = task
super().__init__()
class TaskFailedException(TaskManagementError):
"""Raised when a task has failed."""
class TaskNotFoundException(TaskManagementError):
"""Raised when a task is not found."""
class TaskInProgressException(TaskManagementError):
"""Raised when a task is running but there's no related Task object to return."""
def __init__(self, task_result=None):
self.task_result = task_result
super().__init__()
def custom_exception_handler(exc, context):
if isinstance(exc, django_validation_error):
if hasattr(exc, "error_dict"):
@@ -39,7 +64,12 @@ def custom_exception_handler(exc, context):
else:
exc = ValidationError(detail=exc.messages[0], code=exc.code)
elif isinstance(exc, (TokenError, InvalidToken)):
exc.detail["messages"] = [
message_item["message"] for message_item in exc.detail["messages"]
]
if (
hasattr(exc, "detail")
and isinstance(exc.detail, dict)
and "messages" in exc.detail
):
exc.detail["messages"] = [
message_item["message"] for message_item in exc.detail["messages"]
]
return exception_handler(exc, context)

View File

@@ -1,4 +1,4 @@
from datetime import date, datetime, timezone
from datetime import date, datetime, timedelta, timezone
from django.conf import settings
from django.db.models import Q
@@ -22,15 +22,18 @@ from api.db_utils import (
StatusEnumField,
)
from api.models import (
ComplianceOverview,
ComplianceRequirementOverview,
Finding,
Integration,
Invitation,
Membership,
PermissionChoices,
Provider,
ProviderGroup,
ProviderSecret,
Resource,
ResourceTag,
Role,
Scan,
ScanSummary,
SeverityChoices,
@@ -78,6 +81,114 @@ class ChoiceInFilter(BaseInFilter, ChoiceFilter):
pass
class CommonFindingFilters(FilterSet):
# We filter providers from the scan in findings
provider = UUIDFilter(field_name="scan__provider__id", lookup_expr="exact")
provider__in = UUIDInFilter(field_name="scan__provider__id", lookup_expr="in")
provider_type = ChoiceFilter(
choices=Provider.ProviderChoices.choices, field_name="scan__provider__provider"
)
provider_type__in = ChoiceInFilter(
choices=Provider.ProviderChoices.choices, field_name="scan__provider__provider"
)
provider_uid = CharFilter(field_name="scan__provider__uid", lookup_expr="exact")
provider_uid__in = CharInFilter(field_name="scan__provider__uid", lookup_expr="in")
provider_uid__icontains = CharFilter(
field_name="scan__provider__uid", lookup_expr="icontains"
)
provider_alias = CharFilter(field_name="scan__provider__alias", lookup_expr="exact")
provider_alias__in = CharInFilter(
field_name="scan__provider__alias", lookup_expr="in"
)
provider_alias__icontains = CharFilter(
field_name="scan__provider__alias", lookup_expr="icontains"
)
updated_at = DateFilter(field_name="updated_at", lookup_expr="date")
uid = CharFilter(field_name="uid")
delta = ChoiceFilter(choices=Finding.DeltaChoices.choices)
status = ChoiceFilter(choices=StatusChoices.choices)
severity = ChoiceFilter(choices=SeverityChoices)
impact = ChoiceFilter(choices=SeverityChoices)
muted = BooleanFilter(
help_text="If this filter is not provided, muted and non-muted findings will be returned."
)
resources = UUIDInFilter(field_name="resource__id", lookup_expr="in")
region = CharFilter(method="filter_resource_region")
region__in = CharInFilter(field_name="resource_regions", lookup_expr="overlap")
region__icontains = CharFilter(
field_name="resource_regions", lookup_expr="icontains"
)
service = CharFilter(method="filter_resource_service")
service__in = CharInFilter(field_name="resource_services", lookup_expr="overlap")
service__icontains = CharFilter(
field_name="resource_services", lookup_expr="icontains"
)
resource_uid = CharFilter(field_name="resources__uid")
resource_uid__in = CharInFilter(field_name="resources__uid", lookup_expr="in")
resource_uid__icontains = CharFilter(
field_name="resources__uid", lookup_expr="icontains"
)
resource_name = CharFilter(field_name="resources__name")
resource_name__in = CharInFilter(field_name="resources__name", lookup_expr="in")
resource_name__icontains = CharFilter(
field_name="resources__name", lookup_expr="icontains"
)
resource_type = CharFilter(method="filter_resource_type")
resource_type__in = CharInFilter(field_name="resource_types", lookup_expr="overlap")
resource_type__icontains = CharFilter(
field_name="resources__type", lookup_expr="icontains"
)
# Temporarily disabled until we implement tag filtering in the UI
# resource_tag_key = CharFilter(field_name="resources__tags__key")
# resource_tag_key__in = CharInFilter(
# field_name="resources__tags__key", lookup_expr="in"
# )
# resource_tag_key__icontains = CharFilter(
# field_name="resources__tags__key", lookup_expr="icontains"
# )
# resource_tag_value = CharFilter(field_name="resources__tags__value")
# resource_tag_value__in = CharInFilter(
# field_name="resources__tags__value", lookup_expr="in"
# )
# resource_tag_value__icontains = CharFilter(
# field_name="resources__tags__value", lookup_expr="icontains"
# )
# resource_tags = CharInFilter(
# method="filter_resource_tag",
# lookup_expr="in",
# help_text="Filter by resource tags `key:value` pairs.\nMultiple values may be "
# "separated by commas.",
# )
def filter_resource_service(self, queryset, name, value):
return queryset.filter(resource_services__contains=[value])
def filter_resource_region(self, queryset, name, value):
return queryset.filter(resource_regions__contains=[value])
def filter_resource_type(self, queryset, name, value):
return queryset.filter(resource_types__contains=[value])
def filter_resource_tag(self, queryset, name, value):
overall_query = Q()
for key_value_pair in value:
tag_key, tag_value = key_value_pair.split(":", 1)
overall_query |= Q(
resources__tags__key__icontains=tag_key,
resources__tags__value__icontains=tag_value,
)
return queryset.filter(overall_query).distinct()
class TenantFilter(FilterSet):
inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date")
updated_at = DateFilter(field_name="updated_at", lookup_expr="date")
@@ -254,76 +365,20 @@ class ResourceFilter(ProviderRelationshipFilterSet):
return queryset.filter(tags__text_search=value)
class FindingFilter(FilterSet):
# We filter providers from the scan in findings
provider = UUIDFilter(field_name="scan__provider__id", lookup_expr="exact")
provider__in = UUIDInFilter(field_name="scan__provider__id", lookup_expr="in")
provider_type = ChoiceFilter(
choices=Provider.ProviderChoices.choices, field_name="scan__provider__provider"
)
provider_type__in = ChoiceInFilter(
choices=Provider.ProviderChoices.choices, field_name="scan__provider__provider"
)
provider_uid = CharFilter(field_name="scan__provider__uid", lookup_expr="exact")
provider_uid__in = CharInFilter(field_name="scan__provider__uid", lookup_expr="in")
provider_uid__icontains = CharFilter(
field_name="scan__provider__uid", lookup_expr="icontains"
)
provider_alias = CharFilter(field_name="scan__provider__alias", lookup_expr="exact")
provider_alias__in = CharInFilter(
field_name="scan__provider__alias", lookup_expr="in"
)
provider_alias__icontains = CharFilter(
field_name="scan__provider__alias", lookup_expr="icontains"
)
updated_at = DateFilter(field_name="updated_at", lookup_expr="date")
uid = CharFilter(field_name="uid")
delta = ChoiceFilter(choices=Finding.DeltaChoices.choices)
status = ChoiceFilter(choices=StatusChoices.choices)
severity = ChoiceFilter(choices=SeverityChoices)
impact = ChoiceFilter(choices=SeverityChoices)
resources = UUIDInFilter(field_name="resource__id", lookup_expr="in")
region = CharFilter(field_name="resources__region")
region__in = CharInFilter(field_name="resources__region", lookup_expr="in")
region__icontains = CharFilter(
field_name="resources__region", lookup_expr="icontains"
)
service = CharFilter(field_name="resources__service")
service__in = CharInFilter(field_name="resources__service", lookup_expr="in")
service__icontains = CharFilter(
field_name="resources__service", lookup_expr="icontains"
)
resource_uid = CharFilter(field_name="resources__uid")
resource_uid__in = CharInFilter(field_name="resources__uid", lookup_expr="in")
resource_uid__icontains = CharFilter(
field_name="resources__uid", lookup_expr="icontains"
)
resource_name = CharFilter(field_name="resources__name")
resource_name__in = CharInFilter(field_name="resources__name", lookup_expr="in")
resource_name__icontains = CharFilter(
field_name="resources__name", lookup_expr="icontains"
)
resource_type = CharFilter(field_name="resources__type")
resource_type__in = CharInFilter(field_name="resources__type", lookup_expr="in")
resource_type__icontains = CharFilter(
field_name="resources__type", lookup_expr="icontains"
)
class FindingFilter(CommonFindingFilters):
scan = UUIDFilter(method="filter_scan_id")
scan__in = UUIDInFilter(method="filter_scan_id_in")
inserted_at = DateFilter(method="filter_inserted_at", lookup_expr="date")
inserted_at__date = DateFilter(method="filter_inserted_at", lookup_expr="date")
inserted_at__gte = DateFilter(method="filter_inserted_at_gte")
inserted_at__lte = DateFilter(method="filter_inserted_at_lte")
inserted_at__gte = DateFilter(
method="filter_inserted_at_gte",
help_text=f"Maximum date range is {settings.FINDINGS_MAX_DAYS_IN_RANGE} days.",
)
inserted_at__lte = DateFilter(
method="filter_inserted_at_lte",
help_text=f"Maximum date range is {settings.FINDINGS_MAX_DAYS_IN_RANGE} days.",
)
class Meta:
model = Finding
@@ -351,6 +406,61 @@ class FindingFilter(FilterSet):
},
}
def filter_resource_type(self, queryset, name, value):
return queryset.filter(resource_types__contains=[value])
def filter_resource_region(self, queryset, name, value):
return queryset.filter(resource_regions__contains=[value])
def filter_resource_service(self, queryset, name, value):
return queryset.filter(resource_services__contains=[value])
def filter_queryset(self, queryset):
if not (self.data.get("scan") or self.data.get("scan__in")) and not (
self.data.get("inserted_at")
or self.data.get("inserted_at__date")
or self.data.get("inserted_at__gte")
or self.data.get("inserted_at__lte")
):
raise ValidationError(
[
{
"detail": "At least one date filter is required: filter[inserted_at], filter[inserted_at.gte], "
"or filter[inserted_at.lte].",
"status": 400,
"source": {"pointer": "/data/attributes/inserted_at"},
"code": "required",
}
]
)
gte_date = (
datetime.strptime(self.data.get("inserted_at__gte"), "%Y-%m-%d").date()
if self.data.get("inserted_at__gte")
else datetime.now(timezone.utc).date()
)
lte_date = (
datetime.strptime(self.data.get("inserted_at__lte"), "%Y-%m-%d").date()
if self.data.get("inserted_at__lte")
else datetime.now(timezone.utc).date()
)
if abs(lte_date - gte_date) > timedelta(
days=settings.FINDINGS_MAX_DAYS_IN_RANGE
):
raise ValidationError(
[
{
"detail": f"The date range cannot exceed {settings.FINDINGS_MAX_DAYS_IN_RANGE} days.",
"status": 400,
"source": {"pointer": "/data/attributes/inserted_at"},
"code": "invalid",
}
]
)
return super().filter_queryset(queryset)
# Convert filter values to UUIDv7 values for use with partitioning
def filter_scan_id(self, queryset, name, value):
try:
@@ -371,9 +481,7 @@ class FindingFilter(FilterSet):
)
return (
queryset.filter(id__gte=start)
.filter(id__lt=end)
.filter(scan__id=value_uuid)
queryset.filter(id__gte=start).filter(id__lt=end).filter(scan_id=value_uuid)
)
def filter_scan_id_in(self, queryset, name, value):
@@ -398,31 +506,32 @@ class FindingFilter(FilterSet):
]
)
if start == end:
return queryset.filter(id__gte=start).filter(scan__id__in=uuid_list)
return queryset.filter(id__gte=start).filter(scan_id__in=uuid_list)
else:
return (
queryset.filter(id__gte=start)
.filter(id__lt=end)
.filter(scan__id__in=uuid_list)
.filter(scan_id__in=uuid_list)
)
def filter_inserted_at(self, queryset, name, value):
value = self.maybe_date_to_datetime(value)
start = uuid7_start(datetime_to_uuid7(value))
datetime_value = self.maybe_date_to_datetime(value)
start = uuid7_start(datetime_to_uuid7(datetime_value))
end = uuid7_start(datetime_to_uuid7(datetime_value + timedelta(days=1)))
return queryset.filter(id__gte=start).filter(inserted_at__date=value)
return queryset.filter(id__gte=start, id__lt=end)
def filter_inserted_at_gte(self, queryset, name, value):
value = self.maybe_date_to_datetime(value)
start = uuid7_start(datetime_to_uuid7(value))
datetime_value = self.maybe_date_to_datetime(value)
start = uuid7_start(datetime_to_uuid7(datetime_value))
return queryset.filter(id__gte=start).filter(inserted_at__gte=value)
return queryset.filter(id__gte=start)
def filter_inserted_at_lte(self, queryset, name, value):
value = self.maybe_date_to_datetime(value)
end = uuid7_start(datetime_to_uuid7(value))
datetime_value = self.maybe_date_to_datetime(value)
end = uuid7_start(datetime_to_uuid7(datetime_value + timedelta(days=1)))
return queryset.filter(id__lte=end).filter(inserted_at__lte=value)
return queryset.filter(id__lt=end)
@staticmethod
def maybe_date_to_datetime(value):
@@ -432,6 +541,31 @@ class FindingFilter(FilterSet):
return dt
class LatestFindingFilter(CommonFindingFilters):
class Meta:
model = Finding
fields = {
"id": ["exact", "in"],
"uid": ["exact", "in"],
"delta": ["exact", "in"],
"status": ["exact", "in"],
"severity": ["exact", "in"],
"impact": ["exact", "in"],
"check_id": ["exact", "in", "icontains"],
}
filter_overrides = {
FindingDeltaEnumField: {
"filter_class": CharFilter,
},
StatusEnumField: {
"filter_class": CharFilter,
},
SeverityEnumField: {
"filter_class": CharFilter,
},
}
class ProviderSecretFilter(FilterSet):
inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date")
updated_at = DateFilter(field_name="updated_at", lookup_expr="date")
@@ -481,14 +615,33 @@ class UserFilter(FilterSet):
}
class ComplianceOverviewFilter(FilterSet):
class RoleFilter(FilterSet):
inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date")
provider_type = ChoiceFilter(choices=Provider.ProviderChoices.choices)
provider_type__in = ChoiceInFilter(choices=Provider.ProviderChoices.choices)
scan_id = UUIDFilter(field_name="scan__id")
updated_at = DateFilter(field_name="updated_at", lookup_expr="date")
permission_state = ChoiceFilter(
choices=PermissionChoices.choices, method="filter_permission_state"
)
def filter_permission_state(self, queryset, name, value):
return Role.filter_by_permission_state(queryset, value)
class Meta:
model = ComplianceOverview
model = Role
fields = {
"id": ["exact", "in"],
"name": ["exact", "in"],
"inserted_at": ["gte", "lte"],
"updated_at": ["gte", "lte"],
}
class ComplianceOverviewFilter(FilterSet):
inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date")
scan_id = UUIDFilter(field_name="scan_id")
region = CharFilter(field_name="region")
class Meta:
model = ComplianceRequirementOverview
fields = {
"inserted_at": ["date", "gte", "lte"],
"compliance_id": ["exact", "icontains"],
@@ -508,12 +661,6 @@ class ScanSummaryFilter(FilterSet):
field_name="scan__provider__provider", choices=Provider.ProviderChoices.choices
)
region = CharFilter(field_name="region")
muted_findings = BooleanFilter(method="filter_muted_findings")
def filter_muted_findings(self, queryset, name, value):
if not value:
return queryset.exclude(muted__gt=0)
return queryset
class Meta:
model = ScanSummary
@@ -521,3 +668,39 @@ class ScanSummaryFilter(FilterSet):
"inserted_at": ["date", "gte", "lte"],
"region": ["exact", "icontains", "in"],
}
class ServiceOverviewFilter(ScanSummaryFilter):
def is_valid(self):
# Check if at least one of the inserted_at filters is present
inserted_at_filters = [
self.data.get("inserted_at"),
self.data.get("inserted_at__gte"),
self.data.get("inserted_at__lte"),
]
if not any(inserted_at_filters):
raise ValidationError(
{
"inserted_at": [
"At least one of filter[inserted_at], filter[inserted_at__gte], or "
"filter[inserted_at__lte] is required."
]
}
)
return super().is_valid()
class IntegrationFilter(FilterSet):
inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date")
integration_type = ChoiceFilter(choices=Integration.IntegrationChoices.choices)
integration_type__in = ChoiceInFilter(
choices=Integration.IntegrationChoices.choices,
field_name="integration_type",
lookup_expr="in",
)
class Meta:
model = Integration
fields = {
"inserted_at": ["date", "gte", "lte"],
}

View File

@@ -122,6 +122,22 @@
"scanner_args": {}
}
},
{
"model": "api.provider",
"pk": "7791914f-d646-4fe2-b2ed-73f2c6499a36",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:45:26.352Z",
"updated_at": "2024-10-18T11:16:23.533Z",
"provider": "kubernetes",
"uid": "gke_lucky-coast-419309_us-central1_autopilot-cluster-2",
"alias": "k8s_testing_2",
"connected": true,
"connection_last_checked_at": "2024-10-18T11:16:23.503Z",
"metadata": {},
"scanner_args": {}
}
},
{
"model": "api.providersecret",
"pk": "11491b47-75ae-4f71-ad8d-3e630a72182e",

View File

@@ -11,9 +11,7 @@
"unique_resource_count": 1,
"duration": 5,
"scanner_args": {
"checks_to_execute": [
"accessanalyzer_enabled"
]
"checks_to_execute": ["accessanalyzer_enabled"]
},
"inserted_at": "2024-09-01T17:25:27.050Z",
"started_at": "2024-09-01T17:25:27.050Z",
@@ -33,9 +31,7 @@
"unique_resource_count": 1,
"duration": 20,
"scanner_args": {
"checks_to_execute": [
"accessanalyzer_enabled"
]
"checks_to_execute": ["accessanalyzer_enabled"]
},
"inserted_at": "2024-09-02T17:24:27.050Z",
"started_at": "2024-09-02T17:24:27.050Z",
@@ -55,9 +51,7 @@
"unique_resource_count": 10,
"duration": 10,
"scanner_args": {
"checks_to_execute": [
"cloudsql_instance_automated_backups"
]
"checks_to_execute": ["cloudsql_instance_automated_backups"]
},
"inserted_at": "2024-09-02T19:26:27.050Z",
"started_at": "2024-09-02T19:26:27.050Z",
@@ -77,9 +71,7 @@
"unique_resource_count": 1,
"duration": 35,
"scanner_args": {
"checks_to_execute": [
"accessanalyzer_enabled"
]
"checks_to_execute": ["accessanalyzer_enabled"]
},
"inserted_at": "2024-09-02T19:27:27.050Z",
"started_at": "2024-09-02T19:27:27.050Z",
@@ -97,9 +89,7 @@
"name": "test scheduled aws scan",
"state": "available",
"scanner_args": {
"checks_to_execute": [
"cloudformation_stack_outputs_find_secrets"
]
"checks_to_execute": ["cloudformation_stack_outputs_find_secrets"]
},
"scheduled_at": "2030-09-02T19:20:27.050Z",
"inserted_at": "2024-09-02T19:24:27.050Z",
@@ -178,9 +168,7 @@
"unique_resource_count": 19,
"progress": 100,
"scanner_args": {
"checks_to_execute": [
"accessanalyzer_enabled"
]
"checks_to_execute": ["accessanalyzer_enabled"]
},
"duration": 7,
"scheduled_at": null,
@@ -190,6 +178,56 @@
"completed_at": "2024-10-18T10:46:05.127Z"
}
},
{
"model": "api.scan",
"pk": "6dd8925f-a52d-48de-a546-d2d90db30ab1",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"name": "real scan azure",
"provider": "1b59e032-3eb6-4694-93a5-df84cd9b3ce2",
"trigger": "manual",
"state": "completed",
"unique_resource_count": 20,
"progress": 100,
"scanner_args": {
"checks_to_execute": [
"accessanalyzer_enabled",
"account_security_contact_information_is_registered"
]
},
"duration": 4,
"scheduled_at": null,
"inserted_at": "2024-10-18T11:16:21.358Z",
"updated_at": "2024-10-18T11:16:26.060Z",
"started_at": "2024-10-18T11:16:21.593Z",
"completed_at": "2024-10-18T11:16:26.060Z"
}
},
{
"model": "api.scan",
"pk": "4ca7ce89-3236-41a8-a369-8937bc152af5",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"name": "real scan k8s",
"provider": "7791914f-d646-4fe2-b2ed-73f2c6499a36",
"trigger": "manual",
"state": "completed",
"unique_resource_count": 20,
"progress": 100,
"scanner_args": {
"checks_to_execute": [
"accessanalyzer_enabled",
"account_security_contact_information_is_registered"
]
},
"duration": 4,
"scheduled_at": null,
"inserted_at": "2024-10-18T11:16:21.358Z",
"updated_at": "2024-10-18T11:16:26.060Z",
"started_at": "2024-10-18T11:16:21.593Z",
"completed_at": "2024-10-18T11:16:26.060Z"
}
},
{
"model": "api.scan",
"pk": "01929f57-c0ee-7553-be0b-cbde006fb6f7",

View File

@@ -6,6 +6,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.823Z",
"updated_at": "2024-10-18T10:46:04.841Z",
"first_seen_at": "2024-10-18T10:46:04.823Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-south-2-112233445566",
"delta": "new",
"status": "FAIL",
@@ -61,6 +62,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.855Z",
"updated_at": "2024-10-18T10:46:04.858Z",
"first_seen_at": "2024-10-18T10:46:04.855Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-west-3-112233445566",
"delta": "new",
"status": "FAIL",
@@ -116,6 +118,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.869Z",
"updated_at": "2024-10-18T10:46:04.876Z",
"first_seen_at": "2024-10-18T10:46:04.869Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-central-2-112233445566",
"delta": "new",
"status": "FAIL",
@@ -171,6 +174,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.888Z",
"updated_at": "2024-10-18T10:46:04.892Z",
"first_seen_at": "2024-10-18T10:46:04.888Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-west-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -226,6 +230,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.901Z",
"updated_at": "2024-10-18T10:46:04.905Z",
"first_seen_at": "2024-10-18T10:46:04.901Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-us-east-2-112233445566",
"delta": "new",
"status": "FAIL",
@@ -281,6 +286,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.915Z",
"updated_at": "2024-10-18T10:46:04.919Z",
"first_seen_at": "2024-10-18T10:46:04.915Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-south-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -336,6 +342,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.929Z",
"updated_at": "2024-10-18T10:46:04.934Z",
"first_seen_at": "2024-10-18T10:46:04.929Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-us-west-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -391,6 +398,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.944Z",
"updated_at": "2024-10-18T10:46:04.947Z",
"first_seen_at": "2024-10-18T10:46:04.944Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ca-central-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -446,6 +454,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.957Z",
"updated_at": "2024-10-18T10:46:04.962Z",
"first_seen_at": "2024-10-18T10:46:04.957Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-us-east-1-ConsoleAnalyzer-83b66ad7-d024-454e-b851-52d11cc1cf7c",
"delta": "new",
"status": "PASS",
@@ -501,6 +510,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.971Z",
"updated_at": "2024-10-18T10:46:04.975Z",
"first_seen_at": "2024-10-18T10:46:04.971Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-west-2-112233445566",
"delta": "new",
"status": "FAIL",
@@ -556,6 +566,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.984Z",
"updated_at": "2024-10-18T10:46:04.989Z",
"first_seen_at": "2024-10-18T10:46:04.984Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-sa-east-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -611,6 +622,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:04.999Z",
"updated_at": "2024-10-18T10:46:05.003Z",
"first_seen_at": "2024-10-18T10:46:04.999Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-north-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -666,6 +678,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:05.013Z",
"updated_at": "2024-10-18T10:46:05.018Z",
"first_seen_at": "2024-10-18T10:46:05.013Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-us-west-2-112233445566",
"delta": "new",
"status": "FAIL",
@@ -721,6 +734,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:05.029Z",
"updated_at": "2024-10-18T10:46:05.033Z",
"first_seen_at": "2024-10-18T10:46:05.029Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-southeast-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -776,6 +790,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:05.045Z",
"updated_at": "2024-10-18T10:46:05.050Z",
"first_seen_at": "2024-10-18T10:46:05.045Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-central-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -831,6 +846,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:05.061Z",
"updated_at": "2024-10-18T10:46:05.065Z",
"first_seen_at": "2024-10-18T10:46:05.061Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-northeast-1-112233445566",
"delta": "new",
"status": "FAIL",
@@ -886,6 +902,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:05.080Z",
"updated_at": "2024-10-18T10:46:05.085Z",
"first_seen_at": "2024-10-18T10:46:05.080Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-southeast-2-112233445566",
"delta": "new",
"status": "FAIL",
@@ -941,6 +958,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:05.099Z",
"updated_at": "2024-10-18T10:46:05.104Z",
"first_seen_at": "2024-10-18T10:46:05.099Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-northeast-2-112233445566",
"delta": "new",
"status": "FAIL",
@@ -996,6 +1014,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T10:46:05.115Z",
"updated_at": "2024-10-18T10:46:05.121Z",
"first_seen_at": "2024-10-18T10:46:05.115Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-northeast-3-112233445566",
"delta": "new",
"status": "FAIL",
@@ -1051,6 +1070,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.489Z",
"updated_at": "2024-10-18T11:16:24.506Z",
"first_seen_at": "2024-10-18T10:46:04.823Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-south-2-112233445566",
"delta": null,
"status": "FAIL",
@@ -1106,6 +1126,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.518Z",
"updated_at": "2024-10-18T11:16:24.521Z",
"first_seen_at": "2024-10-18T10:46:04.855Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-west-3-112233445566",
"delta": null,
"status": "FAIL",
@@ -1161,6 +1182,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.526Z",
"updated_at": "2024-10-18T11:16:24.529Z",
"first_seen_at": "2024-10-18T10:46:04.869Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-central-2-112233445566",
"delta": null,
"status": "FAIL",
@@ -1216,6 +1238,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.535Z",
"updated_at": "2024-10-18T11:16:24.538Z",
"first_seen_at": "2024-10-18T10:46:04.888Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-west-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1271,6 +1294,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.544Z",
"updated_at": "2024-10-18T11:16:24.546Z",
"first_seen_at": "2024-10-18T10:46:04.901Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-us-east-2-112233445566",
"delta": null,
"status": "FAIL",
@@ -1326,6 +1350,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.551Z",
"updated_at": "2024-10-18T11:16:24.554Z",
"first_seen_at": "2024-10-18T10:46:04.915Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-south-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1381,6 +1406,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.560Z",
"updated_at": "2024-10-18T11:16:24.562Z",
"first_seen_at": "2024-10-18T10:46:04.929Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-us-west-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1436,6 +1462,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.567Z",
"updated_at": "2024-10-18T11:16:24.569Z",
"first_seen_at": "2024-10-18T10:46:04.944Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ca-central-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1491,6 +1518,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.573Z",
"updated_at": "2024-10-18T11:16:24.575Z",
"first_seen_at": "2024-10-18T10:46:04.957Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-us-east-1-ConsoleAnalyzer-83b66ad7-d024-454e-b851-52d11cc1cf7c",
"delta": null,
"status": "PASS",
@@ -1546,6 +1574,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.580Z",
"updated_at": "2024-10-18T11:16:24.582Z",
"first_seen_at": "2024-10-18T10:46:04.971Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-west-2-112233445566",
"delta": null,
"status": "FAIL",
@@ -1601,6 +1630,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.587Z",
"updated_at": "2024-10-18T11:16:24.589Z",
"first_seen_at": "2024-10-18T10:46:04.984Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-sa-east-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1656,6 +1686,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.595Z",
"updated_at": "2024-10-18T11:16:24.597Z",
"first_seen_at": "2024-10-18T10:46:04.999Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-north-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1711,6 +1742,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.602Z",
"updated_at": "2024-10-18T11:16:24.604Z",
"first_seen_at": "2024-10-18T10:46:05.013Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-us-west-2-112233445566",
"delta": null,
"status": "FAIL",
@@ -1766,6 +1798,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.610Z",
"updated_at": "2024-10-18T11:16:24.612Z",
"first_seen_at": "2024-10-18T10:46:05.029Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-southeast-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1821,6 +1854,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.617Z",
"updated_at": "2024-10-18T11:16:24.620Z",
"first_seen_at": "2024-10-18T10:46:05.045Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-eu-central-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1876,6 +1910,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.625Z",
"updated_at": "2024-10-18T11:16:24.627Z",
"first_seen_at": "2024-10-18T10:46:05.061Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-northeast-1-112233445566",
"delta": null,
"status": "FAIL",
@@ -1931,6 +1966,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.632Z",
"updated_at": "2024-10-18T11:16:24.634Z",
"first_seen_at": "2024-10-18T10:46:05.080Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-southeast-2-112233445566",
"delta": null,
"status": "FAIL",
@@ -1986,6 +2022,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.639Z",
"updated_at": "2024-10-18T11:16:24.642Z",
"first_seen_at": "2024-10-18T10:46:05.099Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-northeast-2-112233445566",
"delta": null,
"status": "FAIL",
@@ -2041,6 +2078,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:24.646Z",
"updated_at": "2024-10-18T11:16:24.648Z",
"first_seen_at": "2024-10-18T10:46:05.115Z",
"uid": "prowler-aws-accessanalyzer_enabled-112233445566-ap-northeast-3-112233445566",
"delta": null,
"status": "FAIL",
@@ -2096,6 +2134,7 @@
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"inserted_at": "2024-10-18T11:16:26.033Z",
"updated_at": "2024-10-18T11:16:26.045Z",
"first_seen_at": "2024-10-18T11:16:26.033Z",
"uid": "prowler-aws-account_security_contact_information_is_registered-112233445566-us-east-1-112233445566",
"delta": "new",
"status": "MANUAL",

View File

@@ -58,5 +58,96 @@
"provider_group": "525e91e7-f3f3-4254-bbc3-27ce1ade86b1",
"inserted_at": "2024-11-13T11:55:41.237Z"
}
},
{
"model": "api.role",
"pk": "3f01e759-bdf9-4a99-8888-1ab805b79f93",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"name": "admin_test",
"manage_users": true,
"manage_account": true,
"manage_billing": true,
"manage_providers": true,
"manage_integrations": true,
"manage_scans": true,
"unlimited_visibility": true,
"inserted_at": "2024-11-20T15:32:42.402Z",
"updated_at": "2024-11-20T15:32:42.402Z"
}
},
{
"model": "api.role",
"pk": "845ff03a-87ef-42ba-9786-6577c70c4df0",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"name": "first_role",
"manage_users": true,
"manage_account": true,
"manage_billing": true,
"manage_providers": true,
"manage_integrations": false,
"manage_scans": false,
"unlimited_visibility": true,
"inserted_at": "2024-11-20T15:31:53.239Z",
"updated_at": "2024-11-20T15:31:53.239Z"
}
},
{
"model": "api.role",
"pk": "902d726c-4bd5-413a-a2a4-f7b4754b6b20",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"name": "third_role",
"manage_users": false,
"manage_account": false,
"manage_billing": false,
"manage_providers": false,
"manage_integrations": false,
"manage_scans": true,
"unlimited_visibility": false,
"inserted_at": "2024-11-20T15:34:05.440Z",
"updated_at": "2024-11-20T15:34:05.440Z"
}
},
{
"model": "api.roleprovidergrouprelationship",
"pk": "57fd024a-0a7f-49b4-a092-fa0979a07aaf",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"role": "3f01e759-bdf9-4a99-8888-1ab805b79f93",
"provider_group": "3fe28fb8-e545-424c-9b8f-69aff638f430",
"inserted_at": "2024-11-20T15:32:42.402Z"
}
},
{
"model": "api.roleprovidergrouprelationship",
"pk": "a3cd0099-1c13-4df1-a5e5-ecdfec561b35",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"role": "3f01e759-bdf9-4a99-8888-1ab805b79f93",
"provider_group": "481769f5-db2b-447b-8b00-1dee18db90ec",
"inserted_at": "2024-11-20T15:32:42.402Z"
}
},
{
"model": "api.roleprovidergrouprelationship",
"pk": "cfd84182-a058-40c2-af3c-0189b174940f",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"role": "3f01e759-bdf9-4a99-8888-1ab805b79f93",
"provider_group": "525e91e7-f3f3-4254-bbc3-27ce1ade86b1",
"inserted_at": "2024-11-20T15:32:42.402Z"
}
},
{
"model": "api.userrolerelationship",
"pk": "92339663-e954-4fd8-98fb-8bfe15949975",
"fields": {
"tenant": "12646005-9067-4d2a-a098-8bb378604362",
"role": "3f01e759-bdf9-4a99-8888-1ab805b79f93",
"user": "8b38e2eb-6689-4f1e-a4ba-95b275130200",
"inserted_at": "2024-11-20T15:36:14.302Z"
}
}
]

View File

@@ -0,0 +1,80 @@
from django.contrib.sites.models import Site
from django.core.management.base import BaseCommand
from django.db import DEFAULT_DB_ALIAS, connection, connections, transaction
from django.db.migrations.recorder import MigrationRecorder
def table_exists(table_name):
with connection.cursor() as cursor:
cursor.execute(
"""
SELECT EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_name = %s
)
""",
[table_name],
)
return cursor.fetchone()[0]
class Command(BaseCommand):
help = "Fix migration inconsistency between socialaccount and sites"
def add_arguments(self, parser):
parser.add_argument(
"--database",
default=DEFAULT_DB_ALIAS,
help="Specifies the database to operate on.",
)
def handle(self, *args, **options):
db = options["database"]
connection = connections[db]
recorder = MigrationRecorder(connection)
applied = set(recorder.applied_migrations())
has_social = ("socialaccount", "0001_initial") in applied
with connection.cursor() as cursor:
cursor.execute(
"""
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_name = 'django_site'
);
"""
)
site_table_exists = cursor.fetchone()[0]
if has_social and not site_table_exists:
self.stdout.write(
f"Detected inconsistency in '{db}'. Creating 'django_site' table manually..."
)
with transaction.atomic(using=db):
with connection.schema_editor() as schema_editor:
schema_editor.create_model(Site)
recorder.record_applied("sites", "0001_initial")
recorder.record_applied("sites", "0002_alter_domain_unique")
self.stdout.write(
"Fixed: 'django_site' table created and migrations registered."
)
# Ensure the relationship table also exists
if not table_exists("socialaccount_socialapp_sites"):
self.stdout.write(
"Detected missing 'socialaccount_socialapp_sites' table. Creating manually..."
)
with connection.schema_editor() as schema_editor:
from allauth.socialaccount.models import SocialApp
schema_editor.create_model(
SocialApp._meta.get_field("sites").remote_field.through
)
self.stdout.write(
"Fixed: 'socialaccount_socialapp_sites' table created."
)

View File

@@ -0,0 +1,285 @@
import random
from datetime import datetime, timezone
from math import ceil
from uuid import uuid4
from django.core.management.base import BaseCommand
from tqdm import tqdm
from api.db_utils import rls_transaction
from api.models import (
Finding,
Provider,
Resource,
ResourceFindingMapping,
ResourceScanSummary,
Scan,
StatusChoices,
)
from prowler.lib.check.models import CheckMetadata
class Command(BaseCommand):
help = "Populates the database with test data for performance testing."
def add_arguments(self, parser):
parser.add_argument(
"--tenant",
type=str,
required=True,
help="Tenant id for which the data will be populated.",
)
parser.add_argument(
"--resources",
type=int,
required=True,
help="The number of resources to create.",
)
parser.add_argument(
"--findings",
type=int,
required=True,
help="The number of findings to create.",
)
parser.add_argument(
"--batch", type=int, required=True, help="The batch size for bulk creation."
)
parser.add_argument(
"--alias",
type=str,
required=False,
help="Optional alias for the provider and scan",
)
def handle(self, *args, **options):
tenant_id = options["tenant"]
num_resources = options["resources"]
num_findings = options["findings"]
batch_size = options["batch"]
alias = options["alias"] or "Testing"
uid_token = str(uuid4())
self.stdout.write(self.style.NOTICE("Starting data population"))
self.stdout.write(self.style.NOTICE(f"\tTenant: {tenant_id}"))
self.stdout.write(self.style.NOTICE(f"\tAlias: {alias}"))
self.stdout.write(self.style.NOTICE(f"\tResources: {num_resources}"))
self.stdout.write(self.style.NOTICE(f"\tFindings: {num_findings}"))
self.stdout.write(self.style.NOTICE(f"\tBatch size: {batch_size}\n\n"))
# Resource metadata
possible_regions = [
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2",
"ca-central-1",
"eu-central-1",
"eu-west-1",
"eu-west-2",
"eu-west-3",
"ap-southeast-1",
"ap-southeast-2",
"ap-northeast-1",
"ap-northeast-2",
"ap-south-1",
"sa-east-1",
]
possible_services = []
possible_types = []
bulk_check_metadata = CheckMetadata.get_bulk(provider="aws")
for check_metadata in bulk_check_metadata.values():
if check_metadata.ServiceName not in possible_services:
possible_services.append(check_metadata.ServiceName)
if (
check_metadata.ResourceType
and check_metadata.ResourceType not in possible_types
):
possible_types.append(check_metadata.ResourceType)
with rls_transaction(tenant_id):
provider, _ = Provider.all_objects.get_or_create(
tenant_id=tenant_id,
provider="aws",
connected=True,
uid=str(random.randint(100000000000, 999999999999)),
defaults={
"alias": alias,
},
)
with rls_transaction(tenant_id):
scan = Scan.all_objects.create(
tenant_id=tenant_id,
provider=provider,
name=alias,
trigger="manual",
state="executing",
progress=0,
started_at=datetime.now(timezone.utc),
)
scan_state = "completed"
try:
# Create resources
resources = []
for i in range(num_resources):
resources.append(
Resource(
tenant_id=tenant_id,
provider_id=provider.id,
uid=f"testing-{uid_token}-{i}",
name=f"Testing {uid_token}-{i}",
region=random.choice(possible_regions),
service=random.choice(possible_services),
type=random.choice(possible_types),
inserted_at="2024-10-01T00:00:00Z",
)
)
num_batches = ceil(len(resources) / batch_size)
self.stdout.write(self.style.WARNING("Creating resources..."))
for i in tqdm(range(0, len(resources), batch_size), total=num_batches):
with rls_transaction(tenant_id):
Resource.all_objects.bulk_create(resources[i : i + batch_size])
self.stdout.write(self.style.SUCCESS("Resources created successfully.\n\n"))
with rls_transaction(tenant_id):
scan.progress = 33
scan.save()
# Create Findings
findings = []
possible_deltas = ["new", "changed", None]
possible_severities = ["critical", "high", "medium", "low"]
findings_resources_mapping = []
for i in range(num_findings):
severity = random.choice(possible_severities)
check_id = random.randint(1, 1000)
assigned_resource_num = random.randint(0, len(resources) - 1)
assigned_resource = resources[assigned_resource_num]
findings_resources_mapping.append(assigned_resource_num)
findings.append(
Finding(
tenant_id=tenant_id,
scan=scan,
uid=f"testing-{uid_token}-{i}",
delta=random.choice(possible_deltas),
check_id=f"check-{check_id}",
status=random.choice(list(StatusChoices)),
severity=severity,
impact=severity,
raw_result={},
check_metadata={
"checktitle": f"Test title for check {check_id}",
"risk": f"Testing risk {uid_token}-{i}",
"provider": "aws",
"severity": severity,
"categories": ["category1", "category2", "category3"],
"description": "This is a random description that should not matter for testing purposes.",
"servicename": assigned_resource.service,
"resourcetype": assigned_resource.type,
},
resource_types=[assigned_resource.type],
resource_regions=[assigned_resource.region],
resource_services=[assigned_resource.service],
inserted_at="2024-10-01T00:00:00Z",
)
)
num_batches = ceil(len(findings) / batch_size)
self.stdout.write(self.style.WARNING("Creating findings..."))
for i in tqdm(range(0, len(findings), batch_size), total=num_batches):
with rls_transaction(tenant_id):
Finding.all_objects.bulk_create(findings[i : i + batch_size])
self.stdout.write(self.style.SUCCESS("Findings created successfully.\n\n"))
with rls_transaction(tenant_id):
scan.progress = 66
scan.save()
# Create ResourceFindingMapping
mappings = []
scan_resource_cache: set[tuple] = set()
for index, finding_instance in enumerate(findings):
resource_instance = resources[findings_resources_mapping[index]]
mappings.append(
ResourceFindingMapping(
tenant_id=tenant_id,
resource=resource_instance,
finding=finding_instance,
)
)
scan_resource_cache.add(
(
str(resource_instance.id),
resource_instance.service,
resource_instance.region,
resource_instance.type,
)
)
num_batches = ceil(len(mappings) / batch_size)
self.stdout.write(
self.style.WARNING("Creating resource-finding mappings...")
)
for i in tqdm(range(0, len(mappings), batch_size), total=num_batches):
with rls_transaction(tenant_id):
ResourceFindingMapping.objects.bulk_create(
mappings[i : i + batch_size]
)
self.stdout.write(
self.style.SUCCESS(
"Resource-finding mappings created successfully.\n\n"
)
)
with rls_transaction(tenant_id):
scan.progress = 99
scan.save()
self.stdout.write(self.style.WARNING("Creating finding filter values..."))
resource_scan_summaries = [
ResourceScanSummary(
tenant_id=tenant_id,
scan_id=str(scan.id),
resource_id=resource_id,
service=service,
region=region,
resource_type=resource_type,
)
for resource_id, service, region, resource_type in scan_resource_cache
]
num_batches = ceil(len(resource_scan_summaries) / batch_size)
with rls_transaction(tenant_id):
for i in tqdm(
range(0, len(resource_scan_summaries), batch_size),
total=num_batches,
):
with rls_transaction(tenant_id):
ResourceScanSummary.objects.bulk_create(
resource_scan_summaries[i : i + batch_size],
ignore_conflicts=True,
)
self.stdout.write(
self.style.SUCCESS("Finding filter values created successfully.\n\n")
)
except Exception as e:
self.stdout.write(self.style.ERROR(f"Failed to populate test data: {e}"))
scan_state = "failed"
finally:
scan.completed_at = datetime.now(timezone.utc)
scan.duration = int(
(datetime.now(timezone.utc) - scan.started_at).total_seconds()
)
scan.progress = 100
scan.state = scan_state
scan.unique_resource_count = num_resources
with rls_transaction(tenant_id):
scan.save()
self.stdout.write(self.style.NOTICE("Successfully populated test data."))

View File

@@ -0,0 +1,23 @@
# Generated by Django 5.1.1 on 2024-12-20 13:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0002_token_migrations"),
]
operations = [
migrations.RemoveConstraint(
model_name="provider",
name="unique_provider_uids",
),
migrations.AddConstraint(
model_name="provider",
constraint=models.UniqueConstraint(
fields=("tenant_id", "provider", "uid", "is_deleted"),
name="unique_provider_uids",
),
),
]

View File

@@ -0,0 +1,248 @@
# Generated by Django 5.1.1 on 2024-12-05 12:29
import uuid
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import api.rls
class Migration(migrations.Migration):
dependencies = [
("api", "0003_update_provider_unique_constraint_with_is_deleted"),
]
operations = [
migrations.CreateModel(
name="Role",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("name", models.CharField(max_length=255)),
("manage_users", models.BooleanField(default=False)),
("manage_account", models.BooleanField(default=False)),
("manage_billing", models.BooleanField(default=False)),
("manage_providers", models.BooleanField(default=False)),
("manage_integrations", models.BooleanField(default=False)),
("manage_scans", models.BooleanField(default=False)),
("unlimited_visibility", models.BooleanField(default=False)),
("inserted_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "roles",
},
),
migrations.CreateModel(
name="RoleProviderGroupRelationship",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("inserted_at", models.DateTimeField(auto_now_add=True)),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "role_provider_group_relationship",
},
),
migrations.CreateModel(
name="UserRoleRelationship",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("inserted_at", models.DateTimeField(auto_now_add=True)),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "role_user_relationship",
},
),
migrations.AddField(
model_name="roleprovidergrouprelationship",
name="provider_group",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.providergroup"
),
),
migrations.AddField(
model_name="roleprovidergrouprelationship",
name="role",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.role"
),
),
migrations.AddField(
model_name="role",
name="provider_groups",
field=models.ManyToManyField(
related_name="roles",
through="api.RoleProviderGroupRelationship",
to="api.providergroup",
),
),
migrations.AddField(
model_name="userrolerelationship",
name="role",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.role"
),
),
migrations.AddField(
model_name="userrolerelationship",
name="user",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
migrations.AddField(
model_name="role",
name="users",
field=models.ManyToManyField(
related_name="roles",
through="api.UserRoleRelationship",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddConstraint(
model_name="roleprovidergrouprelationship",
constraint=models.UniqueConstraint(
fields=("role_id", "provider_group_id"),
name="unique_role_provider_group_relationship",
),
),
migrations.AddConstraint(
model_name="roleprovidergrouprelationship",
constraint=api.rls.RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_roleprovidergrouprelationship",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
migrations.AddConstraint(
model_name="userrolerelationship",
constraint=models.UniqueConstraint(
fields=("role_id", "user_id"), name="unique_role_user_relationship"
),
),
migrations.AddConstraint(
model_name="userrolerelationship",
constraint=api.rls.RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_userrolerelationship",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
migrations.AddConstraint(
model_name="role",
constraint=models.UniqueConstraint(
fields=("tenant_id", "name"), name="unique_role_per_tenant"
),
),
migrations.AddConstraint(
model_name="role",
constraint=api.rls.RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_role",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
migrations.CreateModel(
name="InvitationRoleRelationship",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("inserted_at", models.DateTimeField(auto_now_add=True)),
(
"invitation",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.invitation"
),
),
(
"role",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.role"
),
),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "role_invitation_relationship",
},
),
migrations.AddConstraint(
model_name="invitationrolerelationship",
constraint=models.UniqueConstraint(
fields=("role_id", "invitation_id"),
name="unique_role_invitation_relationship",
),
),
migrations.AddConstraint(
model_name="invitationrolerelationship",
constraint=api.rls.RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_invitationrolerelationship",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
migrations.AddField(
model_name="role",
name="invitations",
field=models.ManyToManyField(
related_name="roles",
through="api.InvitationRoleRelationship",
to="api.invitation",
),
),
]

View File

@@ -0,0 +1,44 @@
from django.db import migrations
from api.db_router import MainRouter
def create_admin_role(apps, schema_editor):
Tenant = apps.get_model("api", "Tenant")
Role = apps.get_model("api", "Role")
User = apps.get_model("api", "User")
UserRoleRelationship = apps.get_model("api", "UserRoleRelationship")
for tenant in Tenant.objects.using(MainRouter.admin_db).all():
admin_role, _ = Role.objects.using(MainRouter.admin_db).get_or_create(
name="admin",
tenant=tenant,
defaults={
"manage_users": True,
"manage_account": True,
"manage_billing": True,
"manage_providers": True,
"manage_integrations": True,
"manage_scans": True,
"unlimited_visibility": True,
},
)
users = User.objects.using(MainRouter.admin_db).filter(
membership__tenant=tenant
)
for user in users:
UserRoleRelationship.objects.using(MainRouter.admin_db).get_or_create(
user=user,
role=admin_role,
tenant=tenant,
)
class Migration(migrations.Migration):
dependencies = [
("api", "0004_rbac"),
]
operations = [
migrations.RunPython(create_admin_role),
]

View File

@@ -0,0 +1,15 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0005_rbac_missing_admin_roles"),
]
operations = [
migrations.AddField(
model_name="finding",
name="first_seen_at",
field=models.DateTimeField(editable=False, null=True),
),
]

View File

@@ -0,0 +1,25 @@
# Generated by Django 5.1.5 on 2025-01-28 15:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0006_findings_first_seen"),
]
operations = [
migrations.AddIndex(
model_name="scan",
index=models.Index(
fields=["tenant_id", "provider_id", "state", "inserted_at"],
name="scans_prov_state_insert_idx",
),
),
migrations.AddIndex(
model_name="scansummary",
index=models.Index(
fields=["tenant_id", "scan_id"], name="scan_summaries_tenant_scan_idx"
),
),
]

View File

@@ -0,0 +1,64 @@
import json
from datetime import datetime, timedelta, timezone
import django.db.models.deletion
from django.db import migrations, models
from django_celery_beat.models import PeriodicTask
from api.db_utils import rls_transaction
from api.models import Scan, StateChoices
def migrate_daily_scheduled_scan_tasks(apps, schema_editor):
for daily_scheduled_scan_task in PeriodicTask.objects.filter(
task="scan-perform-scheduled"
):
task_kwargs = json.loads(daily_scheduled_scan_task.kwargs)
tenant_id = task_kwargs["tenant_id"]
provider_id = task_kwargs["provider_id"]
current_time = datetime.now(timezone.utc)
scheduled_time_today = datetime.combine(
current_time.date(),
daily_scheduled_scan_task.start_time.time(),
tzinfo=timezone.utc,
)
if current_time < scheduled_time_today:
next_scan_date = scheduled_time_today
else:
next_scan_date = scheduled_time_today + timedelta(days=1)
with rls_transaction(tenant_id):
Scan.objects.create(
tenant_id=tenant_id,
name="Daily scheduled scan",
provider_id=provider_id,
trigger=Scan.TriggerChoices.SCHEDULED,
state=StateChoices.SCHEDULED,
scheduled_at=next_scan_date,
scheduler_task_id=daily_scheduled_scan_task.id,
)
class Migration(migrations.Migration):
atomic = False
dependencies = [
("api", "0007_scan_and_scan_summaries_indexes"),
("django_celery_beat", "0019_alter_periodictasks_options"),
]
operations = [
migrations.AddField(
model_name="scan",
name="scheduler_task",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="django_celery_beat.periodictask",
),
),
migrations.RunPython(migrate_daily_scheduled_scan_tasks),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 5.1.5 on 2025-02-07 09:42
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0008_daily_scheduled_tasks_update"),
]
operations = [
migrations.AlterField(
model_name="provider",
name="uid",
field=models.CharField(
max_length=250,
validators=[django.core.validators.MinLengthValidator(3)],
verbose_name="Unique identifier for the provider, set by the provider",
),
),
]

View File

@@ -0,0 +1,109 @@
from functools import partial
from django.db import connection, migrations
def create_index_on_partitions(
apps, schema_editor, parent_table: str, index_name: str, index_details: str
):
with connection.cursor() as cursor:
cursor.execute(
"""
SELECT inhrelid::regclass::text
FROM pg_inherits
WHERE inhparent = %s::regclass;
""",
[parent_table],
)
partitions = [row[0] for row in cursor.fetchall()]
# Iterate over partitions and create index concurrently.
# Note: PostgreSQL does not allow CONCURRENTLY inside a transaction,
# so we need atomic = False for this migration.
for partition in partitions:
sql = (
f"CREATE INDEX CONCURRENTLY IF NOT EXISTS {partition.replace('.', '_')}_{index_name} ON {partition} "
f"{index_details};"
)
schema_editor.execute(sql)
def drop_index_on_partitions(apps, schema_editor, parent_table: str, index_name: str):
with schema_editor.connection.cursor() as cursor:
cursor.execute(
"""
SELECT inhrelid::regclass::text
FROM pg_inherits
WHERE inhparent = %s::regclass;
""",
[parent_table],
)
partitions = [row[0] for row in cursor.fetchall()]
# Iterate over partitions and drop index concurrently.
for partition in partitions:
partition_index = f"{partition.replace('.', '_')}_{index_name}"
sql = f"DROP INDEX CONCURRENTLY IF EXISTS {partition_index};"
schema_editor.execute(sql)
class Migration(migrations.Migration):
atomic = False
dependencies = [
("api", "0009_increase_provider_uid_maximum_length"),
]
operations = [
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="findings_tenant_and_id_idx",
index_details="(tenant_id, id)",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="findings_tenant_and_id_idx",
),
),
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="find_tenant_scan_idx",
index_details="(tenant_id, scan_id)",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="find_tenant_scan_idx",
),
),
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="find_tenant_scan_id_idx",
index_details="(tenant_id, scan_id, id)",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="find_tenant_scan_id_idx",
),
),
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="find_delta_new_idx",
index_details="(tenant_id, id) where delta = 'new'",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="find_delta_new_idx",
),
),
]

View File

@@ -0,0 +1,49 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0010_findings_performance_indexes_partitions"),
]
operations = [
migrations.AddIndex(
model_name="finding",
index=models.Index(
fields=["tenant_id", "id"], name="findings_tenant_and_id_idx"
),
),
migrations.AddIndex(
model_name="finding",
index=models.Index(
fields=["tenant_id", "scan_id"], name="find_tenant_scan_idx"
),
),
migrations.AddIndex(
model_name="finding",
index=models.Index(
fields=["tenant_id", "scan_id", "id"], name="find_tenant_scan_id_idx"
),
),
migrations.AddIndex(
model_name="finding",
index=models.Index(
condition=models.Q(("delta", "new")),
fields=["tenant_id", "id"],
name="find_delta_new_idx",
),
),
migrations.AddIndex(
model_name="resourcetagmapping",
index=models.Index(
fields=["tenant_id", "resource_id"], name="resource_tag_tenant_idx"
),
),
migrations.AddIndex(
model_name="resource",
index=models.Index(
fields=["tenant_id", "service", "region", "type"],
name="resource_tenant_metadata_idx",
),
),
]

View File

@@ -0,0 +1,15 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0011_findings_performance_indexes_parent"),
]
operations = [
migrations.AddField(
model_name="scan",
name="output_location",
field=models.CharField(blank=True, max_length=200, null=True),
),
]

View File

@@ -0,0 +1,35 @@
# Generated by Django 5.1.5 on 2025-03-03 15:46
from functools import partial
from django.db import migrations
from api.db_utils import IntegrationTypeEnum, PostgresEnumMigration, register_enum
from api.models import Integration
IntegrationTypeEnumMigration = PostgresEnumMigration(
enum_name="integration_type",
enum_values=tuple(
integration_type[0]
for integration_type in Integration.IntegrationChoices.choices
),
)
class Migration(migrations.Migration):
atomic = False
dependencies = [
("api", "0012_scan_report_output"),
]
operations = [
migrations.RunPython(
IntegrationTypeEnumMigration.create_enum_type,
reverse_code=IntegrationTypeEnumMigration.drop_enum_type,
),
migrations.RunPython(
partial(register_enum, enum_class=IntegrationTypeEnum),
reverse_code=migrations.RunPython.noop,
),
]

View File

@@ -0,0 +1,131 @@
# Generated by Django 5.1.5 on 2025-03-03 15:46
import uuid
import django.db.models.deletion
from django.db import migrations, models
import api.db_utils
import api.rls
from api.rls import RowLevelSecurityConstraint
class Migration(migrations.Migration):
dependencies = [
("api", "0013_integrations_enum"),
]
operations = [
migrations.CreateModel(
name="Integration",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("inserted_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
("enabled", models.BooleanField(default=False)),
("connected", models.BooleanField(blank=True, null=True)),
(
"connection_last_checked_at",
models.DateTimeField(blank=True, null=True),
),
(
"integration_type",
api.db_utils.IntegrationTypeEnumField(
choices=[
("amazon_s3", "Amazon S3"),
("saml", "SAML"),
("aws_security_hub", "AWS Security Hub"),
("jira", "JIRA"),
("slack", "Slack"),
]
),
),
("configuration", models.JSONField(default=dict)),
("_credentials", models.BinaryField(db_column="credentials")),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={"db_table": "integrations", "abstract": False},
),
migrations.AddConstraint(
model_name="integration",
constraint=RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_integration",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
migrations.CreateModel(
name="IntegrationProviderRelationship",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("inserted_at", models.DateTimeField(auto_now_add=True)),
(
"integration",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="api.integration",
),
),
(
"provider",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.provider"
),
),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "integration_provider_mappings",
"constraints": [
models.UniqueConstraint(
fields=("integration_id", "provider_id"),
name="unique_integration_provider_rel",
),
],
},
),
migrations.AddConstraint(
model_name="IntegrationProviderRelationship",
constraint=RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_integrationproviderrelationship",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
migrations.AddField(
model_name="integration",
name="providers",
field=models.ManyToManyField(
blank=True,
related_name="integrations",
through="api.IntegrationProviderRelationship",
to="api.provider",
),
),
]

View File

@@ -0,0 +1,26 @@
# Generated by Django 5.1.5 on 2025-03-25 11:29
from django.db import migrations, models
import api.db_utils
class Migration(migrations.Migration):
dependencies = [
("api", "0014_integrations"),
]
operations = [
migrations.AddField(
model_name="finding",
name="muted",
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name="finding",
name="status",
field=api.db_utils.StatusEnumField(
choices=[("FAIL", "Fail"), ("PASS", "Pass"), ("MANUAL", "Manual")]
),
),
]

View File

@@ -0,0 +1,32 @@
# Generated by Django 5.1.5 on 2025-03-31 10:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0015_finding_muted"),
]
operations = [
migrations.AddField(
model_name="finding",
name="compliance",
field=models.JSONField(blank=True, default=dict, null=True),
),
migrations.AddField(
model_name="resource",
name="details",
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name="resource",
name="metadata",
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name="resource",
name="partition",
field=models.TextField(blank=True, null=True),
),
]

View File

@@ -0,0 +1,32 @@
# Generated by Django 5.1.7 on 2025-04-16 08:47
from django.db import migrations
import api.db_utils
class Migration(migrations.Migration):
dependencies = [
("api", "0016_finding_compliance_resource_details_and_more"),
]
operations = [
migrations.AlterField(
model_name="provider",
name="provider",
field=api.db_utils.ProviderEnumField(
choices=[
("aws", "AWS"),
("azure", "Azure"),
("gcp", "GCP"),
("kubernetes", "Kubernetes"),
("m365", "M365"),
],
default="aws",
),
),
migrations.RunSQL(
"ALTER TYPE provider ADD VALUE IF NOT EXISTS 'm365';",
reverse_sql=migrations.RunSQL.noop,
),
]

View File

@@ -0,0 +1,81 @@
# Generated by Django 5.1.7 on 2025-05-05 10:01
import uuid
import django.db.models.deletion
import uuid6
from django.db import migrations, models
import api.rls
class Migration(migrations.Migration):
dependencies = [
("api", "0017_m365_provider"),
]
operations = [
migrations.CreateModel(
name="ResourceScanSummary",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("scan_id", models.UUIDField(db_index=True, default=uuid6.uuid7)),
("resource_id", models.UUIDField(db_index=True, default=uuid.uuid4)),
("service", models.CharField(max_length=100)),
("region", models.CharField(max_length=100)),
("resource_type", models.CharField(max_length=100)),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "resource_scan_summaries",
"indexes": [
models.Index(
fields=["tenant_id", "scan_id", "service"],
name="rss_tenant_scan_svc_idx",
),
models.Index(
fields=["tenant_id", "scan_id", "region"],
name="rss_tenant_scan_reg_idx",
),
models.Index(
fields=["tenant_id", "scan_id", "resource_type"],
name="rss_tenant_scan_type_idx",
),
models.Index(
fields=["tenant_id", "scan_id", "region", "service"],
name="rss_tenant_scan_reg_svc_idx",
),
models.Index(
fields=["tenant_id", "scan_id", "service", "resource_type"],
name="rss_tenant_scan_svc_type_idx",
),
models.Index(
fields=["tenant_id", "scan_id", "region", "resource_type"],
name="rss_tenant_scan_reg_type_idx",
),
],
"unique_together": {("tenant_id", "scan_id", "resource_id")},
},
),
migrations.AddConstraint(
model_name="resourcescansummary",
constraint=api.rls.RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_resourcescansummary",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
]

View File

@@ -0,0 +1,42 @@
import django.contrib.postgres.fields
import django.contrib.postgres.indexes
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0018_resource_scan_summaries"),
]
operations = [
migrations.AddField(
model_name="finding",
name="resource_regions",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(max_length=100),
blank=True,
null=True,
size=None,
),
),
migrations.AddField(
model_name="finding",
name="resource_services",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(max_length=100),
blank=True,
null=True,
size=None,
),
),
migrations.AddField(
model_name="finding",
name="resource_types",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.CharField(max_length=100),
blank=True,
null=True,
size=None,
),
),
]

View File

@@ -0,0 +1,86 @@
from functools import partial
from django.db import migrations
from api.db_utils import create_index_on_partitions, drop_index_on_partitions
class Migration(migrations.Migration):
atomic = False
dependencies = [
("api", "0019_finding_denormalize_resource_fields"),
]
operations = [
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="gin_find_service_idx",
columns="resource_services",
method="GIN",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="gin_find_service_idx",
),
),
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="gin_find_region_idx",
columns="resource_regions",
method="GIN",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="gin_find_region_idx",
),
),
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="gin_find_rtype_idx",
columns="resource_types",
method="GIN",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="gin_find_rtype_idx",
),
),
migrations.RunPython(
partial(
drop_index_on_partitions,
parent_table="findings",
index_name="findings_uid_idx",
),
reverse_code=partial(
create_index_on_partitions,
parent_table="findings",
index_name="findings_uid_idx",
columns="uid",
method="BTREE",
),
),
migrations.RunPython(
partial(
drop_index_on_partitions,
parent_table="findings",
index_name="findings_filter_idx",
),
reverse_code=partial(
create_index_on_partitions,
parent_table="findings",
index_name="findings_filter_idx",
columns="scan_id, impact, severity, status, check_id, delta",
method="BTREE",
),
),
]

View File

@@ -0,0 +1,37 @@
import django.contrib.postgres.indexes
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("api", "0020_findings_new_performance_indexes_partitions"),
]
operations = [
migrations.AddIndex(
model_name="finding",
index=django.contrib.postgres.indexes.GinIndex(
fields=["resource_services"], name="gin_find_service_idx"
),
),
migrations.AddIndex(
model_name="finding",
index=django.contrib.postgres.indexes.GinIndex(
fields=["resource_regions"], name="gin_find_region_idx"
),
),
migrations.AddIndex(
model_name="finding",
index=django.contrib.postgres.indexes.GinIndex(
fields=["resource_types"], name="gin_find_rtype_idx"
),
),
migrations.RemoveIndex(
model_name="finding",
name="findings_uid_idx",
),
migrations.RemoveIndex(
model_name="finding",
name="findings_filter_idx",
),
]

View File

@@ -0,0 +1,38 @@
# Generated by Django 5.1.8 on 2025-05-12 10:04
from django.contrib.postgres.operations import AddIndexConcurrently
from django.db import migrations, models
class Migration(migrations.Migration):
atomic = False
dependencies = [
("api", "0021_findings_new_performance_indexes_parent"),
("django_celery_beat", "0019_alter_periodictasks_options"),
]
operations = [
AddIndexConcurrently(
model_name="scan",
index=models.Index(
condition=models.Q(("state", "completed")),
fields=["tenant_id", "provider_id", "state", "-inserted_at"],
name="scans_prov_state_ins_desc_idx",
),
),
AddIndexConcurrently(
model_name="scansummary",
index=models.Index(
fields=["tenant_id", "scan_id", "service"],
name="ss_tenant_scan_service_idx",
),
),
AddIndexConcurrently(
model_name="scansummary",
index=models.Index(
fields=["tenant_id", "scan_id", "severity"],
name="ss_tenant_scan_severity_idx",
),
),
]

View File

@@ -0,0 +1,28 @@
# Generated by Django 5.1.8 on 2025-05-12 10:18
from django.contrib.postgres.operations import AddIndexConcurrently
from django.db import migrations, models
class Migration(migrations.Migration):
atomic = False
dependencies = [
("api", "0022_scan_summaries_performance_indexes"),
]
operations = [
AddIndexConcurrently(
model_name="resource",
index=models.Index(
fields=["tenant_id", "id"], name="resources_tenant_id_idx"
),
),
AddIndexConcurrently(
model_name="resource",
index=models.Index(
fields=["tenant_id", "provider_id"],
name="resources_tenant_provider_idx",
),
),
]

View File

@@ -0,0 +1,29 @@
from functools import partial
from django.db import migrations
from api.db_utils import create_index_on_partitions, drop_index_on_partitions
class Migration(migrations.Migration):
atomic = False
dependencies = [
("api", "0023_resources_lookup_optimization"),
]
operations = [
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="find_tenant_uid_inserted_idx",
columns="tenant_id, uid, inserted_at DESC",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="find_tenant_uid_inserted_idx",
),
)
]

View File

@@ -0,0 +1,17 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0024_findings_uid_index_partitions"),
]
operations = [
migrations.AddIndex(
model_name="finding",
index=models.Index(
fields=["tenant_id", "uid", "-inserted_at"],
name="find_tenant_uid_inserted_idx",
),
),
]

View File

@@ -0,0 +1,14 @@
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("api", "0025_findings_uid_index_parent"),
]
operations = [
migrations.RunSQL(
"ALTER TYPE provider_secret_type ADD VALUE IF NOT EXISTS 'service_account';",
reverse_sql=migrations.RunSQL.noop,
),
]

View File

@@ -0,0 +1,124 @@
# Generated by Django 5.1.8 on 2025-05-21 11:37
import uuid
import django.db.models.deletion
from django.db import migrations, models
import api.db_utils
import api.rls
from api.rls import RowLevelSecurityConstraint
class Migration(migrations.Migration):
dependencies = [
("api", "0026_provider_secret_gcp_service_account"),
]
operations = [
migrations.CreateModel(
name="ComplianceRequirementOverview",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("inserted_at", models.DateTimeField(auto_now_add=True)),
("compliance_id", models.TextField(blank=False)),
("framework", models.TextField(blank=False)),
("version", models.TextField(blank=True)),
("description", models.TextField(blank=True)),
("region", models.TextField(blank=False)),
("requirement_id", models.TextField(blank=False)),
(
"requirement_status",
api.db_utils.StatusEnumField(
choices=[
("FAIL", "Fail"),
("PASS", "Pass"),
("MANUAL", "Manual"),
]
),
),
("passed_checks", models.IntegerField(default=0)),
("failed_checks", models.IntegerField(default=0)),
("total_checks", models.IntegerField(default=0)),
(
"scan",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="compliance_requirements_overviews",
related_query_name="compliance_requirements_overview",
to="api.scan",
),
),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "compliance_requirements_overviews",
"abstract": False,
"indexes": [
models.Index(
fields=["tenant_id", "scan_id"], name="cro_tenant_scan_idx"
),
models.Index(
fields=["tenant_id", "scan_id", "compliance_id"],
name="cro_scan_comp_idx",
),
models.Index(
fields=["tenant_id", "scan_id", "compliance_id", "region"],
name="cro_scan_comp_reg_idx",
),
models.Index(
fields=[
"tenant_id",
"scan_id",
"compliance_id",
"requirement_id",
],
name="cro_scan_comp_req_idx",
),
models.Index(
fields=[
"tenant_id",
"scan_id",
"compliance_id",
"requirement_id",
"region",
],
name="cro_scan_comp_req_reg_idx",
),
],
"constraints": [
models.UniqueConstraint(
fields=(
"tenant_id",
"scan_id",
"compliance_id",
"requirement_id",
"region",
),
name="unique_tenant_compliance_requirement_overview",
)
],
},
),
migrations.AddConstraint(
model_name="ComplianceRequirementOverview",
constraint=RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_compliancerequirementoverview",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
]

View File

@@ -0,0 +1,29 @@
from functools import partial
from django.db import migrations
from api.db_utils import create_index_on_partitions, drop_index_on_partitions
class Migration(migrations.Migration):
atomic = False
dependencies = [
("api", "0027_compliance_requirement_overviews"),
]
operations = [
migrations.RunPython(
partial(
create_index_on_partitions,
parent_table="findings",
index_name="find_tenant_scan_check_idx",
columns="tenant_id, scan_id, check_id",
),
reverse_code=partial(
drop_index_on_partitions,
parent_table="findings",
index_name="find_tenant_scan_check_idx",
),
)
]

View File

@@ -0,0 +1,17 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("api", "0028_findings_check_index_partitions"),
]
operations = [
migrations.AddIndex(
model_name="finding",
index=models.Index(
fields=["tenant_id", "scan_id", "check_id"],
name="find_tenant_scan_check_idx",
),
),
]

View File

@@ -0,0 +1,120 @@
# Generated by Django 5.1.8 on 2025-05-15 09:54
import uuid
import django.db.models.deletion
from django.db import migrations, models
import api.rls
class Migration(migrations.Migration):
dependencies = [
("api", "0029_findings_check_index_parent"),
]
operations = [
migrations.CreateModel(
name="SAMLDomainIndex",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("email_domain", models.CharField(max_length=254, unique=True)),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "saml_domain_index",
},
),
migrations.AddConstraint(
model_name="samldomainindex",
constraint=models.UniqueConstraint(
fields=("email_domain", "tenant"),
name="unique_resources_by_email_domain",
),
),
migrations.AddConstraint(
model_name="samldomainindex",
constraint=api.rls.BaseSecurityConstraint(
name="statements_on_samldomainindex",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
migrations.CreateModel(
name="SAMLConfiguration",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
"email_domain",
models.CharField(
help_text="Email domain used to identify the tenant, e.g. prowlerdemo.com",
max_length=254,
unique=True,
),
),
(
"metadata_xml",
models.TextField(
help_text="Raw IdP metadata XML to configure SingleSignOnService, certificates, etc."
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "saml_configurations",
},
),
migrations.AddConstraint(
model_name="samlconfiguration",
constraint=api.rls.RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_samlconfiguration",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
migrations.AddConstraint(
model_name="samlconfiguration",
constraint=models.UniqueConstraint(
fields=("tenant",), name="unique_samlconfig_per_tenant"
),
),
migrations.AlterField(
model_name="integration",
name="integration_type",
field=api.db_utils.IntegrationTypeEnumField(
choices=[
("amazon_s3", "Amazon S3"),
("aws_security_hub", "AWS Security Hub"),
("jira", "JIRA"),
("slack", "Slack"),
]
),
),
]

View File

@@ -0,0 +1,106 @@
# Generated by Django 5.1.10 on 2025-06-12 12:45
import uuid
import django.core.validators
import django.db.models.deletion
from django.db import migrations, models
import api.rls
class Migration(migrations.Migration):
dependencies = [
("api", "0030_samlconfigurations"),
]
operations = [
migrations.CreateModel(
name="LighthouseConfiguration",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("inserted_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"name",
models.CharField(
help_text="Name of the configuration",
max_length=100,
validators=[django.core.validators.MinLengthValidator(3)],
),
),
(
"api_key",
models.BinaryField(
help_text="Encrypted API key for the LLM service"
),
),
(
"model",
models.CharField(
choices=[
("gpt-4o-2024-11-20", "GPT-4o v2024-11-20"),
("gpt-4o-2024-08-06", "GPT-4o v2024-08-06"),
("gpt-4o-2024-05-13", "GPT-4o v2024-05-13"),
("gpt-4o", "GPT-4o Default"),
("gpt-4o-mini-2024-07-18", "GPT-4o Mini v2024-07-18"),
("gpt-4o-mini", "GPT-4o Mini Default"),
],
help_text="Must be one of the supported model names",
max_length=50,
),
),
(
"temperature",
models.FloatField(default=0, help_text="Must be between 0 and 1"),
),
(
"max_tokens",
models.IntegerField(
default=4000, help_text="Must be between 500 and 5000"
),
),
(
"business_context",
models.TextField(
blank=True,
default="",
help_text="Additional business context for this AI model configuration",
),
),
("is_active", models.BooleanField(default=True)),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="api.tenant"
),
),
],
options={
"db_table": "lighthouse_configurations",
"abstract": False,
"constraints": [
models.UniqueConstraint(
fields=("tenant_id",),
name="unique_lighthouse_config_per_tenant",
),
],
},
),
migrations.AddConstraint(
model_name="lighthouseconfiguration",
constraint=api.rls.RowLevelSecurityConstraint(
"tenant_id",
name="rls_on_lighthouseconfiguration",
statements=["SELECT", "INSERT", "UPDATE", "DELETE"],
),
),
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
from rest_framework_json_api.pagination import JsonApiPageNumberPagination
from drf_spectacular_jsonapi.schemas.pagination import JsonApiPageNumberPagination
class ComplianceOverviewPagination(JsonApiPageNumberPagination):

View File

@@ -0,0 +1,75 @@
from enum import Enum
from typing import Optional
from django.db.models import QuerySet
from rest_framework.permissions import BasePermission
from api.db_router import MainRouter
from api.models import Provider, Role, User
class Permissions(Enum):
MANAGE_USERS = "manage_users"
MANAGE_ACCOUNT = "manage_account"
MANAGE_BILLING = "manage_billing"
MANAGE_PROVIDERS = "manage_providers"
MANAGE_INTEGRATIONS = "manage_integrations"
MANAGE_SCANS = "manage_scans"
UNLIMITED_VISIBILITY = "unlimited_visibility"
class HasPermissions(BasePermission):
"""
Custom permission to check if the user's role has the required permissions.
The required permissions should be specified in the view as a list in `required_permissions`.
"""
def has_permission(self, request, view):
required_permissions = getattr(view, "required_permissions", [])
if not required_permissions:
return True
user_roles = (
User.objects.using(MainRouter.admin_db).get(id=request.user.id).roles.all()
)
if not user_roles:
return False
for perm in required_permissions:
if not getattr(user_roles[0], perm.value, False):
return False
return True
def get_role(user: User) -> Optional[Role]:
"""
Retrieve the first role assigned to the given user.
Returns:
The user's first Role instance if the user has any roles, otherwise None.
"""
return user.roles.first()
def get_providers(role: Role) -> QuerySet[Provider]:
"""
Return a distinct queryset of Providers accessible by the given role.
If the role has no associated provider groups, an empty queryset is returned.
Args:
role: A Role instance.
Returns:
A QuerySet of Provider objects filtered by the role's provider groups.
If the role has no provider groups, returns an empty queryset.
"""
tenant = role.tenant
provider_groups = role.provider_groups.all()
if not provider_groups.exists():
return Provider.objects.none()
return Provider.objects.filter(
tenant=tenant, provider_groups__in=provider_groups
).distinct()

View File

@@ -2,7 +2,7 @@ from contextlib import nullcontext
from rest_framework_json_api.renderers import JSONRenderer
from api.db_utils import tenant_transaction
from api.db_utils import rls_transaction
class APIJSONRenderer(JSONRenderer):
@@ -13,9 +13,9 @@ class APIJSONRenderer(JSONRenderer):
tenant_id = getattr(request, "tenant_id", None) if request else None
include_param_present = "include" in request.query_params if request else False
# Use tenant_transaction if needed for included resources, otherwise do nothing
# Use rls_transaction if needed for included resources, otherwise do nothing
context_manager = (
tenant_transaction(tenant_id)
rls_transaction(tenant_id)
if tenant_id and include_param_present
else nullcontext()
)

View File

@@ -2,8 +2,7 @@ from typing import Any
from uuid import uuid4
from django.core.exceptions import ValidationError
from django.db import DEFAULT_DB_ALIAS
from django.db import models
from django.db import DEFAULT_DB_ALIAS, models
from django.db.backends.ddl_references import Statement, Table
from api.db_utils import DB_USER, POSTGRES_TENANT_VAR
@@ -59,11 +58,11 @@ class RowLevelSecurityConstraint(models.BaseConstraint):
drop_sql_query = """
ALTER TABLE %(table_name)s NO FORCE ROW LEVEL SECURITY;
ALTER TABLE %(table_name)s DISABLE ROW LEVEL SECURITY;
REVOKE ALL ON TABLE %(table_name) TO %(db_user)s;
REVOKE ALL ON TABLE %(table_name)s FROM %(db_user)s;
"""
drop_policy_sql_query = """
DROP POLICY IF EXISTS %(db_user)s_%(table_name)s_{statement} on %(table_name)s;
DROP POLICY IF EXISTS %(db_user)s_%(raw_table_name)s_{statement} ON %(table_name)s;
"""
def __init__(
@@ -88,9 +87,7 @@ class RowLevelSecurityConstraint(models.BaseConstraint):
f"{grant_queries}{self.grant_sql_query.format(statement=statement)}"
)
full_create_sql_query = (
f"{self.rls_sql_query}" f"{policy_queries}" f"{grant_queries}"
)
full_create_sql_query = f"{self.rls_sql_query}{policy_queries}{grant_queries}"
table_name = model._meta.db_table
if self.partition_name:
@@ -107,16 +104,20 @@ class RowLevelSecurityConstraint(models.BaseConstraint):
def remove_sql(self, model: Any, schema_editor: Any) -> Any:
field_column = schema_editor.quote_name(self.target_field)
raw_table_name = model._meta.db_table
table_name = raw_table_name
if self.partition_name:
raw_table_name = f"{raw_table_name}_{self.partition_name}"
table_name = raw_table_name
full_drop_sql_query = (
f"{self.drop_sql_query}"
f"{''.join([self.drop_policy_sql_query.format(statement) for statement in self.statements])}"
f"{''.join([self.drop_policy_sql_query.format(statement=statement) for statement in self.statements])}"
)
table_name = model._meta.db_table
if self.partition_name:
table_name = f"{table_name}_{self.partition_name}"
return Statement(
full_drop_sql_query,
table_name=Table(table_name, schema_editor.quote_name),
raw_table_name=raw_table_name,
field_column=field_column,
db_user=DB_USER,
partition_name=self.partition_name,

View File

@@ -1,12 +1,12 @@
from celery import states
from celery.signals import before_task_publish
from config.celery import celery_app
from django.db.models.signals import post_delete
from django.dispatch import receiver
from django_celery_beat.models import PeriodicTask
from django_celery_results.backends.database import DatabaseBackend
from api.db_utils import delete_related_daily_task
from api.models import Provider
from config.celery import celery_app
def create_task_result_on_publish(sender=None, headers=None, **kwargs): # noqa: F841
@@ -31,5 +31,4 @@ before_task_publish.connect(
@receiver(post_delete, sender=Provider)
def delete_provider_scan_task(sender, instance, **kwargs): # noqa: F841
# Delete the associated periodic task when the provider is deleted
task_name = f"scan-perform-scheduled-{instance.id}"
PeriodicTask.objects.filter(name=task_name).delete()
delete_related_daily_task(instance.id)

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,11 @@
import pytest
from conftest import TEST_PASSWORD, get_api_tokens, get_authorization_header
from django.urls import reverse
from unittest.mock import patch
from rest_framework.test import APIClient
from conftest import TEST_PASSWORD, get_api_tokens, get_authorization_header
from api.models import Membership, User
@patch("api.v1.views.MainRouter.admin_db", new="default")
@pytest.mark.django_db
def test_basic_authentication():
client = APIClient()
@@ -98,3 +97,204 @@ def test_refresh_token(create_test_user, tenants_fixture):
format="vnd.api+json",
)
assert new_refresh_response.status_code == 200
@pytest.mark.django_db
def test_user_me_when_inviting_users(create_test_user, tenants_fixture, roles_fixture):
client = APIClient()
role = roles_fixture[0]
user1_email = "user1@testing.com"
user2_email = "user2@testing.com"
password = "thisisapassword123"
user1_response = client.post(
reverse("user-list"),
data={
"data": {
"type": "users",
"attributes": {
"name": "user1",
"email": user1_email,
"password": password,
},
}
},
format="vnd.api+json",
)
assert user1_response.status_code == 201
user1_access_token, _ = get_api_tokens(client, user1_email, password)
user1_headers = get_authorization_header(user1_access_token)
user2_invitation = client.post(
reverse("invitation-list"),
data={
"data": {
"type": "invitations",
"attributes": {"email": user2_email},
"relationships": {
"roles": {
"data": [
{
"type": "roles",
"id": str(role.id),
}
]
}
},
}
},
format="vnd.api+json",
headers=user1_headers,
)
assert user2_invitation.status_code == 201
invitation_token = user2_invitation.json()["data"]["attributes"]["token"]
user2_response = client.post(
reverse("user-list") + f"?invitation_token={invitation_token}",
data={
"data": {
"type": "users",
"attributes": {
"name": "user2",
"email": user2_email,
"password": password,
},
}
},
format="vnd.api+json",
)
assert user2_response.status_code == 201
user2_access_token, _ = get_api_tokens(client, user2_email, password)
user2_headers = get_authorization_header(user2_access_token)
user1_me = client.get(reverse("user-me"), headers=user1_headers)
assert user1_me.status_code == 200
assert user1_me.json()["data"]["attributes"]["email"] == user1_email
user2_me = client.get(reverse("user-me"), headers=user2_headers)
assert user2_me.status_code == 200
assert user2_me.json()["data"]["attributes"]["email"] == user2_email
@pytest.mark.django_db
class TestTokenSwitchTenant:
def test_switch_tenant_with_valid_token(self, tenants_fixture, providers_fixture):
client = APIClient()
test_user = "test_email@prowler.com"
test_password = "test_password"
# Check that we can create a new user without any kind of authentication
user_creation_response = client.post(
reverse("user-list"),
data={
"data": {
"type": "users",
"attributes": {
"name": "test",
"email": test_user,
"password": test_password,
},
}
},
format="vnd.api+json",
)
assert user_creation_response.status_code == 201
# Create a new relationship between this user and another tenant
tenant_id = tenants_fixture[0].id
user_instance = User.objects.get(email=test_user)
Membership.objects.create(user=user_instance, tenant_id=tenant_id)
# Check that using our new user's credentials we can authenticate and get the providers
access_token, _ = get_api_tokens(client, test_user, test_password)
auth_headers = get_authorization_header(access_token)
user_me_response = client.get(
reverse("user-me"),
headers=auth_headers,
)
assert user_me_response.status_code == 200
# Assert this user belongs to two tenants
assert (
user_me_response.json()["data"]["relationships"]["memberships"]["meta"][
"count"
]
== 2
)
provider_response = client.get(
reverse("provider-list"),
headers=auth_headers,
)
assert provider_response.status_code == 200
# Empty response since there are no providers in this tenant
assert not provider_response.json()["data"]
switch_tenant_response = client.post(
reverse("token-switch"),
data={
"data": {
"type": "tokens-switch-tenant",
"attributes": {"tenant_id": tenant_id},
}
},
headers=auth_headers,
)
assert switch_tenant_response.status_code == 200
new_access_token = switch_tenant_response.json()["data"]["attributes"]["access"]
new_auth_headers = get_authorization_header(new_access_token)
provider_response = client.get(
reverse("provider-list"),
headers=new_auth_headers,
)
assert provider_response.status_code == 200
# Now it must be data because we switched to another tenant with providers
assert provider_response.json()["data"]
def test_switch_tenant_with_invalid_token(self, create_test_user, tenants_fixture):
client = APIClient()
access_token, refresh_token = get_api_tokens(
client, create_test_user.email, TEST_PASSWORD
)
auth_headers = get_authorization_header(access_token)
invalid_token_response = client.post(
reverse("token-switch"),
data={
"data": {
"type": "tokens-switch-tenant",
"attributes": {"tenant_id": "invalid_tenant_id"},
}
},
headers=auth_headers,
)
assert invalid_token_response.status_code == 400
assert invalid_token_response.json()["errors"][0]["code"] == "invalid"
assert (
invalid_token_response.json()["errors"][0]["detail"]
== "Must be a valid UUID."
)
invalid_tenant_response = client.post(
reverse("token-switch"),
data={
"data": {
"type": "tokens-switch-tenant",
"attributes": {"tenant_id": tenants_fixture[-1].id},
}
},
headers=auth_headers,
)
assert invalid_tenant_response.status_code == 400
assert invalid_tenant_response.json()["errors"][0]["code"] == "invalid"
assert invalid_tenant_response.json()["errors"][0]["detail"] == (
"Tenant does not exist or user is not a " "member."
)

View File

@@ -0,0 +1,85 @@
from unittest.mock import Mock, patch
import pytest
from conftest import get_api_tokens, get_authorization_header
from django.urls import reverse
from rest_framework.test import APIClient
from api.models import Provider
@patch("api.v1.views.Task.objects.get")
@patch("api.v1.views.delete_provider_task.delay")
@pytest.mark.django_db
def test_delete_provider_without_executing_task(
mock_delete_task, mock_task_get, create_test_user, tenants_fixture, tasks_fixture
):
client = APIClient()
test_user = "test_email@prowler.com"
test_password = "test_password"
prowler_task = tasks_fixture[0]
task_mock = Mock()
task_mock.id = prowler_task.id
mock_delete_task.return_value = task_mock
mock_task_get.return_value = prowler_task
user_creation_response = client.post(
reverse("user-list"),
data={
"data": {
"type": "users",
"attributes": {
"name": "test",
"email": test_user,
"password": test_password,
},
}
},
format="vnd.api+json",
)
assert user_creation_response.status_code == 201
access_token, _ = get_api_tokens(client, test_user, test_password)
auth_headers = get_authorization_header(access_token)
create_provider_response = client.post(
reverse("provider-list"),
data={
"data": {
"type": "providers",
"attributes": {
"provider": Provider.ProviderChoices.AWS,
"uid": "123456789012",
},
}
},
format="vnd.api+json",
headers=auth_headers,
)
assert create_provider_response.status_code == 201
provider_id = create_provider_response.json()["data"]["id"]
provider_uid = create_provider_response.json()["data"]["attributes"]["uid"]
remove_provider = client.delete(
reverse("provider-detail", kwargs={"pk": provider_id}),
headers=auth_headers,
)
assert remove_provider.status_code == 202
recreate_provider_response = client.post(
reverse("provider-list"),
data={
"data": {
"type": "providers",
"attributes": {
"provider": Provider.ProviderChoices.AWS,
"uid": provider_uid,
},
}
},
format="vnd.api+json",
headers=auth_headers,
)
assert recreate_provider_response.status_code == 201

View File

@@ -13,6 +13,7 @@ def test_check_resources_between_different_tenants(
enforce_test_user_db_connection,
authenticated_api_client,
tenants_fixture,
set_user_admin_roles_fixture,
):
client = authenticated_api_client

View File

@@ -0,0 +1,82 @@
from unittest.mock import MagicMock
import pytest
from allauth.socialaccount.models import SocialLogin
from django.contrib.auth import get_user_model
from api.adapters import ProwlerSocialAccountAdapter
from api.db_router import MainRouter
from api.models import Membership, SAMLConfiguration, Tenant
User = get_user_model()
@pytest.mark.django_db
class TestProwlerSocialAccountAdapter:
def test_get_user_by_email_returns_user(self, create_test_user):
adapter = ProwlerSocialAccountAdapter()
user = adapter.get_user_by_email(create_test_user.email)
assert user == create_test_user
def test_get_user_by_email_returns_none_for_unknown_email(self):
adapter = ProwlerSocialAccountAdapter()
assert adapter.get_user_by_email("notfound@example.com") is None
def test_pre_social_login_links_existing_user(self, create_test_user, rf):
adapter = ProwlerSocialAccountAdapter()
sociallogin = MagicMock(spec=SocialLogin)
sociallogin.account = MagicMock()
sociallogin.account.provider = "saml"
sociallogin.account.extra_data = {}
sociallogin.user = create_test_user
sociallogin.connect = MagicMock()
adapter.pre_social_login(rf.get("/"), sociallogin)
call_args = sociallogin.connect.call_args
assert call_args is not None
called_request, called_user = call_args[0]
assert called_request.path == "/"
assert called_user.email == create_test_user.email
def test_pre_social_login_no_link_if_email_missing(self, rf):
adapter = ProwlerSocialAccountAdapter()
sociallogin = MagicMock(spec=SocialLogin)
sociallogin.account = MagicMock()
sociallogin.account.provider = "github"
sociallogin.account.extra_data = {}
sociallogin.connect = MagicMock()
adapter.pre_social_login(rf.get("/"), sociallogin)
sociallogin.connect.assert_not_called()
def test_save_user_saml_flow(
self,
rf,
saml_setup,
saml_sociallogin,
):
adapter = ProwlerSocialAccountAdapter()
request = rf.get("/")
saml_sociallogin.user.email = saml_setup["email"]
tenant = Tenant.objects.using(MainRouter.admin_db).get(
id=saml_setup["tenant_id"]
)
saml_config = SAMLConfiguration.objects.using(MainRouter.admin_db).get(
tenant=tenant
)
assert saml_config.email_domain == saml_setup["domain"]
user = adapter.save_user(request, saml_sociallogin)
assert user.email == saml_setup["email"]
assert (
Membership.objects.using(MainRouter.admin_db)
.filter(user=user, tenant=tenant)
.exists()
)

View File

@@ -1,12 +1,12 @@
from unittest.mock import patch, MagicMock
from unittest.mock import MagicMock, patch
from api.compliance import (
generate_compliance_overview_template,
generate_scan_compliance,
get_prowler_provider_checks,
get_prowler_provider_compliance,
load_prowler_compliance,
load_prowler_checks,
generate_scan_compliance,
generate_compliance_overview_template,
load_prowler_compliance,
)
from api.models import Provider
@@ -69,7 +69,7 @@ class TestCompliance:
load_prowler_compliance()
from api.compliance import PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE, PROWLER_CHECKS
from api.compliance import PROWLER_CHECKS, PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE
assert PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE == {
"template_key": "template_value"
@@ -218,6 +218,10 @@ class TestCompliance:
Description="Description of requirement 1",
Attributes=[],
Checks=["check1", "check2"],
Tactics=["tactic1"],
SubTechniques=["subtechnique1"],
Platforms=["platform1"],
TechniqueURL="https://example.com",
)
requirement2 = MagicMock(
Id="requirement2",
@@ -225,6 +229,10 @@ class TestCompliance:
Description="Description of requirement 2",
Attributes=[],
Checks=[],
Tactics=[],
SubTechniques=[],
Platforms=[],
TechniqueURL="",
)
compliance1 = MagicMock(
Requirements=[requirement1, requirement2],
@@ -247,6 +255,10 @@ class TestCompliance:
"requirement1": {
"name": "Requirement 1",
"description": "Description of requirement 1",
"tactics": ["tactic1"],
"subtechniques": ["subtechnique1"],
"platforms": ["platform1"],
"technique_url": "https://example.com",
"attributes": [],
"checks": {"check1": None, "check2": None},
"checks_status": {
@@ -260,6 +272,10 @@ class TestCompliance:
"requirement2": {
"name": "Requirement 2",
"description": "Description of requirement 2",
"tactics": [],
"subtechniques": [],
"platforms": [],
"technique_url": "",
"attributes": [],
"checks": {},
"checks_status": {
@@ -268,7 +284,7 @@ class TestCompliance:
"manual": 0,
"total": 0,
},
"status": "PASS",
"status": "MANUAL",
},
},
"requirements_status": {

Some files were not shown because too many files have changed in this diff Show More