Upstream Source Monitoring Guide
July 3, 2026 ยท View on GitHub
Status: โ
Operational
Last Updated: 2026-07-03
Automation: Daily at 2 AM UTC
๐ฏ Overview
The upstream source monitoring system automatically fetches updates from trusted blocklist sources and creates pull requests with new domains. This keeps your lists current with the latest security threats without manual intervention.
Key Features
- ๐ค Fully Automated - Runs daily, creates PRs automatically
- ๐ Transparent - Every change visible with source attribution
- ๐ Trust-Based - Only trusted sources eligible for auto-merge
- โก Smart Caching - 24-hour TTL reduces bandwidth
- ๐ Scalable - Add sources by editing YAML config
- โ Quality Control - Manual review for large changes
๐๏ธ Architecture
Components
- Configuration (
config/lists.yml) - Defines upstream sources - Monitor Script (
scripts/monitor_upstream.py) - Fetches and compares - GitHub Workflow (
.github/workflows/upstream-monitor.yml) - Automation - Pull Requests - Generated with detailed change reports
Workflow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Daily Trigger (2 AM UTC) โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Load config/lists.yml โ
โ โข Find lists with upstream_sources โ
โ โข Get update frequency and trust settings โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ For each list with upstream sources: โ
โ 1. Fetch upstream data (with caching) โ
โ 2. Normalize domains based on format โ
โ 3. Compare with local list โ
โ 4. Identify new and removed domains โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ If changes found: โ
โ 1. Create git branch โ
โ 2. Add new domains to list โ
โ 3. Commit changes โ
โ 4. Generate PR description โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Create Pull Request: โ
โ โข Add labels (size:small/medium/large) โ
โ โข Mark auto-merge eligible if โค10 domains โ
โ โข Request review if >100 domains โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Create summary issue: โ
โ โข List all updated lists โ
โ โข Total new domains โ
โ โข Links to PRs โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Configuration
Current Lists with Upstream Sources
| List | Category | Sources | Frequency |
|---|---|---|---|
| abuse | Security | 2 | Daily |
| ads | Advertising | 3 | Daily/Weekly |
| crypto | Security | 2 | Daily/Weekly |
| fraud | Security | 1 | Daily |
| gambling | Content | 1 | Weekly |
| malware | Security | 3 | Daily |
| phishing | Security | 2 | Daily |
| porn | Content | 1 | Weekly |
| ransomware | Security | 2 | Daily |
| tracking | Privacy | 2 | Weekly |
Total: 23 upstream sources configured
Adding a New Upstream Source
Edit config/lists.yml and add to the appropriate list:
lists:
your_list:
description: "Description of your list"
category: security # or advertising, content, tracking, etc.
status: stable
upstream_sources:
- url: "https://example.com/blocklist.txt"
format: hosts # hosts, domains, adguard, or dnsmasq
trusted: true # true = auto-merge eligible, false = always review
update_frequency: daily # daily, weekly, hourly
filter_comments: true # Skip lines starting with #
max_domains: 1000 # Optional: limit to prevent huge merges
Format Types
| Format | Example | Description |
|---|---|---|
hosts | 0.0.0.0 example.com | Standard hosts file format |
domains | example.com | Plain domain list (one per line) |
adguard | ||example.com^ | AdGuard format |
dnsmasq | server=/example.com/ | dnsmasq format |
Trust Levels
trusted: true- Auto-merge eligible if changes โค thresholdtrusted: false- Always requires manual review
Update Frequencies
daily- Checked every day at 2 AM UTCweekly- Checked once per weekhourly- Checked every hour (use sparingly!)
๐ Usage
Manual Execution
# Check a specific list
python scripts/monitor_upstream.py --list ads
# Check all lists with upstream sources
python scripts/monitor_upstream.py --all
# Dry run (check only, don't create PRs)
python scripts/monitor_upstream.py --all --dry-run
# Force fresh fetch (ignore cache)
python scripts/monitor_upstream.py --all --no-cache
Automated Execution
The workflow runs automatically via GitHub Actions:
- Schedule: Daily at 2 AM UTC
- Trigger:
.github/workflows/upstream-monitor.yml - Manual: Actions tab โ "Upstream Source Monitoring" โ Run workflow
Manual Workflow Options
- Specific List: Set
list_nameinput (e.g.,ads) - All Lists: Leave
list_nameempty - Dry Run: Set
dry_runtotrue
๐ Pull Request Format
Example PR Title
chore: update malware from upstream sources (+8 domains)
Example PR Body
## ๐ค Automated Upstream Update: malware
This PR was automatically generated by the upstream monitoring system.
### ๐ Summary
- **List:** malware.txt
- **New domains:** 8
- **Removed domains:** 0
- **Sources checked:** 3
### ๐ก Source Details
#### Source 1: urlhaus-filter-hosts.txt
- **URL:** https://malware-filter.gitlab.io/malware-filter/urlhaus-filter-hosts.txt
- **Upstream total:** 5,234 domains
- **New domains:** 8
**New domains:**
malicious-domain1.com malicious-domain2.com malicious-domain3.com ...
### โ
Validation
- [ ] New domains are relevant to the malware category
- [ ] No false positives identified
- [ ] Domains pass validation checks
- [ ] Build succeeds
### ๐ Merge Policy
โ
**Auto-merge eligible** - Changes are below threshold (โค10 domains)
Labels Added
automation- Automated PRupstream-update- From upstream monitoringsize:small- โค10 domainssize:medium- 11-100 domainssize:large- >100 domainsauto-merge-candidate- Eligible for auto-mergeneeds-review- Requires manual reviewbreaking-change- Large changes (>100 domains)
๐ง Merge Policy
Automatic Merge Eligibility
Changes are eligible for automatic merge when ALL conditions are met:
โ
Source is trusted (trusted: true in config)
โ
Small changes (โค10 new domains)
โ
CI passes (all tests green)
โ
No conflicts (clean merge)
Manual Review Required
Manual review is required when ANY condition is met:
โ ๏ธ Source not trusted (trusted: false)
โ ๏ธ Medium changes (11-100 domains)
๐ด Large changes (>100 domains)
๐ด CI fails (tests or validation errors)
Review Checklist
When reviewing a PR:
- โ Verify domains are relevant to the list category
- โ Check for false positives (legitimate sites)
- โ Ensure no typos in domain names
- โ Confirm source is reputable
- โ Check CI results (all tests passing)
- โ Review sample domains in PR description
๐ฏ Thresholds & Limits
Global Settings (config/lists.yml)
settings:
upstream:
enabled: true
check_frequency: daily
auto_merge_threshold: 10 # Auto-merge if changes โค this
require_review_threshold: 100 # Manual review if changes > this
cache_ttl: 86400 # 24 hours in seconds
Per-Source Settings
upstream_sources:
- url: "..."
max_domains: 1000 # Limit to prevent huge merges
trusted: true # Auto-merge eligible
๐ Monitoring & Statistics
Daily Summary Issue
After each run, a summary issue is created with:
- Total new domains across all lists
- Number of lists updated
- Number of PRs created
- Links to each PR
- Auto-merge eligibility status
Weekly Reports
The weekly issue report (created by weekly-report.yml) includes:
- Upstream PRs created
- Auto-merge success rate
- Manual review turnaround time
- Source health statistics
๐ Troubleshooting
Common Issues
1. Source URL Not Accessible
Symptom: Workflow fails with "Error fetching URL"
Solution:
- Check if upstream source is still online
- Verify URL is correct in
lists.yml - Check for rate limiting or IP blocks
- Review GitHub Actions logs
2. Too Many Changes
Symptom: PR marked as breaking-change with 1000+ domains
Solution:
- Review upstream source quality
- Add
max_domainslimit to source config - Consider splitting large sources
- Verify source format is correct
3. False Positives
Symptom: Legitimate domains in PR
Solution:
- Mark source as
trusted: falsefor manual review - Report false positives to upstream source
- Add domains to local allowlist
- Consider different upstream source
4. Cache Issues
Symptom: Not detecting updates from upstream
Solution:
# Clear cache and force refresh
python scripts/monitor_upstream.py --all --no-cache
# Or delete cache files
rm -f /tmp/upstream_cache_*.txt
5. Workflow Not Running
Symptom: No PRs created at scheduled time
Solution:
- Check workflow is enabled in Actions tab
- Verify cron schedule in
.github/workflows/upstream-monitor.yml - Check GitHub Actions status page
- Review workflow run history for errors
๐ก๏ธ Security Considerations
Source Validation
Before adding a new upstream source:
- โ Verify reputation - Is the source well-known and trusted?
- โ Check update frequency - How often is it updated?
- โ Review content quality - Any false positives?
- โ
Test manually - Run with
--dry-runfirst - โ
Monitor initially - Set
trusted: falseuntil proven reliable
Sensitive Sources
For security-critical lists (ransomware, phishing):
- Set
trusted: falseto always require review - Limit
max_domainsto catch anomalies - Monitor more frequently (
dailyorhourly) - Set up alerts for large changes
๐ Examples
Example 1: Adding AdGuard DNS Filter
lists:
ads:
upstream_sources:
- url: "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt"
format: adguard
trusted: true
update_frequency: daily
max_domains: 5000
Example 2: Adding Security List (Requires Review)
lists:
phishing:
upstream_sources:
- url: "https://example.com/new-phishing-list.txt"
format: domains
trusted: false # Require manual review
update_frequency: daily
max_domains: 500
Example 3: Multiple Sources for One List
lists:
malware:
upstream_sources:
- url: "https://urlhaus.abuse.ch/downloads/hostfile/"
format: hosts
trusted: true
update_frequency: daily
- url: "https://malware-filter.gitlab.io/malware-filter/urlhaus-filter-hosts.txt"
format: hosts
trusted: true
update_frequency: daily
- url: "https://raw.githubusercontent.com/Spam404/lists/master/main-blacklist.txt"
format: domains
trusted: false
update_frequency: weekly
max_domains: 1000
๐ Support
Getting Help
- Documentation: This file
- Issues: GitHub Issues
- Workflow Logs: Actions tab โ Upstream Source Monitoring
- Configuration:
config/lists.yml
Reporting Bugs
If upstream monitoring is not working:
- Check the workflow run logs
- Review recent changes to
config/lists.yml - Test manually with
--dry-run - Open an issue with logs and details
๐ Best Practices
โ DO
- Start with
trusted: falsefor new sources - Set reasonable
max_domainslimits - Monitor PRs in the first week
- Use caching (
cache_ttl: 86400) - Group related sources in same list
- Document source in comments
โ DON'T
- Set all sources to
trusted: trueimmediately - Use
hourlyfrequency unless necessary - Skip manual review of large PRs
- Ignore build failures
- Add sources without testing
- Disable caching globally
๐ฎ Future Enhancements
Planned Features
- VirusTotal Integration - Reputation checks for new domains
- Incremental Updates - Track last-seen dates for efficiency
- Source Health Monitoring - Detect broken URLs automatically
- IP Address Support - Monitor upstream
.ipfiles - Scheduled Health Reports - Weekly source reliability stats
- Auto-Remove Dead Sources - Remove consistently failing sources
Feature Requests
Have an idea? Open an issue with the feature-request label!
๐ Statistics
Current Status
- Lists Configured: 10
- Upstream Sources: 23
- Update Frequency: Daily (2 AM UTC)
- Average PR Size: ~5-15 domains
- Auto-Merge Rate: ~80% (small trusted changes)
- Cache Hit Rate: ~90% (during same day)
Performance
- Fetch Time: ~5-10 seconds per source (without cache)
- Cache Hit Time: <1 second per source
- PR Generation: <30 seconds
- Total Runtime: ~2-5 minutes for all lists
Last Updated: 2026-07-03
Version: 1.0
Maintainer: Block List Project Team