Skip to content

Conversation

@HugoPBrito
Copy link
Member

Context

Large environments were experiencing extremely slow scan times of approximately for Azure KeyVault checks. The root cause was sequential processing of vaults and their contents (keys, secrets, monitor settings), compounded by Azure Management API pagination returning only 2-3 items per page.

Description

This PR introduces vault-level parallelization to the Azure KeyVault service, dramatically improving scan performance for large-scale environments.
Changes:

  1. prowler/providers/azure/lib/service/service.py
    • Added __threading_call__ method to the base AzureService class
    • Configurable MAX_WORKERS=10 thread pool for parallel processing
    • Includes timing/logging for observability
  2. prowler/providers/azure/services/keyvault/keyvault_service.py
    • Refactored _get_key_vaults() to process vaults in parallel using threading_call
    • Each vault's keys, secrets, and monitor settings are fetched concurrently via nested ThreadPoolExecutor(max_workers=3)
    • Added _process_single_keyvault() for thread-safe vault processing
    • Added detailed timing logs for performance visibility
  3. prowler/providers/azure/services/keyvault/keyvault_rbac_secret_expiration_set/keyvault_rbac_secret_expiration_set.py
    • Bug fix: Previously tried to create 1 finding per vault, but didn't happen, trying to reuse the same Check_Report_Azure object across secrets (causing incorrect status propagation) and lacking PASS findings.
    • Now correctly creates 1 finding per secret with proper resource attribution and status

Steps to review

  1. Review the base service threading implementation (service.py:30-60)
    • Verify __threading_call__ handles exceptions gracefully
    • Check thread pool size (MAX_WORKERS=10) is reasonable
  2. Review KeyVault service parallelization (keyvault_service.py)
    • Verify _process_single_keyvault() is thread-safe (no shared mutable state)
    • Check nested parallelism for keys/secrets/monitor (max 3 workers per vault)
    • Confirm proper exception handling per-vault
  3. Review the check fix (keyvault_rbac_secret_expiration_set.py)
    • Verify each secret now gets its own Check_Report_Azure instance
    • Confirm resource=secret (not resource=keyvault) for proper attribution
  4. Testing considerations:
    • Run against an Azure environment with multiple vaults
    • Verify logs show parallel processing: "Starting threads for...", "Completed ... in X.XXs"
    • Confirm findings are correctly attributed to individual secrets

Checklist

Community Checklist
  • This feature/issue is listed in here or roadmap.prowler.com
  • Is it assigned to me, if not, request it via the issue/feature in here or Prowler Community Slack

SDK/CLI

  • Are there new checks included in this PR? Yes / No
    • If so, do we need to update permissions for the provider? Please review this carefully.

UI

  • All issue/task requirements work as expected on the UI
  • Screenshots/Video of the functionality flow (if applicable) - Mobile (X < 640px)
  • Screenshots/Video of the functionality flow (if applicable) - Table (640px > X < 1024px)
  • Screenshots/Video of the functionality flow (if applicable) - Desktop (X > 1024px)
  • Ensure new entries are added to CHANGELOG.md, if applicable.

API

  • All issue/task requirements work as expected on the API
  • Endpoint response output (if applicable)
  • EXPLAIN ANALYZE output for new/modified queries or indexes (if applicable)
  • Performance test results (if applicable)
  • Any other relevant evidence of the implementation (if applicable)
  • 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, if applicable.

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@HugoPBrito HugoPBrito requested review from a team as code owners January 23, 2026 12:53
@github-actions github-actions bot added the provider/azure Issues/PRs related with the Azure provider label Jan 23, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 23, 2026

✅ All necessary CHANGELOG.md files have been updated.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 23, 2026

Conflict Markers Resolved

All conflict markers have been successfully resolved in this pull request.

…o PROWLER-737-clone-scans-running-for-more-than-24-hours-in-production-sdk-root-cause
result = future.result()
if result is not None:
results.append(result)
except Exception:

Check notice

Code scanning / CodeQL

Empty except Note

'except' clause does nothing but pass and there is no explanatory comment.

Copilot Autofix

AI about 9 hours ago

In general, empty except blocks should be replaced with handling that at minimum logs the exception, and optionally re-raises it or aggregates it, depending on how critical the failure is. In this case, we want to preserve the current behavior of continuing to process other futures while improving observability.

The best minimal-impact fix is to log any exception raised by future.result() using the existing logger, similar to how __set_clients__ logs errors. We should not re-raise, because that would change the function’s behavior from “best effort, skip failures” to “fail entire call on first error”. Instead, we log the exception (optionally including the associated item and traceback line) and keep skipping that result, preserving the public behavior while making failures visible.

Concretely, in prowler/providers/azure/lib/service/service.py:

  • Inside AzureService.__threading_call__, replace the except Exception: pass block with except Exception as error: and a logger.error(...) call. We can mirror the formatting used in __set_clients__, and additionally include the item associated with the future (available via futures[future]).
  • No new imports are needed; logger is already imported at the top of the file.
Suggested changeset 1
prowler/providers/azure/lib/service/service.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/prowler/providers/azure/lib/service/service.py b/prowler/providers/azure/lib/service/service.py
--- a/prowler/providers/azure/lib/service/service.py
+++ b/prowler/providers/azure/lib/service/service.py
@@ -38,8 +38,11 @@
                 result = future.result()
                 if result is not None:
                     results.append(result)
-            except Exception:
-                pass
+            except Exception as error:
+                logger.error(
+                    f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] "
+                    f"while processing item {futures.get(future)!r}: {error}"
+                )
 
         return results
 
EOF
@@ -38,8 +38,11 @@
result = future.result()
if result is not None:
results.append(result)
except Exception:
pass
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] "
f"while processing item {futures.get(future)!r}: {error}"
)

return results

Copilot is powered by AI and may make mistakes. Always verify output.
@codecov
Copy link

codecov bot commented Jan 23, 2026

Codecov Report

❌ Patch coverage is 25.00000% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.08%. Comparing base (f7a16ff) to head (3e297bf).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9876      +/-   ##
==========================================
- Coverage   86.60%   86.08%   -0.52%     
==========================================
  Files         222      222              
  Lines        5645     5686      +41     
==========================================
+ Hits         4889     4895       +6     
- Misses        756      791      +35     
Flag Coverage Δ
prowler-py3.10-azure 86.03% <25.00%> (-0.58%) ⬇️
prowler-py3.11-azure 86.03% <25.00%> (-0.58%) ⬇️
prowler-py3.12-azure 86.03% <25.00%> (-0.58%) ⬇️
prowler-py3.9-azure 86.08% <25.00%> (-0.52%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
prowler 86.08% <25.00%> (-0.52%) ⬇️
api ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 23, 2026

🔒 Container Security Scan

Image: prowler:b2906df
Last scan: 2026-01-23 13:12:42 UTC

📊 Vulnerability Summary

Severity Count
🔴 Critical 3
Total 3

3 package(s) affected

⚠️ Action Required

Critical severity vulnerabilities detected. These should be addressed before merging:

  • Review the detailed scan results
  • Update affected packages to patched versions
  • Consider using a different base image if updates are unavailable

📋 Resources:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

provider/azure Issues/PRs related with the Azure provider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants