Point your firewall at our EDL and 17,410+ AI-tool domains are enforced automatically — updated daily, zero manual imports.
The "dynamic" means the content behind the URL changes without any firewall reconfiguration. You set the URL once and the list updates itself.
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.
EDLs were designed for threat intelligence — lists of malicious IPs or C2 domains published by threat intel providers.
Same infrastructure, different use case. Host 17,410+ 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.
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.
*.example.com are supported on some platforms to match all subdomains.app.toolname.com, api.toolname.com, cdn.toolname.com).# AI Tools Blocklist — External Dynamic List # Generated: 2026-07-09T06:00:00Z # Total entries: 17,410+ # Source: https://aitoolsblocklist.com # Format: one domain per line # Update frequency: daily # Category: All (18 categories) # --- Text & Language --- openai.com chat.openai.com api.openai.com claude.ai anthropic.com gemini.google.com jasper.ai copy.ai writesonic.com rytr.me # --- Image & Visual --- midjourney.com stability.ai leonardo.ai deepai.org playground.com # --- Code & Development --- github.com/features/copilot codeium.com tabnine.com replit.com cursor.sh # ... 17,410+ domains total
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.
Serve over TLS with a valid certificate your firewall trusts.
Content-Type: text/plain so every platform parses the list.
Cache-Control aligned to your firewall's refresh interval.
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.
# /etc/nginx/sites-available/edl.conf # nginx virtual host for serving the AI-tool EDL server { listen 443 ssl http2; server_name edl.internal.example.com; ssl_certificate /etc/ssl/certs/edl.pem; ssl_certificate_key /etc/ssl/private/edl.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; root /var/www/edl; index index.txt; # Serve the EDL file with correct headers location /ai-tools.txt { default_type text/plain; charset utf-8; # Cache-Control: firewall gets fresh content every 5 minutes add_header Cache-Control "public, max-age=300, must-revalidate"; add_header X-EDL-Generated $date_gmt; add_header X-EDL-Source "aitoolsblocklist.com"; # ETag for conditional requests (If-None-Match) etag on; # Restrict access to firewall management IPs allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; } # Health check endpoint for monitoring location /health { return 200 "OK\n"; add_header Content-Type text/plain; } access_log /var/log/nginx/edl-access.log; error_log /var/log/nginx/edl-error.log; }
allow / deny directives restrict access to internal network ranges — your firewall's management IP must fall within an allowed range. For cloud-delivered firewalls, allow the 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>
a2enmod ssl headers. Then run a2ensite edl and systemctl reload apache2.curl -I https://edl.internal.example.com/ai-tools.txt — expect a 200 OK with Content-Type: text/plain and your Cache-Control header./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.
mv (atomic on POSIX) to swap.
#!/usr/bin/env python3 # edl_update.py — Fetch AI-tool domains from API and write EDL file # Run via cron: 0 2 * * * /usr/local/bin/edl_update.py import requests, tempfile, os, sys, csv, io from datetime import datetime, timezone API_URL = "https://www.aitoolsblocklist.com/api/database/" API_KEY = os.environ["BLOCKLIST_API_KEY"] EDL_PATH = "/var/www/edl/ai-tools.txt" EDL_DIR = os.path.dirname(EDL_PATH) def fetch_domains(): resp = requests.get(API_URL, headers={ "X-API-Key": API_KEY }, params={ "action": "download_database" }, timeout=60) resp.raise_for_status() # CSV columns: domain,category,subcategory — keep the domain column rows = csv.DictReader(io.StringIO(resp.text)) return [row["domain"] for row in rows] def write_edl(domains): now = datetime.now(timezone.utc).isoformat() header = f"""# AI Tools Blocklist — External Dynamic List # Generated: {now} # Entries: {len(domains)} # Source: https://aitoolsblocklist.com # Update frequency: daily """ # Atomic write: temp file + rename fd, tmp = tempfile.mkstemp(dir=EDL_DIR, suffix=".tmp") try: with os.fdopen(fd, "w") as f: f.write(header) for d in domains: f.write(d.strip() + "\n") os.chmod(tmp, 0o644) os.rename(tmp, EDL_PATH) # atomic on same filesystem except: os.unlink(tmp) raise if __name__ == "__main__": domains = fetch_domains() if len(domains) < 1000: print(f"Sanity check failed: only {len(domains)} domains", file=sys.stderr) sys.exit(1) write_edl(domains) print(f"EDL updated: {len(domains)} domains written to {EDL_PATH}")
# /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
edl-update.service and edl-update.timer unit. The timer provides better journalctl integration, randomized delay, and status through systemctl list-timers.
Every poll of the EDL pulls from the same daily-updated intelligence that powers the full database.
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.
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.
Sends standard HTTP GET and respects Cache-Control and ETag headers. Avoids full re-download when nothing has changed.
must-revalidate matters. This 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 modern firmware.
External connector refresh: 60–86400 seconds. Supports HTTP/HTTPS. Respects Cache-Control. Typical max 131,072 entries per feed.
Custom intelligence feed via threat prevention modules. Refresh configurable via management console. Supports domain, IP, and URL types.
A stale EDL is a silent policy gap. If your pipeline breaks, the firewall keeps polling the same stale list with no error raised.
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.
#!/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}"
Both models deliver the same domain data. The choice depends on your security policy, infrastructure maturity, and operational preferences.
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.