Azure Provider¶
In this page you can find all the details about Microsoft Azure provider implementation in Prowler.
By default, Prowler will audit all the subscriptions that it is able to list in the Microsoft Entra tenant, and tenant Entra ID service. To configure it, follow the getting started page.
Azure Provider Classes Architecture¶
The Azure provider implementation follows the general Provider structure. This section focuses on the Azure-specific implementation, highlighting how the generic provider concepts are realized for Azure in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see Provider documentation. In next subsection you can find a list of the main classes of the Azure provider.
AzureProvider
(Main Class)¶
- Location:
prowler/providers/azure/azure_provider.py
- Base Class: Inherits from
Provider
(see base class details). - Purpose: Central orchestrator for Azure-specific logic, session management, credential validation, and configuration.
- Key Azure Responsibilities:
- Initializes and manages Azure sessions (supports Service Principal, CLI, Browser, and Managed Identity authentication).
- Validates credentials and sets up the Azure identity context.
- Loads and manages configuration, mutelist, and fixer settings.
- Retrieves subscription(s) metadata.
- Provides properties and methods for downstream Azure service classes to access session, identity, and configuration data.
Data Models¶
- Location:
prowler/providers/azure/models.py
- Purpose: Define structured data for Azure identity, session, region configuration, and subscription info.
- Key Azure Models:
AzureIdentityInfo
: Holds Azure identity metadata, including tenant ID, domain, subscription names and IDs, and locations.AzureRegionConfig
: Stores the specific region that will be audited. That can be: Global, US Government or China.AzureSubscription
: Represents a subscription with ID, display name, and state.
AzureService
(Service Base Class)¶
- Location:
prowler/providers/azure/lib/service/service.py
- Purpose: Abstract base class that all Azure service-specific classes inherit from. This implements the generic service pattern (described in service page) specifically for Azure.
- Key Azure Responsibilities:
- Receives an
AzureProvider
instance to access session, identity, and configuration. - Manages clients for all services by subscription.
- Exposes common audit context (
subscriptions
,locations
,audit_config
,fixer_config
) to subclasses.
- Receives an
Exception Handling¶
- Location:
prowler/providers/azure/exceptions/exceptions.py
- Purpose: Custom exception classes for Azure-specific error handling, such as credential, region, and session errors.
Session and Utility Helpers¶
- Location:
prowler/providers/azure/lib/
- Purpose: Helpers for argument parsing, region setup, mutelist management, and other cross-cutting concerns.
Specific Patterns in Azure Services¶
The generic service pattern is described in service page. You can find all the currently implemented services in the following locations:
- Directly in the code, in location
prowler/providers/azure/services/
- In the Prowler Hub for a more human-readable view.
The best reference to understand how to implement a new service is following the service implementation documentation and taking other services already implemented as reference. In next subsection you can find a list of common patterns that are used accross all Azure services.
Azure Service Common Patterns¶
- Services communicate with Azure using the Azure Python SDK, mainly using the Azure Management Client (except for the Microsoft Entra ID service, that is using the Microsoft Graph API), you can find the documentation with all the management services here.
- Every Azure service class inherits from
AzureService
, ensuring access to session, identity, configuration, and client utilities. - The constructor (
__init__
) always callssuper().__init__
with the service Azure Management Client and Prowler provider object (e.gsuper().__init__(WebSiteManagementClient, provider)
). - Resource containers must be initialized in the constructor, and they should be dictionaries, with the key being the subscription ID, the value being a dictionary with the resource ID as key and the resource object as value.
- All Azure resources are represented as Pydantic
BaseModel
classes, providing type safety and structured access to resource attributes. Some are represented as dataclasses due to legacy reasons, but new resources should be represented as PydanticBaseModel
classes. - Azure SDK functions are wrapped in try/except blocks, with specific handling for errors, always logging errors. It is a best practice to create a custom function for every Azure SDK call, in that way we can handle the errors in a more specific way.
Specific Patterns in Azure Checks¶
The Azure checks pattern is described in checks page. You can find all the currently implemented checks:
- Directly in the code, within each service folder, each check has its own folder named after the name of the check. (e.g.
prowler/providers/azure/services/storage/storage_blob_public_access_level_is_disabled/
) - In the Prowler Hub for a more human-readable view.
The best reference to understand how to implement a new check is the Azure check implementation documentation and taking other similar checks as reference.
Check Report Class¶
The Check_Report_Azure
class models a single finding for an Azure resource in a check report. It is defined in prowler/lib/check/models.py
and inherits from the generic Check_Report
base class.
Purpose¶
Check_Report_Azure
extends the base report structure with Azure-specific fields, enabling detailed tracking of the resource, resource ID, name, subscription, and location associated with each finding.
Constructor and Attribute Population¶
When you instantiate Check_Report_Azure
, you must provide the check metadata and a resource object. The class will attempt to automatically populate its Azure-specific attributes from the resource, using the following logic (in order of precedence):
-
resource_id
:- Uses
resource.id
if present. - Otherwise, uses
resource.resource_id
if present. - Defaults to an empty string if not available.
- Uses
-
resource_name
:- Uses
resource.name
if present. - Otherwise, uses
resource.resource_name
if present. - Defaults to an empty string if not available.
- Uses
-
subscription
:- Defaults to an empty string, it must be set in the check logic.
-
location
:- Uses
resource.location
if present. - Defaults to an empty string if not available.
- Uses
If the resource object does not contain the required attributes, you must set them manually in the check logic.
Other attributes are inherited from the Check_Report
class, from which you always have to set the status
and status_extended
attributes in the check logic.