Palo Alto Networks NGFW Best Practice Assessment (BPA) via the Posture API

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Palo Alto Networks NGFW Best Practice Assessment (BPA) via the Posture API

L2 Linker

Palo Alto Networks NGFW Best Practice Assessment (BPA) via the Posture API

Client & Partner Implementation Guide — Windows PowerShell Workflow

Purpose

This guide provides a practical end-to-end procedure for generating an on-demand Best Practice Assessment (BPA) from a Palo Alto Networks firewall configuration using the Strata Cloud Manager Posture API.

Current workflow

The legacy manual On-Demand BPA dashboard was scheduled for deprecation on April 30, 2026. The Posture API is the current programmatic path for uploading NGFW/Panorama configuration files and retrieving machine-readable BPA results.

Version: 1.0

Published: August 2026

Audience: Customers, partners, presales, and security engineering teams

This document is implementation guidance. Palo Alto Networks UI labels and APIs can evolve; verify against current official documentation before production automation.


Document Control

Item Details
Document Palo Alto Networks NGFW BPA via Posture API
Scope On-demand BPA from firewall XML configuration
Platform Strata Cloud Manager Posture API
Shell Windows PowerShell + curl.exe
Sensitive inputs Client Secret, OAuth token, signed upload URL, firewall XML configuration

Contents

  1. [Background and Migration Context](#1-background-and-migration-context)
  2. [Workflow Overview](#2-workflow-overview)
  3. [Prerequisites and Information to Collect](#3-prerequisites-and-information-to-collect)
  4. [Create the Palo Alto Networks Service Account](#4-create-the-palo-alto-networks-service-account)
  5. [Export the Firewall Configuration XML](#5-export-the-firewall-configuration-xml)
  6. [Run the BPA Workflow in PowerShell](#6-run-the-bpa-workflow-in-powershell)
  7. [Download and Format the BPA Result](#7-download-and-format-the-bpa-result)
  8. [Optional — Convert the BPA Best-Practice Results to CSV](#8-optional--convert-the-bpa-best-practice-results-to-csv)
  9. [Recommended Official References](#9-recommended-official-references)

1. Background and Migration Context

Palo Alto Networks has moved the on-demand BPA workflow toward the Strata Cloud Manager Posture API. The API accepts a configuration file from an NGFW or Panorama, processes it against Palo Alto Networks best-practice checks, and provides the assessment as structured JSON for downstream review or automation.

Deprecation context

A Palo Alto Networks LIVEcommunity discussion captured the platform notice stating that the On-Demand BPA dashboard would be deprecated on April 30, 2026 and that customers should transition to the new Posture API. The Posture API documentation identifies the on-demand Best Practice report API as an available module.

This guide focuses on a standalone NGFW export and a Windows PowerShell workflow. The same general API pattern can also be used with Panorama configuration files when the request metadata and configuration file are appropriate.


2. Workflow Overview

The workflow is:

  1. Create a service account in Palo Alto Networks Common Services > Identity & Access.
  2. Assign an API-capable role and securely record the Client ID, Client Secret, and TSG ID.
  3. Export a named firewall configuration snapshot as XML.
  4. Use OAuth 2.0 client credentials to obtain an access token.
  5. Create a BPA upload task and receive a task ID plus a signed upload URL.
  6. Upload the XML configuration to the signed URL.
  7. Poll the BPA task until the status is COMPLETED or FAILED.
  8. Download the JSON result.
  9. Optionally convert the best-practice checks into a readable CSV.

Important — API concurrency limit

The config-upload endpoint can return HTTP 429 when the maximum number of active jobs is reached. Current Palo Alto Networks API documentation states a limit of five active jobs.


3. Prerequisites and Information to Collect

Before starting, make sure you have:

  • Palo Alto Networks Hub / Activation Console access with permission to manage Identity & Access.
  • Administrative access to the target firewall sufficient to save and export a named configuration snapshot.
  • Windows PowerShell.
  • Windows curl.exe.
  • Outbound HTTPS access to:
  • auth.apps.paloaltonetworks.com
  • api.strata.paloaltonetworks.com
  • Signed cloud-storage upload/download URLs returned by the API.
  • The firewall:
  • Model family
  • Model
  • Serial number
  • PAN-OS version
  • Requester name and email.
  • A secure location for the exported XML and generated BPA report.

Security — Configuration sensitivity

A firewall configuration can reveal policy structure, addresses, objects, user information, certificates/keys metadata, and internal architecture. Treat the XML file and BPA output as confidential security data.


4. Create the Palo Alto Networks Service Account

Open the Palo Alto Networks Hub:

https://apps.paloaltonetworks.com/hub

4.1 Open Identity & Access

From the Hub / Activation Console, navigate to:

Common Services > Identity & Access

Select the tenant/TSG against which the API call will run.

JeanPaul222_0-1786098299046.png

 

4.2 Add an Identity / Service Account

JeanPaul222_1-1786098312985.png

 

4.3 Create the Service Account

Create a clearly named service account dedicated to BPA/API usage.

Use a name that allows the account owner and purpose to be identified during audits.

JeanPaul222_2-1786098327651.png

 

4.4 Save the Client ID, Client Secret, and TSG ID

Record the following values:

  • Client ID
  • Client Secret
  • Tenant Service Group (TSG) ID

Palo Alto Networks documentation warns that the Client Secret cannot be retrieved again after creation. If it is lost, reset or rotate the service account credentials.

JeanPaul222_3-1786098347950.png

 

Security — Credential handling

Store the Client Secret in an approved password/secret manager. Never place a real Client Secret, bearer token, or signed upload/download URL in client documentation, tickets, email, chat, or LIVEcommunity posts.

4.5 Assign Roles

For the broad-access setup described in this workflow, assign:

  • Apps & Services: All Apps & Services
  • Role: Superuser

Superuser provides unrestricted access. Use the minimum privileges appropriate for your environment whenever possible.


5. Export the Firewall Configuration XML

5.1 Save a Named Configuration Snapshot

On the firewall GUI, navigate to:

Device > Setup > Operations

Under Configuration Management:

  1. Select Save named configuration snapshot.
  2. Enter a descriptive file name.
  3. Save the snapshot.

5.2 Export the Named Configuration Snapshot

Still under:

Device > Setup > Operations

  1. Select Export named configuration snapshot.
  2. Choose the snapshot.
  3. Export it to the administrative workstation.

Palo Alto Networks exports the configuration as XML.

5.3 Record Device Metadata

Before opening PowerShell, record the values that will be used in the BPA request body:

  • Firewall family
  • Model
  • Serial number
  • PAN-OS version

Use values that match the device whose XML configuration is being uploaded.


6. Run the BPA Workflow in PowerShell

Important — PowerShell syntax

The commands below are provided inside fenced code blocks so that underscores, dollar signs, URLs, backticks, and other PowerShell characters remain unchanged when copied.

Copy the entire command or block exactly as shown. When a command uses a PowerShell continuation backtick (` ``), the backtick must be the final character on that line.

Step 1 — Get an OAuth Access Token

Replace the placeholder values with the credentials from the Palo Alto Networks service account.

$tokenResponse = Invoke-RestMethod -Method Post `
    -Uri "https://auth.apps.paloaltonetworks.com/oauth2/access_token" `
    -ContentType "application/x-www-form-urlencoded" `
    -Body @{
        grant_type    = "client_credentials"
        client_id     = "PASTE_YOUR_CLIENT_ID"
        client_secret = "PASTE_YOUR_CLIENT_SECRET"
        scope         = "tsg_id:PASTE_YOUR_TSG_ID"
    }

$token = $tokenResponse.access_token
$tokenResponse

The OAuth access token is stored in:

$token

Security

Do not post the real value of $tokenResponse, $token, your Client ID, or your Client Secret publicly.


Step 2 — Prepare Headers and the BPA Request Body

Replace the placeholder values with the actual firewall and requester information.

$headers = @{
    Authorization = "Bearer $token"
    Accept        = "application/json"
}

$body = @{
    family            = "FW_MODEL_FAMILY_E.g:400"
    model             = "MODEL_E.g:PA-450"
    "requester-email" = "YOUR_EMAIL"
    "requester-name"  = "YOUR_NAME"
    serial            = "FW_SERIAL_NB"
    version           = "FW_VERSION"
} | ConvertTo-Json

Example values could look like:

  • family = "400"
  • model = "PA-450"
  • version = "12.1.7"

Use the actual values for the firewall being assessed.


Step 3 — Create the BPA Upload Task

Run:

$bpa = Invoke-RestMethod -Method Post `
    -Uri "https://api.strata.paloaltonetworks.com/posture/checks/v1/reports/config-file-upload" `
    -Headers $headers `
    -ContentType "application/json" `
    -Body $body

$taskId = $bpa.task_id
$uploadUrl = $bpa.upload_url

$bpa

Expected Result

The response should contain:

  • A BPA task/tracking ID
  • A signed upload URL

The values are stored in:

$taskId
$uploadUrl

Keep the same PowerShell window/session open so these variables remain available.


Step 4 — Select and Validate the Raw XML File

Set $src to the actual location of the exported firewall XML file.

$src="C:\Users\YourUser\Downloads\FirewallConfig.xml"

Validate the path:

Test-Path $src

Expected Result

True

Do not continue until Test-Path returns True.


Step 5 — Upload the Raw XML to the Signed URL

Run:

curl.exe -v `
    -X PUT "$uploadUrl" `
    -H "Content-Type: text/plain" `
    -H "Content-Encoding: gzip" `
    --data-binary "@$src"
JeanPaul222_4-1786098422565.png

 


Step 6 — Poll the BPA Task Until Completion

Run:

curl.exe -v `
    -X GET "https://api.strata.paloaltonetworks.com/posture/checks/v1/reports/$taskId/bpa-result" `
    -H "Authorization: Bearer $token" `
    -H "Accept: application/json"

The documented task states include:

  • QUEUED
  • IN_PROGRESS
  • COMPLETED
  • FAILED

Continue to the download step only after the BPA status is:

COMPLETED

JeanPaul222_5-1786098493750.png

7. Download and Format the BPA Result

7.1 Retrieve the Completed BPA Response

Run:

$response = Invoke-RestMethod -Uri "https://api.strata.paloaltonetworks.com/posture/checks/v1/reports/$taskId/bpa-result" -Headers @{ "Accept"="application/json"; "Authorization"="Bearer $token" }

To inspect the returned object:

$response | ConvertTo-Json -Depth 20

If the download property is empty

First confirm that the task status is COMPLETED. API response schemas can evolve, so the returned payload should be treated as the source of truth.


7.2 Extract the Download URL

Run:

$downloadUrl = $response.result.custom_check_url

Confirm that the variable contains a URL:

$downloadUrl

It should return an HTTPS URL rather than a blank value.


7.3 Download the Raw JSON Result

To download the report into the current PowerShell directory:

Invoke-WebRequest -Uri $downloadUrl -OutFile "BPA_Report_$($taskId).json"

To download the report directly into the current user's Downloads folder:

$rawJsonPath = Join-Path $HOME "Downloads\BPA_Report_$($taskId).json"; Invoke-WebRequest -Uri $downloadUrl -OutFile $rawJsonPath; Write-Host "BPA report downloaded to: $rawJsonPath"

7.4 Optional — Save a Formatted / Indented JSON Copy

The following single PowerShell command downloads the returned JSON, parses it, formats it with indentation, and saves it under the user's Downloads folder:

$downloadPath = Join-Path $HOME "Downloads\BPA_Report_$($taskId).json"; $reportContent = Invoke-RestMethod -Uri $downloadUrl; $reportContent | ConvertTo-Json -Depth 100 | Set-Content -Path $downloadPath -Encoding UTF8; Write-Host "Report downloaded and formatted at: $downloadPath"

The generated file will look similar to:

C:\Users\<username>\Downloads\BPA_Report_<task-id>.json

8. Optional — Convert the BPA Best-Practice Results to CSV

The following PowerShell command flattens the nested best-practice warning/check structure into rows that can be filtered more easily in Excel.

It also sanitizes the device hostname before using it in the Windows filename.

Run this after $reportContent has been populated in Step 7.4.

$deviceName=[string]$reportContent.information.device_hostname; if([string]::IsNullOrWhiteSpace($deviceName)){$deviceName="UnknownDevice"}; $safeDeviceName=$deviceName -replace '[<>:"/\\|?*]','_'; $csvPath=Join-Path $HOME "Downloads\BPA_$($safeDeviceName)_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"; $rows=foreach($section in $reportContent.best_practices.PSObject.Properties){if($null -eq $section.Value){continue}; foreach($configType in $section.Value.PSObject.Properties){if($null -eq $configType.Value){continue}; foreach($item in @($configType.Value)){if($null -eq $item -or $null -eq $item.warnings){continue}; foreach($check in @($item.warnings)){if($null -eq $check){continue}; $status=if($check.check_excluded -eq $true){"Excluded"}elseif($check.check_passed -eq $true){"Passed"}else{"Failed"}; $configName=if($item.configuration.name){[string]$item.configuration.name}elseif($item.configuration.location){[string]$item.configuration.location}else{[string]$configType.Name}; $failedFields=if($null -ne $check.failed_fields){$check.failed_fields | ConvertTo-Json -Depth 100 -Compress}else{""}; [pscustomobject][ordered]@{"Device Hostname"=$deviceName;"Device IP"=[string]$reportContent.information.device_ip_address;"PAN-OS Version"=[string]$reportContent.information.PanOS_version;"Section"=[string]$section.Name;"Configuration Type"=[string]$configType.Name;"Configuration Name"=$configName;"Location"=[string]$item.configuration.location;"Status"=$status;"Check ID"=$check.check_id;"Check Type"=[string]$check.check_type;"Check Name"=[string]$check.check_name;"Check Message"=[string]$check.check_message;"Failed Fields"=$failedFields;"Excluded"=if($check.check_excluded -eq $true){"Yes"}else{"No"};"Defined By"=[string]$check.defined_by;"UUID"=[string]$check.uuid}}}}}; $rows | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8; Write-Host "Readable CSV created at: $csvPath"; Invoke-Item $csvPath

Result

The command:

  1. Reads the firewall hostname from the BPA JSON.
  2. Replaces characters that are invalid in Windows filenames.
  3. Iterates through the best_practices sections.
  4. Extracts each warning/check.
  5. Assigns a readable status:
  • Passed
  • Failed
  • Excluded
  1. Exports the results to a timestamped CSV file in the user's Downloads folder.
  2. Opens the generated CSV automatically.

Example output filename:

BPA_LBCRPA-450_20260807_124500.csv

Schema dependency

The CSV conversion assumes the BPA JSON contains information and best_practices structures consistent with the current report shape. If Palo Alto Networks changes the JSON schema, inspect the raw JSON and adjust the field paths.

 


9. Recommended Official References


Author

JeanPaul Mansour | Systems Engineer

Crestan International

www.crestanint.com


Community note

If you use this workflow in production, validate the returned API schema and endpoint behavior against the latest Palo Alto Networks documentation before incorporating it into automation.

0 REPLIES 0
  • 25 Views
  • 0 replies
  • 1 Likes
Like what you see?

Show your appreciation!

Click Like if a post is helpful to you or if you just want to show your support.

Click Accept as Solution to acknowledge that the answer to your question has been provided.

The button appears next to the replies on topics you’ve started. The member who gave the solution and all future visitors to this topic will appreciate it!

These simple actions take just seconds of your time, but go a long way in showing appreciation for community members and the LIVEcommunity as a whole!

The LIVEcommunity thanks you for your participation!