Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 85 additions & 1 deletion docs/commandline-flags-and-env-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,90 @@ azmpf terraform \
# ... other required flags
```

### Example: ARM with Known Permissions (Comma-separated)

When deploying ARM templates where you already know some of the required permissions (e.g., from a previous MPF run or from documentation), you can seed them upfront to reduce execution time:

```bash
export MPF_SUBSCRIPTIONID="YOUR_SUBSCRIPTION_ID"
export MPF_TENANTID="YOUR_TENANT_ID"
export MPF_SPCLIENTID="YOUR_SP_CLIENT_ID"
export MPF_SPCLIENTSECRET="YOUR_SP_CLIENT_SECRET"
export MPF_SPOBJECTID="YOUR_SP_OBJECT_ID"

azmpf arm \
--initialPermissions "Microsoft.Network/virtualNetworks/read,Microsoft.Network/virtualNetworks/write,Microsoft.Network/virtualNetworks/subnets/read,Microsoft.Network/virtualNetworks/subnets/write" \
--templateFilePath ./samples/templates/aks-private-subnet.json \
--parametersFilePath ./samples/templates/aks-private-subnet-parameters.json \
--verbose
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm `
--initialPermissions "Microsoft.Network/virtualNetworks/read,Microsoft.Network/virtualNetworks/write,Microsoft.Network/virtualNetworks/subnets/read,Microsoft.Network/virtualNetworks/subnets/write" `
--templateFilePath .\samples\templates\aks-private-subnet.json `
--parametersFilePath .\samples\templates\aks-private-subnet-parameters.json `
--verbose
```

### Example: ARM with Known Permissions (JSON File format)

For ARM templates with many pre-requisite permissions, using a JSON file is cleaner. Create a file called `arm-initial-permissions.json`:
Comment thread
maniSbindra marked this conversation as resolved.

```json
{
"RequiredPermissions": {
"": [
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/write",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/write",
"Microsoft.Network/virtualNetworks/subnets/join/action"
]
}
}
```

Then run MPF with:

```bash
export MPF_SUBSCRIPTIONID="YOUR_SUBSCRIPTION_ID"
export MPF_TENANTID="YOUR_TENANT_ID"
export MPF_SPCLIENTID="YOUR_SP_CLIENT_ID"
export MPF_SPCLIENTSECRET="YOUR_SP_CLIENT_SECRET"
export MPF_SPOBJECTID="YOUR_SP_OBJECT_ID"

azmpf arm \
--initialPermissions @arm-initial-permissions.json \
--templateFilePath ./samples/templates/aks-private-subnet.json \
--parametersFilePath ./samples/templates/aks-private-subnet-parameters.json \
--verbose
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm `
--initialPermissions "@arm-initial-permissions.json" `
--templateFilePath .\samples\templates\aks-private-subnet.json `
--parametersFilePath .\samples\templates\aks-private-subnet-parameters.json `
--verbose
```

### Example: Bicep with Pre-existing Storage Backend (Comma-separated)

When deploying Bicep templates that depend on pre-existing Azure Storage (for configuration, state, or secrets), you can use comma-separated permissions to speed up analysis:
Expand Down Expand Up @@ -206,7 +290,7 @@ $env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"
$env:MPF_BICEPEXECPATH = "C:\Program Files\Azure Bicep CLI\bicep.exe"

.\azmpf.exe bicep `
--initialPermissions @bicep-backend-permissions.json `
--initialPermissions "@bicep-backend-permissions.json" `
--bicepFilePath .\samples\bicep\aks-private-subnet.bicep `
--parametersFilePath .\samples\bicep\aks-private-subnet-params.json `
--verbose
Expand Down
53 changes: 23 additions & 30 deletions docs/display-options.MD
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export MPF_SPCLIENTID="YOUR_SP_CLIENT_ID"
export MPF_SPCLIENTSECRET="YOUR_SP_CLIENT_SECRET"
export MPF_SPOBJECTID="YOUR_SP_OBJECT_ID"

$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json --outputFormat json --verbose
$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json --jsonOutput --verbose
```

Or using PowerShell on Windows:
Expand All @@ -129,12 +129,12 @@ $env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json --outputFormat json --verbose
.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json --jsonOutput --verbose
```

Output:
Comment thread
maniSbindra marked this conversation as resolved.

