Issue search
Which component is affected?
Prowler CLI/SDK
Cloud Provider (if applicable)
Azure
Steps to Reproduce
- Use an Azure tenant that contains several subscriptions sharing the same
display_name (for example, auto-generated names under certain billing account types — all subscriptions show the same name in az account list). A Service Principal with Reader assigned at a management group that covers all of them can see every subscription:
az account list --query "[].{name:name, id:id, state:state}" -o table
Name State
---------------- -------
<same-name> Enabled
<same-name> Enabled
<same-name> Enabled
<same-name> Enabled
- Run any Azure scan, either letting Prowler auto-discover the subscriptions:
prowler azure --sp-env-auth
or passing the IDs explicitly:
prowler azure --sp-env-auth --subscription-ids <ID1> <ID2> <ID3> <ID4>
- Observe Prowler's banner and the resulting CSV.
Expected behavior
All four subscriptions are scanned, and each one is represented in identity.subscriptions and in the output CSV (one row per finding per subscription).
Actual Result with Screenshots or Logs
Only a single subscription is scanned regardless of how many were requested. Prowler's banner line lists just one subscription:
· Azure Subscriptions: ['<same-name>: <last-subscription-id>']
The output CSV contains findings only for that last subscription; the other subscription IDs do not appear anywhere in the file.
Root cause (in prowler/providers/azure/azure_provider.py, AzureProvider.setup_identity):
if not subscription_ids:
for subscription in subscriptions_client.subscriptions.list():
identity.subscriptions.update(
{subscription.display_name: subscription.subscription_id}
)
else:
for id in subscription_ids:
subscription = subscriptions_client.subscriptions.get(subscription_id=id)
identity.subscriptions.update({subscription.display_name: id})
identity.subscriptions is a dict keyed by display_name. Azure allows multiple subscriptions to share the same display_name, so each update() call overwrites the previous entry and only the last subscription survives. The dictionary is later consumed by every downstream service and by output/reporting code, so only that surviving subscription is scanned.
The argparse definition for --subscription-ids (prowler/providers/azure/lib/arguments/arguments.py) uses nargs="+" and parses the list correctly — the list arrives intact at setup_identity. The bug is purely in how the dictionary is built.
How did you install Prowler?
From brew (brew install prowler)
Environment Resource
Workstation
OS used
macOS
Prowler version
5.23.0 (also confirmed against the 5.18.3 container image — same code path is unchanged)
Python version
3.12
Pip version
Not applicable (installed via brew)
Context
Workaround until this is fixed: invoke Prowler once per subscription, passing a single --subscription-ids <ID> each time. With one ID per process no dictionary collision can occur, so every subscription is scanned independently.
Fix proposed in #10718.
Issue search
Which component is affected?
Prowler CLI/SDK
Cloud Provider (if applicable)
Azure
Steps to Reproduce
display_name(for example, auto-generated names under certain billing account types — all subscriptions show the same name inaz account list). A Service Principal withReaderassigned at a management group that covers all of them can see every subscription:Expected behavior
All four subscriptions are scanned, and each one is represented in
identity.subscriptionsand in the output CSV (one row per finding per subscription).Actual Result with Screenshots or Logs
Only a single subscription is scanned regardless of how many were requested. Prowler's banner line lists just one subscription:
The output CSV contains findings only for that last subscription; the other subscription IDs do not appear anywhere in the file.
Root cause (in
prowler/providers/azure/azure_provider.py,AzureProvider.setup_identity):identity.subscriptionsis adictkeyed bydisplay_name. Azure allows multiple subscriptions to share the samedisplay_name, so eachupdate()call overwrites the previous entry and only the last subscription survives. The dictionary is later consumed by every downstream service and by output/reporting code, so only that surviving subscription is scanned.The argparse definition for
--subscription-ids(prowler/providers/azure/lib/arguments/arguments.py) usesnargs="+"and parses the list correctly — the list arrives intact atsetup_identity. The bug is purely in how the dictionary is built.How did you install Prowler?
From brew (brew install prowler)
Environment Resource
Workstation
OS used
macOS
Prowler version
5.23.0 (also confirmed against the 5.18.3 container image — same code path is unchanged)
Python version
3.12
Pip version
Not applicable (installed via
brew)Context
Workaround until this is fixed: invoke Prowler once per subscription, passing a single
--subscription-ids <ID>each time. With one ID per process no dictionary collision can occur, so every subscription is scanned independently.Fix proposed in #10718.