-
Notifications
You must be signed in to change notification settings - Fork 7
docs: add more ARM samples for JSON output and --initialPermissions flag #251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -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 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`: | ||||||
|
|
||||||
| ```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 ` | ||||||
|
||||||
| --initialPermissions @arm-initial-permissions.json ` | |
| --initialPermissions "@arm-initial-permissions.json" ` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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: | ||
|
|
@@ -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: | ||
|
|
||
| ``` | ||
| ```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 | ||
|
|
@@ -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", | ||
|
|
@@ -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 on lines
196
to
198
|
||
|
|
@@ -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): | ||
|
|
@@ -262,7 +255,7 @@ $env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID" | |
|
|
||
| Output: | ||
|
|
||
| ``` | ||
| ```text | ||
| Permissions Required: | ||
| ------------------------------------------------------------------------------------------------------------------------------------------ | ||
| Microsoft.ContainerService/managedClusters/read | ||
|
|
@@ -305,7 +298,7 @@ $env:MPF_SPOBJECTID = "YOUR_SP_OBJECT_ID" | |
|
|
||
| Output: | ||
|
|
||
| ``` | ||
| ```text | ||
| Permissions Required: | ||
| ------------------------------------------------------------------------------------------------------------------------------------------ | ||
| Microsoft.Authorization/roleAssignments/read | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -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): | ||||||
|
|
||||||
| ```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 ` | ||||||
|
||||||
| --initialPermissions @arm-initial-permissions.json ` | |
| --initialPermissions "@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" | ||
| ] | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be ARM with Known Permissions (JSON File format)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @bgdnext64 once this nit is addressed, we are good to go