Authenticated External Dynamic Lists on PAN-OS

osting EDLs that Palo Alto Networks firewalls fetch over HTTPS with per-firewall credentials, including the PAN-OS behaviour that makes it look broken when it isn't.

Authenticated External Dynamic Lists on PAN-OS

An External Dynamic List (EDL) is a text file that the firewall downloads from a web server on a schedule. It's the cleanest way to feed blocklists, allowlists or threat intel into policy without a commit for every change. A public list can be a plain HTTPS URL. A list that's specific to one customer, or not meant for the internet, needs authentication. PAN-OS supports that, but it imposes conditions that aren't obvious from the GUI, and its built-in test button misreports the result.

This article covers the setup that works, both on the server and on the firewall, and the behaviour you'll hit along the way. All of it was verified on a PA-440 running PAN-OS 11.2.10-h3.

// Concept
External Dynamic List (EDL)

A list of IP addresses, domains or URLs hosted on an external web server. The firewall polls it at a set interval (every five minutes to monthly) and uses the entries as a policy object, without a commit when the list changes.

Prerequisites

Item Requirement
List source HTTPS URL with a stable server certificate
Firewall PAN-OS with internet access from the management interface, or a service route for External Dynamic Lists
Authentication HTTP Basic (username + password) on the web server
Certificate A CA certificate the firewall can import to validate the server

The Rule That Shapes Everything

PAN-OS only offers Client Authentication (username and password) on an EDL object when the source is HTTPS and a Certificate Profile is selected. Without a profile, the fields don't appear, and the firewall fetches the list anonymously.

