Point your firewall at our EDL and 16,024+ AI-tool domains are enforced automatically — updated daily, zero manual imports.
An External Dynamic List is a plain-text file served over HTTPS containing one entry per line — a domain, IP, or URL. Your firewall downloads it on a schedule and enforces policy against every entry automatically.
The "dynamic" means the content behind the URL changes without any firewall reconfiguration. You set the URL once and the list updates itself.
EDLs were designed for threat intelligence — lists of malicious IPs or C2 domains published by threat intel providers.
Same infrastructure, different use case. Host 16,024+ AI-tool domains instead of malware domains, and create a block-AI-tools policy rule.
A static domain list is frozen the moment you paste it. New AI tools launch daily — 300,000 newly registered domains pass through our pipeline every 24 hours.
Configure once. The firewall polls the URL on schedule and stays current.
Between 50 and 500 new AI tools are identified daily. The EDL captures them automatically.
Refreshed on a 5-minute or hourly interval. The list stays current indefinitely.
If your firewall can read a text file from a URL, it can use an EDL.
Firewalls without explicit EDL features can consume the list through scripted imports or DNS-based enforcement.
Each line contains exactly one entry. Lines starting with # are comments and blank lines are ignored.
No JSON envelope, no XML wrapping — just raw domain names. Trivial to generate, trivial to validate, and compatible with every firewall platform that supports external lists.
Each line is a fully-qualified domain name without a protocol prefix or trailing slash. Wildcard entries like *.example.com are supported on some platforms to match all subdomains.
Our EDL includes both bare domains and wildcard entries where AI tools operate across multiple subdomains (e.g., app.toolname.com, api.toolname.com, cdn.toolname.com).
If your platform has a lower limit, our API lets you filter by category or confidence score.
The comment header documents generation timestamp, entry count, source, and update frequency. Firewalls ignore these lines, but they are invaluable for troubleshooting.
LF is universally supported and avoids edge-case parsing issues. If generating on Windows, ensure your script writes LF endings.
If your security policy requires serving the EDL from infrastructure you control, any web server with HTTPS works. The nginx config below creates a dedicated virtual host.
Content-Type: text/plainCache-Control aligned to refreshSetting max-age=300 ensures the list is never more than five minutes stale, even behind a CDN or proxy. For daily-refresh EDLs, max-age=3600 balances freshness and server load.
The allow / deny directives restrict access to internal network ranges. Your firewall's management IP must fall within an allowed range.
For Prisma Access or cloud-delivered firewalls, allow the Palo Alto cloud egress IPs or switch to API-key-based authentication instead.
Firewalls sending If-None-Match headers receive a 304 Not Modified when the list hasn't changed. This confirms freshness with a few hundred bytes instead of re-downloading the full list.
The Apache VirtualHost below provides equivalent functionality. mod_headers handles custom headers, mod_ssl handles TLS, and mod_authz_host handles IP-based access control.
# /etc/apache2/sites-available/edl.conf # Apache VirtualHost for serving the AI-tool EDL <VirtualHost *:443> ServerName edl.internal.example.com DocumentRoot /var/www/edl SSLEngine on SSLCertificateFile /etc/ssl/certs/edl.pem SSLCertificateKeyFile /etc/ssl/private/edl.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 <Directory /var/www/edl> Options -Indexes AllowOverride None # Restrict to internal firewall management IPs Require ip 10.0.0.0/8 Require ip 172.16.0.0/12 Require ip 192.168.0.0/16 </Directory> # Serve .txt files with correct MIME type and caching headers <FilesMatch "\.txt$"> ForceType text/plain Header set Cache-Control "public, max-age=300, must-revalidate" Header set X-EDL-Source "aitoolsblocklist.com" </FilesMatch> ErrorLog ${APACHE_LOG_DIR}/edl-error.log CustomLog ${APACHE_LOG_DIR}/edl-access.log combined </VirtualHost>
Enable the required modules: a2enmod ssl headers. Then run a2ensite edl and systemctl reload apache2.
Verify with curl -I https://edl.internal.example.com/ai-tools.txt — expect a 200 OK with Content-Type: text/plain and your Cache-Control header.
Both configurations assume the EDL file already exists at /var/www/edl/ai-tools.txt. The next section covers the automated pipeline to populate it.
A cron job or systemd timer triggers the pipeline daily (or more frequently on enterprise plans). It runs three stages:
Pull domain data from the AI Tools Blocklist API.
Convert the response into one-domain-per-line EDL format.
Atomically replace the live file so mid-update polls never read a partial list.
Writing directly to the live path creates a window where the file is partial. A firewall polling mid-write receives a truncated list, unblocking thousands of domains. Always write to a temp file, then use mv (atomic on POSIX) to swap.
The sanity check is a safety valve. If the API returns fewer than 1,000 domains — far below the expected 16,024+ — the script preserves the last known-good version.
Set the threshold well below your expected count but high enough to catch empty or near-empty responses from auth failures or API outages.
Schedule the script with cron or systemd:
# /etc/cron.d/edl-update # Run daily at 02:00 UTC — after our pipeline publishes the daily update at 01:00 UTC BLOCKLIST_API_KEY=your_api_key_here 0 2 * * * root /usr/local/bin/edl_update.py >> /var/log/edl-update.log 2>&1
For systemd, create an edl-update.service and edl-update.timer unit. The timer provides better journalctl integration, randomized delay, and status through systemctl list-timers.
The refresh interval controls how often the firewall downloads the list. If the file hasn't changed and the server returns a 304 Not Modified, the firewall keeps its current copy without re-parsing.
Configurable per list: 5 min, hourly, daily, or weekly.
Recommendation: Hourly. The list changes daily, but hourly refresh resolves pipeline delays within 60 minutes. Five-minute intervals are available for enterprise near-real-time needs.
Set in seconds: minimum 60s, default 300s (5 min).
Sends standard HTTP GET and respects Cache-Control and ETag headers. Avoids full re-download when nothing has changed.
must-revalidate MattersThis directive prevents stale content from being served if the origin is temporarily unreachable. For security policy enforcement, you want the firewall to fail closed (keep the last known-good list) rather than fail open with an expired list.
EDL refresh intervals: 5 min, hourly, daily, weekly. Supports HTTP, HTTPS, and IP-based EDLs. ETag and If-Modified-Since supported on PAN-OS 10.1+.
External connector refresh: 60–86400 seconds. Supports HTTP/HTTPS. Respects Cache-Control. Maximum 131,072 entries per feed.
Custom Intelligence Feed via Threat Prevention. Refresh configurable in SmartConsole. Supports domain, IP, and URL types.
On PAN-OS, an EDL is a first-class object referenceable in security rules, URL filtering profiles, and anti-spyware profiles. The CLI below creates the EDL, sets hourly refresh, and builds a blocking policy rule.
After committing, verify with request system external-list show name ai-tools-blocklist. The output shows last refresh time, entry count, and any download errors.
If the entry count is zero, check the EDL URL, DNS resolution, and any rules blocking outbound HTTPS from the management plane. See our Palo Alto integration guide for detailed troubleshooting.
Define the EDL as a shared object in the Panorama device group and push to all managed firewalls. Consistent AI-tool blocking across all sites with a single config change — each firewall polls independently.
FortiGate uses the Threat Feed Connector (External Connector in FortiOS 7.4+) to consume external domain lists. The connector creates an address object you reference in a firewall policy with a deny action.
# FortiOS CLI — External connector for AI-tool domain list # Step 1: Create the external connector config system external-resource edit "ai-tools-blocklist" set type domain set resource "https://feeds.aitoolsblocklist.com/v1/edl?key=YOUR_API_KEY&format=plain" set refresh-rate 300 set status enable next end # Step 2: Create a web filter profile using the external resource config webfilter profile edit "block-ai-tools" config web set blocklist enable end config ftgd-wf unset options end next end # Step 3: Create a firewall policy that applies the web filter config firewall policy edit 100 set name "Block-AI-Tools" set srcintf "internal" set dstintf "wan1" set srcaddr "all" set dstaddr "ai-tools-blocklist" set action deny set schedule "always" set logtraffic all next end # Verify the external resource is loaded diagnose system external-resource list
Verify with diagnose system external-resource list. If the entry count shows zero, check URL accessibility, DNS resolution, and outbound HTTPS rules from the management IP.
Push the external connector config to all managed FortiGate devices through policy packages. Centralized AI-tool blocking across the entire Fortinet fabric with a single template.
A stale EDL is a silent policy gap. If your pipeline breaks, the firewall keeps polling the same stale list with no error raised.
When a cron job fails, an API key expires, or disk fills up, the EDL file stops updating — but it still exists and parses correctly. The only signal is the timestamp in the header, and nobody reads that until something has already gone wrong.
Modification time of the EDL file on your web server. Alert if older than 26 hours.
Number of domains in the file. A sudden drop indicates a pipeline error.
Whether the firewall successfully downloaded the list on its last poll.
Any monitoring stack — Nagios, Zabbix, Prometheus, Datadog, or a simple cron script with a Slack webhook — can check these signals.
#!/bin/bash # edl_monitor.sh — Check EDL freshness and entry count # Alert if the EDL file is older than 26 hours or entry count drops below threshold EDL_FILE="/var/www/edl/ai-tools.txt" MAX_AGE_HOURS=26 MIN_ENTRIES=30000 SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" # Check file age file_age=$(( ($(date +%s) - $(stat -c %Y "$EDL_FILE")) / 3600 )) if [ "$file_age" -gt "$MAX_AGE_HOURS" ]; then curl -s -X POST "$SLACK_WEBHOOK" \ -d "{\"text\":\"EDL STALE: ai-tools.txt is ${file_age}h old (threshold: ${MAX_AGE_HOURS}h)\"}" fi # Check entry count (exclude comments and blank lines) entry_count=$(grep -cv '^#\|^$' "$EDL_FILE") if [ "$entry_count" -lt "$MIN_ENTRIES" ]; then curl -s -X POST "$SLACK_WEBHOOK" \ -d "{\"text\":\"EDL COUNT LOW: ai-tools.txt has ${entry_count} entries (threshold: ${MIN_ENTRIES})\"}" fi echo "EDL check: age=${file_age}h, entries=${entry_count}"
Run this script hourly via cron. The 26-hour threshold provides a buffer above the 24-hour cycle to avoid false alerts from minor timing differences.
logid=0100044546 to your SIEM for refresh failure alerts.Both models deliver the same domain data. The choice depends on your security policy, infrastructure maturity, and operational preferences.
Most organizations start with the managed EDL for zero-overhead deployment. Regulated industries (finance, healthcare, defense) or air-gapped environments typically move to self-hosted.
The transition is straightforward: build the pipeline above, point firewalls at the new internal URL, and decommission the external reference. Only the delivery path changes.
Tell us your firewall platform and deployment model. We will provide the EDL URL or API credentials for your self-hosted pipeline — ready to deploy in under an hour.
Specify your firewall vendor, deployment model (managed or self-hosted), and any category filtering requirements. We will provision your EDL feed within 24 hours.