```
```text
INFO[0000] Executing MPF for ARM
INFO[0000] TemplateFilePath: .\samples\templates\aks-private-subnet.json
INFO[0000] ParametersFilePath: .\samples\templates\aks-private-subnet-parameters.json
Expand Down Expand Up @@ -163,7 +163,7 @@ INFO[0434] *************************
INFO[0447] Role definition deleted successfully
INFO[0452] Resource group deletion initiated successfully...
{
"permissions": [
"SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS": [
"Microsoft.ContainerService/managedClusters/read",
"Microsoft.ContainerService/managedClusters/write",
"Microsoft.Network/virtualNetworks/read",
Expand All @@ -174,33 +174,25 @@ INFO[0452] Resource group deletion initiated successfully...
"Microsoft.Resources/deployments/read",
"Microsoft.Resources/deployments/write"
],
"permissionsByResourceScope": [
{
"resourceScope": "/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-Uqc4z3E/providers/Microsoft.Network/virtualNetworks/azmpfakstestvnet",
"permissions": [
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/write"
]
},
{
"resourceScope": "/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-Uqc4z3E/providers/Microsoft.Network/virtualNetworks/azmpfakstestvnet/subnets/azmpfakstestsubnet",
"permissions": [
"Microsoft.Network/virtualNetworks/subnets/join/action",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/write"
]
},
{
"resourceScope": "/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-Uqc4z3E/providers/Microsoft.ContainerService/managedClusters/azmpfakstestcluster",
"permissions": [
"Microsoft.ContainerService/managedClusters/read",
"Microsoft.ContainerService/managedClusters/write"
]
}
"/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-Uqc4z3E/providers/Microsoft.ContainerService/managedClusters/azmpfakstestcluster": [
"Microsoft.ContainerService/managedClusters/read",
"Microsoft.ContainerService/managedClusters/write"
],
"/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-Uqc4z3E/providers/Microsoft.Network/virtualNetworks/azmpfakstestvnet": [
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/write"
],
"/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-Uqc4z3E/providers/Microsoft.Network/virtualNetworks/azmpfakstestvnet/subnets/azmpfakstestsubnet": [
"Microsoft.Network/virtualNetworks/subnets/join/action",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/write"
]
}

```

The JSON output is a map where the subscription ID key contains all aggregate permissions, and each resource scope key contains permissions specific to that resource.

### Bicep JSON Output

Similar to ARM templates, Bicep deployments can produce JSON output which shows detailed permission breakdowns. The following is a sample of JSON output:
Comment thread
maniSbindra marked this conversation as resolved.
Expand All @@ -216,7 +208,7 @@ export MPF_BICEPEXECPATH=$(which bicep)
azmpf bicep --bicepFilePath ./samples/bicep/storage-account-simple.bicep --parametersFilePath ./samples/bicep/storage-account-simple-params.json --jsonOutput --verbose
```

Output shows JSON with permissions array and permissionsByResourceScope details (similar to ARM example above).
The Bicep JSON output uses the same format as the ARM example above: a flat map where the subscription ID key contains all aggregate permissions, and each resource scope key contains permissions specific to that resource.

### Bicep Detailed Output

Expand All @@ -234,6 +226,7 @@ azmpf bicep --bicepFilePath ./samples/bicep/storage-account-simple.bicep --param
```

Output shows permissions aggregated and broken down by resource scope (similar to ARM detailed output example above).

### Viewing info, warn, or debug level logs

By default, the log level is error. More verbose logs can be viewed by setting the LOG_LEVEL environment variable to info, warn, or debug. Additionally, the global flag --verbose can be used to view info level logging and --debug can be used to view debug level logging. The following is a sample of default logging (error level only):
Expand Down Expand Up @@ -262,7 +255,7 @@ $env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

Output:

```
```text
Permissions Required:
------------------------------------------------------------------------------------------------------------------------------------------
Microsoft.ContainerService/managedClusters/read
Expand Down Expand Up @@ -305,7 +298,7 @@ $env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

Output:

```
```text
Permissions Required:
------------------------------------------------------------------------------------------------------------------------------------------
Microsoft.Authorization/roleAssignments/read
Expand Down
139 changes: 139 additions & 0 deletions docs/installation-and-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,145 @@ Microsoft.Resources/deployments/write

```

#### ARM with JSON Output

To get the output in JSON format (which includes per-resource permission details by default), use the `--jsonOutput` flag:

```shell
export MPF_SUBSCRIPTIONID="YOUR_SUBSCRIPTION_ID"
export MPF_TENANTID="YOUR_TENANT_ID"
export MPF_SPCLIENTID="YOUR_SP_CLIENT_ID"
export MPF_SPCLIENTSECRET="YOUR_SP_CLIENT_SECRET"
export MPF_SPOBJECTID="YOUR_SP_OBJECT_ID"

$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json --jsonOutput --verbose
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json --jsonOutput --verbose
```

Output (verbose INFO lines omitted for brevity):
Comment thread
maniSbindra marked this conversation as resolved.

```json
{
"SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS": [
"Microsoft.ContainerService/managedClusters/read",
"Microsoft.ContainerService/managedClusters/write",
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/subnets/join/action",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/write",
"Microsoft.Network/virtualNetworks/write",
"Microsoft.Resources/deployments/read",
"Microsoft.Resources/deployments/write"
],
"/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-OJ2zCNA/providers/Microsoft.ContainerService/managedClusters/azmpfakstestcluster": [
"Microsoft.ContainerService/managedClusters/read",
"Microsoft.ContainerService/managedClusters/write"
],
"/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-OJ2zCNA/providers/Microsoft.Network/virtualNetworks/azmpfakstestvnet": [
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/write"
],
"/subscriptions/SSSSSSSS-SSSS-SSSS-SSSS-SSSSSSSSSSSS/resourceGroups/testdeployrg-OJ2zCNA/providers/Microsoft.Network/virtualNetworks/azmpfakstestvnet/subnets/azmpfakstestsubnet": [
"Microsoft.Network/virtualNetworks/subnets/join/action",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/write"
]
}
```

The JSON output is a map where the subscription ID key contains all aggregate permissions, and each resource scope key contains permissions specific to that resource. The `--showDetailedOutput` flag is not needed with `--jsonOutput` (they are mutually exclusive). For more display options, see [display options](display-options.MD).

#### ARM with Initial Permissions

The `--initialPermissions` flag allows you to seed known permissions before MPF starts its analysis. This can reduce execution time by avoiding extra permission-discovery iterations. It accepts either a comma-separated list or a JSON file reference (prefixed with `@`).

##### Comma-separated format

```shell
export MPF_SUBSCRIPTIONID="YOUR_SUBSCRIPTION_ID"
export MPF_TENANTID="YOUR_TENANT_ID"
export MPF_SPCLIENTID="YOUR_SP_CLIENT_ID"
export MPF_SPCLIENTSECRET="YOUR_SP_CLIENT_SECRET"
export MPF_SPOBJECTID="YOUR_SP_OBJECT_ID"

$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json \
--initialPermissions "Microsoft.Network/virtualNetworks/read,Microsoft.Network/virtualNetworks/write,Microsoft.Network/virtualNetworks/subnets/read,Microsoft.Network/virtualNetworks/subnets/write" \
--verbose
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json `
--initialPermissions "Microsoft.Network/virtualNetworks/read,Microsoft.Network/virtualNetworks/write,Microsoft.Network/virtualNetworks/subnets/read,Microsoft.Network/virtualNetworks/subnets/write" `
--verbose
```

##### JSON file format

For many permissions, a JSON file is cleaner. Create a file (e.g., `arm-initial-permissions.json`):

```json
{
"RequiredPermissions": {
"": [
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/write",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/write",
"Microsoft.Network/virtualNetworks/subnets/join/action"
]
}
}
```

Then reference it with the `@` prefix:

```shell
export MPF_SUBSCRIPTIONID="YOUR_SUBSCRIPTION_ID"
export MPF_TENANTID="YOUR_TENANT_ID"
export MPF_SPCLIENTID="YOUR_SP_CLIENT_ID"
export MPF_SPCLIENTSECRET="YOUR_SP_CLIENT_SECRET"
export MPF_SPOBJECTID="YOUR_SP_OBJECT_ID"

$ ./azmpf arm --templateFilePath ./samples/templates/aks-private-subnet.json --parametersFilePath ./samples/templates/aks-private-subnet-parameters.json \
--initialPermissions @arm-initial-permissions.json \
--verbose
```

Or using PowerShell on Windows:

```powershell
$env:MPF_SUBSCRIPTIONID = "YOUR_SUBSCRIPTION_ID"
$env:MPF_TENANTID = "YOUR_TENANT_ID"
$env:MPF_SPCLIENTID = "YOUR_SP_CLIENT_ID"
$env:MPF_SPCLIENTSECRET = "YOUR_SP_CLIENT_SECRET"
$env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID"

.\azmpf.exe arm --templateFilePath .\samples\templates\aks-private-subnet.json --parametersFilePath .\samples\templates\aks-private-subnet-parameters.json `
--initialPermissions "@arm-initial-permissions.json" `
--verbose
```

For full details on the `--initialPermissions` flag, see [Initial Permissions](commandline-flags-and-env-variables.md#initial-permissions).

### Bicep

```shell
Expand Down
11 changes: 11 additions & 0 deletions samples/templates/arm-initial-permissions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"RequiredPermissions": {
"": [
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/write",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/write",
"Microsoft.Network/virtualNetworks/subnets/join/action"
]
}
}
Loading