That means the firewall must be able to validate your server's certificate against a CA you hand it. The choice of CA then matters more than it seems:

  • A CDN or reverse proxy in front of the list (e.g. Cloudflare's orange-cloud proxy) presents its certificate, and the CDN can change issuers without notice. Every customer's Certificate Profile would then fail on the next renewal. Serve the list from a hostname that terminates TLS on your own server: in Cloudflare, a DNS-only record.
  • A public CA (e.g. Let's Encrypt) works, but customers must trust the root, and you're exposed to that CA's root and intermediate changes.
  • A private, single-purpose root CA gives you full control. The root is valid for ten years, you renew the server certificate yearly, and customers import the root once.

Option: A Private Root CA Limited to One Hostname

Asking a customer to import your root CA is a fair security question for their team. Answer it technically with an X.509 Name Constraint: the root can then only vouch for your EDL hostname, nothing else. PAN-OS 11.2 accepts a root with the constraint marked critical.

root.cnf:

[req]
distinguished_name = dn
prompt = no
[dn]
O  = Example Org
CN = Example Org EDL Root CA
[v3_root]
basicConstraints     = critical, CA:true, pathlen:0
keyUsage             = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
nameConstraints      = critical, permitted;DNS:edl.example.com

server.ext:

basicConstraints       = critical, CA:false
keyUsage               = critical, digitalSignature, keyEncipherment
extendedKeyUsage       = serverAuth
subjectAltName         = DNS:edl.example.com
authorityKeyIdentifier = keyid
# Root CA: once, offline, passphrase-protected (10 years)
openssl genrsa -aes256 -out edl-root.key 4096
openssl req -x509 -new -key edl-root.key -sha256 -days 3650 \
  -config root.cnf -extensions v3_root -out edl-root.crt

# Server certificate: repeat yearly; customers notice nothing
openssl req -new -newkey rsa:2048 -nodes -keyout edl.example.com.key \
  -subj "/CN=edl.example.com" -out edl.example.com.csr
openssl x509 -req -in edl.example.com.csr -CA edl-root.crt -CAkey edl-root.key \
  -CAcreateserial -days 397 -sha256 -extfile server.ext -out edl.example.com.crt

# Fingerprint to publish, so customers can verify the root they received
openssl x509 -in edl-root.crt -noout -fingerprint -sha256

Keep the root key off the web server. Leave out CRL and OCSP URLs: if the server key leaks, you rotate the server certificate, not the root.

Note: Generate one set of credentials per firewall, not per customer, and don't let people choose them. Random secrets (e.g. 32 URL-safe characters) let you store only a hash, revoke one device at a time, and see in your logs which device is polling.

Firewall Configuration

Step 1 — Import the Root and Build a Certificate Profile

  1. Device → Certificate Management → Certificates → Import the root CA certificate (certificate only, no key).
  2. Leave Trusted Root CA unticked. That flag is for SSL decryption trust, and the EDL doesn't need it.
  3. Device → Certificate Management → Certificate Profile: add a profile containing only this CA. Leave CRL and OCSP off.

Step 2 — Create the EDL Object

Objects → External Dynamic Lists → Add: choose the type matching the list's content (IP List, Domain List or URL List). Then enter the HTTPS source URL, select the Certificate Profile, and fill in Client Authentication.

The resulting configuration:

admin@PA-440# show external-list EXAMPLE-EDL
EXAMPLE-EDL {
  type {
    url {
      recurring { hourly; }
      certificate-profile EDL-Root-Profile;
      url https://edl.example.com/edl/example.txt;
      auth {
        username fw01;
        password -AQ==...;
      }
    }
  }
}

Step 3 — Use It in Policy, Then Commit

Reference the EDL in policy: a Security rule for IP and Domain lists, or a URL Filtering profile category for URL lists. Then commit.

Three Ways It Looks Broken When It Isn't

Test Source URL Reports "URL Access Error"

With Client Authentication configured, Test Source URL returns URL access error even when the list downloads fine. This is a known PAN-OS issue (PAN-69505), and it still happens on 11.2.10-h3. Don't troubleshoot based on the button.

The Candidate Config Isn't the Running Config

show external-list in configure mode shows the candidate configuration. Scheduled fetches and manual refreshes use the running configuration. Until the commit completes, the firewall keeps fetching without credentials and receives 401, even though the credentials appear in the config. Run show config diff in configure mode to check for uncommitted changes.

"Not Referenced in Policy, Not Downloaded, or Empty"

admin@PA-440> request system external-list show type url name EXAMPLE-EDL
EXAMPLE-EDL
        EDL is either not referenced in policy, not downloaded, or empty

This single message covers three different states. Reference the EDL in policy and commit before you troubleshoot further. Remember that a list that is legitimately empty produces the same output.

Troubleshooting From Both Ends

On the firewall, force a fetch and inspect the result:

request system external-list refresh type url name EXAMPLE-EDL
request system external-list show type url name EXAMPLE-EDL

Failed authentication shows up in the System log with event ID edl-cli-auth-failure.

On the web server, the default nginx combined log format already tells you whether credentials arrived. The third field is the HTTP Basic username:

203.0.113.7 - -    [08/Oct/2026:16:45:32 +0300] "GET /edl/example.txt HTTP/1.1" 401 24 "-" "-"
203.0.113.7 - fw01 [08/Oct/2026:17:02:10 +0300] "GET /edl/example.txt HTTP/1.1" 200 225 "-" "-"
Log line Meaning
- + 401 No credentials sent: no Certificate Profile, or not committed
username + 401 Credentials sent but wrong, disabled or expired
username + 200 / 304 Working
No line at all The firewall didn't fetch: DNS, routing, the management-interface path, or the EDL isn't used in policy
SSL error in error.log The certificate doesn't validate against the profile's CA

Don't Identify Firewalls by Source IP

Behind carrier-grade NAT (Starlink, many mobile and some fixed-line providers), the firewall's management traffic and the clients behind it can leave through different public IPs, and those addresses change. A per-firewall source-IP allowlist will break without warning. Credentials are the identity. Log the source IP for troubleshooting, but don't enforce it.

Checklist

Step Done when
EDL hostname terminates TLS on your server (no CDN proxy) openssl s_client shows your certificate and issuer
Root CA imported, Certificate Profile with only that CA Profile selected on the EDL object
Client Authentication filled in auth block present in show external-list
EDL used in policy Rule or URL Filtering profile references it
Committed show config diff is empty
Fetch verified request system external-list show lists entries; server log shows the username + 200