feat(docs): publish Azure deployment template

- Serve the generated ARM template from public Mintlify documentation
- Display the same canonical JSON in the Azure authentication guide
- Enforce byte-for-byte synchronization with drift tests
This commit is contained in:
Hugo P.Brito committed 2026-08-21 09:45:21 +01:00
1 parent 970bb22df2
commit c230fdf9ce
10 files changed
+587 -200

No files matched your search

@@ -1,12 +1,14 @@
---
title: 'Azure Authentication in Prowler'
title: "Azure Authentication in Prowler"
---
import AzureProwlerScanTemplate from "/snippets/azure-prowler-scan-template.mdx";
Prowler for Azure supports multiple authentication types. Authentication methods vary between Prowler Cloud and Prowler CLI:
**Prowler Cloud:**
- [**Certificate Authentication**](#certificate-authentication) (**Recommended** — one-click setup via the [Deploy to Azure](#deploy-to-azure-quick-start) quick-start)
- [**Certificate Authentication**](#certificate-authentication) (**Recommended**)
- [**Service Principal Application**](#service-principal-application-authentication-recommended) with a client secret
**Prowler CLI:**
@@ -60,6 +62,7 @@ Replace `Directory.Read.All` with `Domain.Read.All` for more restrictive permiss
![Grant Admin Consent](/images/providers/grant-admin-consent.png)
![Granted Admin Consent](/images/providers/granted-admin-consent.png)
</Tab>
<Tab title="Azure CLI">
1. To grant permissions to a Service Principal, execute the following command in a terminal:
@@ -67,6 +70,7 @@ Replace `Directory.Read.All` with `Domain.Read.All` for more restrictive permiss
```console
az ad app permission add --id {appId} --api 00000003-0000-0000-c000-000000000000 --api-permissions 7ab1d382-f21e-4acd-a863-ba3e13f7da61=Role 246dd0d5-5bd0-4def-940b-0421030a5b68=Role b0afded3-3588-46d8-8b3d-9842eff778da=Role
```
</Tab>
</Tabs>
### Subscription Scope Permissions
@@ -76,8 +80,8 @@ These permissions are required to perform security checks against Azure resource
- `Reader` – Grants read-only access to Azure resources.
- `ProwlerRole` – A custom role with minimal permissions needed for some specific checks, defined in the [prowler-azure-custom-role](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-azure-custom-role.json).
#### Assigning "Reader" Role at the Subscription Level
By default, Prowler scans all accessible subscriptions. If you need to audit specific subscriptions, you must assign the necessary role `Reader` for each one. For streamlined and less repetitive role assignments in multi-subscription environments, refer to the [following section](/user-guide/providers/azure/subscriptions#recommendation-for-managing-multiple-subscriptions).
<Tabs>
@@ -96,6 +100,7 @@ By default, Prowler scans all accessible subscriptions. If you need to audit spe
6. Click "Review + assign" to finalize and apply the role assignment.
![Adding the Reader Role to a Subscription](/images/providers/add-reader-role.png)
</Tab>
<Tab title="Azure CLI">
1. Open a terminal and execute the following command to assign the `Reader` role to the identity that is going to be assumed by Prowler:
@@ -103,6 +108,7 @@ By default, Prowler scans all accessible subscriptions. If you need to audit spe
```console
az role assignment create --role "Reader" --assignee <user, group, or service principal> --scope /subscriptions/<subscription-id>
```
</Tab>
</Tabs>
#### Assigning "ProwlerRole" Permissions at the Subscription Level
@@ -142,6 +148,7 @@ The checks requiring this `ProwlerRole` can be found in this [section](/user-gui
The `assignableScopes` field in the JSON custom role file must be updated to reflect the correct subscription or management group. Use one of the following formats: `/subscriptions/<subscription-id>` or `/providers/Microsoft.Management/managementGroups/<management-group-id>`.
</Note>
</Tab>
<Tab title="Azure CLI">
1. To create a new custom role, open a terminal and execute the following command:
@@ -161,40 +168,42 @@ The checks requiring this `ProwlerRole` can be found in this [section](/user-gui
}'
```
2. If the command is executed successfully, the output is going to be similar to the following:
2. If the command is executed successfully, the output is going to be similar to the following:
```json
{
"assignableScopes": [
"/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
],
"createdBy": null,
"createdOn": "YYYY-MM-DDTHH:MM:SS.SSSSSS+00:00",
"description": "Role used for checks that require read-only access to Azure resources and are not covered by the Reader role.",
"id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/providers/Microsoft.Authorization/roleDefinitions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"name": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"permissions": [
```json
{
"actions": [
"Microsoft.Web/sites/host/listkeys/action",
"Microsoft.Web/sites/config/list/Action"
"assignableScopes": [
"/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
],
"condition": null,
"conditionVersion": null,
"dataActions": [],
"notActions": [],
"notDataActions": []
"createdBy": null,
"createdOn": "YYYY-MM-DDTHH:MM:SS.SSSSSS+00:00",
"description": "Role used for checks that require read-only access to Azure resources and are not covered by the Reader role.",
"id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/providers/Microsoft.Authorization/roleDefinitions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"name": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"permissions": [
{
"actions": [
"Microsoft.Web/sites/host/listkeys/action",
"Microsoft.Web/sites/config/list/Action"
],
"condition": null,
"conditionVersion": null,
"dataActions": [],
"notActions": [],
"notDataActions": []
}
],
"roleName": "ProwlerRole",
"roleType": "CustomRole",
"type": "Microsoft.Authorization/roleDefinitions",
"updatedBy": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"updatedOn": "YYYY-MM-DDTHH:MM:SS.SSSSSS+00:00"
}
],
"roleName": "ProwlerRole",
"roleType": "CustomRole",
"type": "Microsoft.Authorization/roleDefinitions",
"updatedBy": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"updatedOn": "YYYY-MM-DDTHH:MM:SS.SSSSSS+00:00"
}
```
</Tab>
</Tabs>
```
</Tab>
</Tabs>
### Additional Resources
@@ -216,30 +225,22 @@ The following security checks require the `ProwlerRole` permissions for executio
- `app_function_ftps_deployment_disabled`
- `app_function_latest_runtime_version`
---
## Deploy to Azure (Quick-Start)
Prowler ships a public [Bicep template](https://github.com/prowler-cloud/prowler/blob/master/permissions/templates/azure/bicep/prowler-scan.bicep) that provisions the App Registration / Service Principal, the built-in `Reader` role assignment, and the custom `ProwlerRole` — all bound to an X.509 certificate credential — in a single deployment. This is the Azure analogue of the AWS CloudFormation quick-create flow.
Use it from the Prowler Cloud **add-provider wizard**:
1. Pick **Azure**, then choose **Certificate Authentication (Recommended)** in the credential-type selector.
2. Click **Deploy to Azure**. The button opens the Azure Portal deployment blade pre-loaded with the template.
3. Generate a certificate (see [Certificate Authentication](#certificate-authentication) below) and paste the base64-encoded public certificate into the Bicep `certificateBase64` parameter.
4. Deploy and, when the stack finishes, copy the `tenantId` and `applicationId` outputs into Prowler along with the base64-encoded PEM bundle (certificate + private key) you generated locally. The `certificateThumbprint` output is informational — use it to reconcile that the deployed keyCredential matches your local certificate.
<Note>
The Deploy to Azure button is not available for sovereign clouds (Azure Government, Azure China, Azure Germany) or personal Microsoft accounts. Follow the manual [Certificate Authentication](#certificate-authentication) or [Service Principal](#service-principal-application-authentication-recommended) instructions instead.
</Note>
## Certificate Authentication
Certificate authentication is the recommended way to run Prowler against Azure because Entra ID keeps only the public certificate (no shared secrets to rotate), and Bicep can bind the certificate to the App Registration natively via `keyCredentials`.
Certificate authentication is the recommended way to run Prowler against Azure because Microsoft Entra ID stores only the public certificate, so no shared client secret needs to be rotated. Upload the public certificate to the App Registration and provide Prowler with the matching private bundle.
### Generating the certificate
### Prerequisites
Prowler never sees the private key during deployment — the user generates the keypair locally.
Certificate authentication requires:
- Permission to create or manage a Microsoft Entra App Registration.
- An administrator authorized to grant tenant-wide consent for the required Microsoft Graph application permissions.
- `Owner` on each target subscription when using the deployment template. `Contributor` cannot create role definitions or role assignments.
- The Service Principal Object ID from **Microsoft Entra ID** > **Enterprise applications** > the application > **Overview**. This value differs from the Object ID under **App registrations**.
### Generating the Certificate
Generate the key pair locally. Upload only the public certificate to Microsoft Entra ID and keep the private key secure.
**macOS / Linux (OpenSSL):**
@@ -247,7 +248,7 @@ Prowler never sees the private key during deployment — the user generates the
openssl req -x509 -newkey rsa:4096 -keyout prowler.key -out prowler.crt \
-days 365 -nodes -subj "/CN=Prowler"
# Base64 of the public certificate — feeds `certificateBase64` in the Bicep template
# Base64 of the public certificate, if a base64 representation is needed
openssl x509 -in prowler.crt -outform DER | base64 | tr -d '\n'
# Base64 of a PEM bundle containing the certificate AND the private key —
@@ -264,41 +265,78 @@ $cert = New-SelfSignedCertificate -Subject "CN=Prowler" `
-KeyExportPolicy Exportable -KeySpec Signature `
-KeyLength 4096 -HashAlgorithm SHA256
[Convert]::ToBase64String($cert.RawData) # certificateBase64
$cert.Thumbprint # certificateThumbprint
Export-Certificate -Cert $cert -FilePath prowler.cer
# Export a PKCS#12 bundle for Prowler. Keep this value secret.
$pfxBytes = $cert.Export('Pfx', '')
[Convert]::ToBase64String($pfxBytes)
```
### Deploying Subscription Permissions
The Prowler Azure Resource Manager (ARM) template creates the subscription permissions required by Prowler for an existing Service Principal. The template does not create an App Registration, create a Service Principal, upload a certificate, or grant Microsoft Graph permissions.
To deploy the template:
1. Copy the Service Principal Object ID from **Enterprise applications**.
2. Click [**Deploy to Azure**](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fdocs.prowler.com%2Fassets%2Ftemplates%2Fazure%2Fprowler-scan.json).
3. Select the target subscription, enter the Service Principal Object ID, and review the optional deployment label and custom role name.
4. Create the deployment.
The deployment creates:
- The subscription-scoped `ProwlerRole` custom role definition.
- A `Reader` role assignment for the existing Service Principal.
- A `ProwlerRole` role assignment for the existing Service Principal.
The deployment outputs the tenant ID, subscription ID, and `ProwlerRole` definition ID. Return to Prowler with the App Registration's Application (client) ID and the certificate bundle after the deployment succeeds.
<Note>
Azure Portal loads the public ARM JSON from
`https://docs.prowler.com/assets/templates/azure/prowler-scan.json`. For a
sovereign cloud or a deployment that cannot retrieve this public URL, download
the [ARM JSON template](/assets/templates/azure/prowler-scan.json) and deploy
it with the Azure CLI or Azure PowerShell.
</Note>
### ARM JSON Template
The following JSON is generated from the same canonical template that Azure Portal retrieves from Prowler documentation:
<AzureProwlerScanTemplate />
### Prowler Cloud
Paste the following into the Certificate Authentication form of the Azure add-provider wizard:
- **Tenant ID** — copy from the deployment outputs.
- **Client ID** — copy from the deployment outputs (`applicationId`).
- **Certificate Content** — the base64-encoded **PEM bundle** (certificate + private key) or PKCS#12 export. The Bicep template only received the public certificate; Prowler needs both parts here to sign the token request.
- **Tenant ID** — copy the Directory (tenant) ID from the App Registration overview.
- **Client ID** — copy the Application (client) ID from the App Registration overview.
- **Certificate Content** — provide the base64-encoded **PEM bundle** (certificate + private key) or PKCS#12 export. Prowler needs both parts to sign the token request.
### Prowler CLI
Set the following environment variables and invoke Prowler with `--certificate-auth`:
Set the certificate environment variables and run Prowler with `--certificate-auth`:
```console
export AZURE_CLIENT_ID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
export AZURE_TENANT_ID="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
export AZURE_CERTIFICATE_CONTENT="<base64-encoded private key>"
export AZURE_CERTIFICATE_CONTENT="<base64-encoded certificate and private key bundle>"
prowler azure --certificate-auth
```
Alternatively, point Prowler at a certificate file on disk:
Alternatively, provide a PEM or PKCS#12 file that contains both the certificate and matching private key:
```console
prowler azure --certificate-auth --certificate-path /path/to/prowler.key
prowler azure --certificate-auth --certificate-path /path/to/prowler-bundle.pem
```
## Service Principal Application Authentication
This client-secret flow is the supported fallback when [Certificate Authentication](#certificate-authentication) is not an option — for example on sovereign clouds where the Deploy to Azure quick-start is unavailable, or when an organisation policy forbids certificate-based service principals. New Prowler Cloud onboardings should prefer certificate authentication.
This client-secret flow is the supported fallback when [Certificate Authentication](#certificate-authentication) is not an option or when an organization policy forbids certificate-based Service Principals. New Prowler Cloud onboardings should prefer certificate authentication.
### Creating the Service Principal
For more information, see [Creating Prowler Service Principal](/user-guide/providers/azure/create-prowler-service-principal).
### Environment Variables (CLI)
@@ -315,7 +353,7 @@ Execution with the `--sp-env-auth` flag fails if these variables are not set or
## AZ CLI Authentication
*Available only for Prowler CLI*
_Available only for Prowler CLI_
Use stored Azure CLI credentials:
@@ -325,7 +363,7 @@ prowler azure --az-cli-auth
## Managed Identity Authentication
*Available only for Prowler CLI*
_Available only for Prowler CLI_
Authenticate via Azure Managed Identity when running Prowler on Azure resources (VMs, Container Instances, Azure Functions, etc.):
@@ -341,7 +379,13 @@ Before using Managed Identity authentication, the following steps are required:
2. **Assign the required permissions** to the Managed Identity on the target subscription(s) to scan
<Warning>
A common misconception is that enabling a Managed Identity on a resource automatically grants it permissions. **This is not the case.** Without explicit role assignments, Prowler will be unable to scan subscriptions and will return authorization errors, resulting in incomplete security assessments. The Managed Identity itself is a service principal that must be explicitly granted Reader and ProwlerRole permissions on each subscription to scan.
A common misconception is that enabling a Managed Identity on a resource
automatically grants it permissions. **This is not the case.** Without
explicit role assignments, Prowler will be unable to scan subscriptions and
will return authorization errors, resulting in incomplete security
assessments. The Managed Identity itself is a service principal that must be
explicitly granted Reader and ProwlerRole permissions on each subscription to
scan.
</Warning>
### Step-by-Step Setup Guide
@@ -365,6 +409,7 @@ A common misconception is that enabling a Managed Identity on a resource automat
# Get the principal ID
az vm identity show --name <vm-name> --resource-group <resource-group> --query principalId -o tsv
```
</Tab>
<Tab title="Azure Container Instance">
**Via Azure CLI:**
@@ -379,6 +424,7 @@ A common misconception is that enabling a Managed Identity on a resource automat
# Get the principal ID
az container show --resource-group <resource-group> --name <container-name> --query identity.principalId -o tsv
```
</Tab>
</Tabs>
@@ -400,6 +446,7 @@ The Managed Identity needs the **Reader** role on each subscription to scan. Thi
<Note>
When scanning a subscription different from where the VM is located, ensure the role is assigned on the **target subscription**, not the VM's subscription.
</Note>
</Tab>
<Tab title="Azure CLI">
```console
@@ -413,6 +460,7 @@ The Managed Identity needs the **Reader** role on each subscription to scan. Thi
--assignee-principal-type ServicePrincipal \
--scope /subscriptions/<target-subscription-id>
```
</Tab>
</Tabs>
@@ -448,6 +496,7 @@ The ProwlerRole is a custom role required for specific security checks. First, c
--assignee-principal-type ServicePrincipal \
--scope /subscriptions/<target-subscription-id>
```
</Tab>
<Tab title="Azure Portal">
Follow the same process as creating the ProwlerRole in the [Assigning ProwlerRole Permissions](/user-guide/providers/azure/authentication#assigning-prowlerrole-permissions-at-the-subscription-level) section, then assign it to the Managed Identity using the same steps as the Reader role assignment.
@@ -459,7 +508,9 @@ The ProwlerRole is a custom role required for specific security checks. First, c
For Entra ID (Azure AD) checks, the Managed Identity needs Microsoft Graph API permissions: `Directory.Read.All`, `Policy.Read.All`, and `AuditLog.Read.All`.
<Note>
Assigning Microsoft Graph API permissions to a Managed Identity requires Azure CLI or PowerShell - it cannot be done through the Azure Portal's standard role assignment interface.
Assigning Microsoft Graph API permissions to a Managed Identity requires Azure
CLI or PowerShell - it cannot be done through the Azure Portal's standard role
assignment interface.
</Note>
```console
@@ -495,7 +546,8 @@ prowler azure --managed-identity-auth --subscription-ids <subscription-id>
```
<Note>
Wait a few minutes after assigning roles for Azure to propagate permissions. Role assignments are not always immediately effective.
Wait a few minutes after assigning roles for Azure to propagate permissions.
Role assignments are not always immediately effective.
</Note>
### Troubleshooting
@@ -505,6 +557,7 @@ Wait a few minutes after assigning roles for Azure to propagate permissions. Rol
**Cause:** The Managed Identity does not have the Reader role assigned on any subscription.
**Solution:**
- Verify the Managed Identity has the Reader role assigned on at least one subscription.
- Wait a few minutes after role assignment for Azure to propagate permissions.
- Verify role assignments:
@@ -517,6 +570,7 @@ Wait a few minutes after assigning roles for Azure to propagate permissions. Rol
**Cause:** The Managed Identity lacks the Reader role on the target subscription.
**Solution:**
- Ensure the Reader role is assigned to the **Managed Identity's principal ID**, not the VM resource.
- Verify the role is assigned on the **target subscription** to scan, not just the VM's resource group.
- Check role assignments:
@@ -529,6 +583,7 @@ Wait a few minutes after assigning roles for Azure to propagate permissions. Rol
**Cause:** Managed Identity is not enabled on the resource, or Prowler is running outside of Azure.
**Solution:**
- Verify Managed Identity is enabled on the Azure resource.
- Ensure Prowler is running from within the Azure resource (not a local machine).
- Check Managed Identity status:
@@ -541,12 +596,13 @@ Wait a few minutes after assigning roles for Azure to propagate permissions. Rol
**Cause:** The Managed Identity lacks Microsoft Graph API permissions.
**Solution:**
- Assign the required Graph API permissions as shown in Step 4.
- These permissions are optional for basic resource scanning but required for Entra ID security checks.
## Browser Authentication
*Available only for Prowler CLI*
_Available only for Prowler CLI_
Authenticate using the default browser:
@@ -1,13 +1,20 @@
---
title: 'Getting Started With Azure on Prowler'
title: "Getting Started With Azure on Prowler"
---
## Prowler Cloud
<iframe width="560" height="380" src="https://www.youtube-nocookie.com/embed/v1as8vTFlMg" title="Prowler Cloud Onboarding Azure" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="1"></iframe>
<iframe
width="560"
height="380"
src="https://www.youtube-nocookie.com/embed/v1as8vTFlMg"
title="Prowler Cloud Onboarding Azure"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen="1"
></iframe>
> Walkthrough video onboarding an Azure Subscription using Service Principal.
<Note>
**Government Cloud Support**
@@ -27,8 +34,8 @@ For detailed instructions on how to create the Service Principal and configure p
1. Go to the [Azure Portal](https://portal.azure.com/#home) and search for `Subscriptions`
2. Locate and copy your Subscription ID
![Search Subscription](/images/providers/search-subscriptions.png)
![Subscriptions Page](/images/providers/get-subscription-id.png)
![Search Subscription](/images/providers/search-subscriptions.png)
![Subscriptions Page](/images/providers/get-subscription-id.png)
---
@@ -37,19 +44,19 @@ For detailed instructions on how to create the Service Principal and configure p
1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler Local Server](/user-guide/tutorials/prowler-app)
2. Navigate to `Configuration` > `Providers`
![Providers Page](/images/prowler-app/cloud-providers-page.png)
![Providers Page](/images/prowler-app/cloud-providers-page.png)
3. Click `Add Provider`
![Add a Provider](/images/prowler-app/add-cloud-provider.png)
![Add a Provider](/images/prowler-app/add-cloud-provider.png)
4. Select `Microsoft Azure`
![Select Microsoft Azure](/images/providers/select-azure-prowler-cloud.png)
![Select Microsoft Azure](/images/providers/select-azure-prowler-cloud.png)
5. Add the Subscription ID and an optional alias, then click `Next`
![Add Subscription ID](/images/providers/add-subscription-id.png)
![Add Subscription ID](/images/providers/add-subscription-id.png)
### Step 3: Add Credentials to Prowler Cloud
@@ -57,43 +64,26 @@ Azure supports two authentication methods in the add-provider wizard. Prowler Cl
#### Certificate Authentication (Recommended)
Certificate authentication uses an Entra ID App Registration with an X.509 keyCredential. The Prowler wizard splits the setup in two steps: the manual pieces that only the Azure Portal UI supports (creating the App Registration and uploading the certificate), and the RBAC pieces the Prowler Bicep template deploys with one click on Azure Portal (`Reader` + custom `ProwlerRole`).
<Note>
**Why the split?** Microsoft Graph resources in Bicep (`Microsoft.Graph/applications`, `Microsoft.Graph/servicePrincipals`) are [not supported by Portal `Deploy to Azure` URL deployments](https://github.com/microsoftgraph/msgraph-bicep-types/issues/294). A template that contains them fails at deploy time with `Authorization_RequestDenied` regardless of the deploying user's Entra ID role — even a Global Administrator hits the wall. The wizard therefore creates the App Registration through the Portal UI (which works normally) and reserves the Bicep template for the RBAC assignments (which Portal deployments handle cleanly).
</Note>
<Note>
**Required permissions in the Azure account you run the setup with**
Two separate permission systems apply:
- **Microsoft Entra ID**: `Application Administrator`, `Cloud Application Administrator`, or `Global Administrator` — needed for the manual App Registration + certificate upload in steps 1-2 below. Not required if your tenant already allows all users to register applications (Entra ID → Users → User settings).
- **Azure RBAC**: `Owner` on the target subscription — needed by the Deploy to Azure click in step 3 to assign `Reader` and the custom `ProwlerRole`.
If you do not have both, ask your Azure administrator to grant them or to complete the missing step on your behalf.
</Note>
Certificate authentication uses a Microsoft Entra ID App Registration with an X.509 certificate. Complete the App Registration, certificate upload, Microsoft Graph permissions, and subscription permissions by following [Azure Certificate Authentication](/user-guide/providers/azure/authentication#certificate-authentication).
1. In the Azure wizard, select **Certificate Authentication (Recommended)**.
2. **Create the App Registration** — click *Open Azure Portal → New App Registration* in the wizard, sign in to the tenant you want Prowler to scan, and register an application. Any name works (e.g. `Prowler`); keep the default single-tenant audience and no redirect URI.
3. **Upload the certificate** — in the wizard, click *Generate certificate for me* to produce a keypair in your browser (the private key auto-fills the form; the public certificate downloads as a base64 text file). Decode it with `base64 -D -i prowler-cert-base64.txt -o prowler.cer`, then in the Portal open your new App Registration → *Certificates & secrets → Certificates → Upload certificate* and upload `prowler.cer`. Prefer the CLI? Follow the openssl / PowerShell steps in [Certificate Authentication → Generating the certificate](/user-guide/providers/azure/authentication#generating-the-certificate).
4. **Copy the Service Principal Object ID** — Portal → Entra ID → *Enterprise applications* → search for the app you just created → *Overview → Object ID*. Beware this is a different Object ID than the one on the *App registrations* blade (Enterprise applications and App registrations are two separate objects with separate Object IDs but the same Application (client) ID).
5. **Grant Prowler read access** — click **Deploy to Azure** in the wizard. The Azure Portal opens with the Prowler Bicep template pre-loaded. Pick your target subscription, paste the Service Principal Object ID from step 4 into the `servicePrincipalObjectId` field, and confirm the deployment.
6. **Fill the wizard** — back in Prowler, paste the `Tenant ID` from Entra ID → Overview, the `Application (client) ID` from your App Registration's Overview page, and confirm the `Certificate Private Key` field is populated from step 3. Click **Next**, then **Launch Scan**.
2. Paste the Directory (tenant) ID and Application (client) ID from the App Registration.
3. Paste the base64-encoded certificate and private key bundle. To create a new key pair, click **Generate certificate**, upload the downloaded `prowler-cert.cer` file to the App Registration, and keep the generated bundle in the form.
4. Click **Next**, then **Launch Scan**.
#### Service Principal with Client Secret
The manual fallback that mirrors the previous Prowler Cloud flow, and the only option for sovereign clouds and personal accounts.
Client-secret authentication remains available when certificate authentication is not suitable.
1. Follow [Creating Prowler Service Principal](/user-guide/providers/azure/create-prowler-service-principal) to create the App Registration, assign the [Entra](/user-guide/providers/azure/create-prowler-service-principal#assigning-proper-permissions) and [Subscription](/user-guide/providers/azure/subscriptions) scope permissions, and issue a client secret.
2. In the Azure wizard, select **Service Principal with Client Secret**.
3. Paste `Tenant ID`, `Client ID`, and `Client Secret`.
![Prowler Cloud Azure Credentials](/images/providers/add-credentials-azure-prowler-cloud.png)
![Prowler Cloud Azure Credentials](/images/providers/add-credentials-azure-prowler-cloud.png)
4. Click `Next`, then **Launch Scan**.
![Launch Scan Azure](/images/providers/launch-scan.png)
![Launch Scan Azure](/images/providers/launch-scan.png)
---
@@ -105,28 +95,6 @@ To authenticate with Azure, Prowler CLI supports multiple authentication methods
For detailed authentication setup instructions, see [Authentication](/user-guide/providers/azure/authentication).
**Certificate Authentication (Recommended)**
Set up environment variables with the base64-encoded private key:
```console
export AZURE_CLIENT_ID="XXXXXXXXX"
export AZURE_TENANT_ID="XXXXXXXXX"
export AZURE_CERTIFICATE_CONTENT="<base64-encoded private key>"
```
Then run:
```console
prowler azure --certificate-auth
```
Or point Prowler at a certificate file on disk:
```console
prowler azure --certificate-auth --certificate-path /path/to/prowler.key
```
**Service Principal with Client Secret**
Set up environment variables: