← All posts

By Speedy ·August 4, 2026· 2 min read

New query_palo_cortex_cloud utility!!

New tool: query_palo_cortex_cloud

If you've pulled asset inventory out of Palo Alto's Cortex Cloud Platform before, you've probably hit the same two surprises I did.

First: the assets API doesn't paginate the way you'd expect. There's no page or offset parameter — instead you send a search_from/search_to window (an absolute [start, end) slice into the result set) and slide it forward yourself, request by request, until a page comes back short. Second: Cortex gives you a choice of two auth schemes, and picking wrong (or getting the "advanced" one's signing wrong) is a quiet way to spend an afternoon staring at 401s. Standard auth is just your raw API key in the Authorization header. Advanced auth signs every request fresh — sha256(api_key + nonce + timestamp_ms), sent alongside an x-xdr-nonce and x-xdr-timestamp — which is more resistant to key leakage and replay, but only if you build the signature exactly right.

query_palo_cortex_cloud handles both of those for you.

What it does

It's a CLI wrapper around Cortex Cloud's POST /public_api/v1/assets — the "get all or filtered assets" endpoint — that manages the search_from/search_to pagination internally and lets you pick standard or advanced auth with one flag.

python qpcc.py \
  --fqdn api-yourinstance.xdr.us.paloaltonetworks.com \
  --api-key "$CORTEX_API_KEY" --api-key-id "$CORTEX_API_KEY_ID" \
  --filters '{"AND":[{"SEARCH_FIELD":"xdm.asset.type.class","SEARCH_TYPE":"NEQ","SEARCH_VALUE":"Other"}]}' \
  --on-demand-fields xdm.host.ipv4_addresses \
  --sort-field xdm.asset.name --sort-order DESC

That pulls every non-"Other" asset in your tenant, with IP addresses pulled in as an on-demand field, sorted by name — streaming out as JSONL by default.

Why it's worth reaching for

  • Pagination is handled for you. You never touch search_from/search_to — set --page-size and --limit, and it slides the window and stops automatically on a short page.
  • Both auth schemes, one flag. --key-type standard or --key-type advanced — the request signing for advanced is built and re-generated on every request, not something you have to get right yourself.
  • Real filtering, not just "give me everything." Pass Cortex's own AND/OR filter tree straight through with --filters, plus --on-demand-fields for data that isn't returned by default.
  • Same output options as the rest of the query_* family. jsonl, csv, table (with rounded/double/single/ascii/none styles), or a proper json file — pick whatever the next step in your pipeline wants.
  • Plays nice with jq. JSONL streams to stdout, so | jq 'select(."xdm.asset.provider" == "AWS")' just works.

Try it

git clone https://github.com/ownjoo/query_palo_cortex_cloud.git
cd query_palo_cortex_cloud
pip install -r requirements.txt

python qpcc.py \
  --fqdn api-yourinstance.xdr.us.paloaltonetworks.com \
  --api-key "$CORTEX_API_KEY" --api-key-id "$CORTEX_API_KEY_ID"

Generate the API key and key ID from Settings → Configurations → API Keys in the Cortex console — you'll need a Cortex Cloud Runtime Security or Cortex Cloud Posture Management license for the endpoint itself.

Full docs, flags, and the rest of the output formats: ownjoo.org/projects/?repo=query_palo_cortex_cloud

// about the author

Speedy