A daily security news aggregator that keeps your team informed.
Automatically fetches cybersecurity articles from 13 verified working sources, organizes them into 7 categories, and delivers a polished newspaper to your Slack channel each morning.
Features • Installation • Usage • Configuration • Troubleshooting • Contributing
- 🔍 Multi-Source Aggregation – Fetches from 13 verified working security sources in parallel
- 📂 Auto-Categorization – Organizes articles into 7 security categories with emoji
- 🚫 Deduplication – Removes duplicate articles from the same day
- 📰 Slack-Ready Format – Professional newspaper layout for Slack delivery
- ⏰ Flexible Scheduling – Run daily via system cron or on-demand
- 📊 Rich Logging – Detailed activity logs for debugging and monitoring
- ⚙️ Fully Configurable – Customize sources, categories, timing via
config.yaml
- Python 3.8+
- Slack Workspace with webhook capability
- Internet Connection for fetching RSS feeds
git clone <repo>
cd security-newspaper
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt- Go to https://api.slack.com/apps
- Click "Create New App" (or select existing)
- Enable "Incoming Webhooks"
- Create a new webhook and copy the URL
- Export as environment variable:
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"Tip
Save this to your shell profile (.bashrc, .zshrc, etc.) to persist across sessions.
python -m src.main --nowExpected output:
- Articles fetched from 13 sources ✓
- Articles organized into 7 sections ✓
- Newspaper message posted to Slack ✓
- Logs saved to
logs/newspaper.log✓
Set up automatic daily runs using system cron:
crontab -eAdd this line (runs every weekday at 9 AM):
0 9 * * 1-5 cd /path/to/security-newspaper && SLACK_WEBHOOK_URL="your-webhook-url" /path/to/venv/bin/python -m src.main --now >> logs/cron.log 2>&1Verify the cron job:
crontab -l | grep security-newspaperNote
System cron is recommended over the Python daemon mode for reliability. It ensures the job continues running indefinitely without process crashes or state accumulation issues.
# Run immediately (don't wait for schedule)
python -m src.main --now
# Test with fake data (doesn't hit real feeds)
python -m src.main --now --test
# Preview output without sending to Slack
python -m src.main --now --dry-run
# Use a different config file
python -m src.main --config custom-config.yaml
# Start background daemon (not recommended for production)
python -m src.main# Watch logs in real-time
tail -f logs/newspaper.log
# Check for errors
grep ERROR logs/newspaper.log
# Search for specific source
grep "BleepingComputer" logs/newspaper.logAll settings are in config.yaml. Most defaults work, but you can customize:
schedule:
cron: "0 9 * * 1-5" # Runs every weekday at 9 AM
timezone: "Europe/Berlin" # Your timezone
lookback_hours: 24 # Fetch articles from last 24 hours
max_items_per_section: 5 # Max articles per category
slack:
webhook_url: "${SLACK_WEBHOOK_URL}" # Read from environment
newspaper_name: "Security Gazette" # Name shown in Slack
show_sources_count: true # Display source count in header13 Verified & Active Sources:
| Tier | Source | Description |
|---|---|---|
| Government | CISA Alerts | US government cybersecurity advisories |
| Security Research | Krebs on Security | Deep-dive breach investigations |
| Security Research | Recorded Future | Advanced threat intelligence |
| Security Research | Microsoft Security Blog | Microsoft security advisories & research |
| Enterprise Security | SANS ISC | Daily threat summaries & analysis |
| Enterprise Security | Dark Reading | Enterprise security news |
| Enterprise Security | CrowdStrike Blog | Threat intelligence & incident response |
| Threat Intelligence | Bleeping Computer | Malware, ransomware & security news |
| Threat Intelligence | Threatpost | Vulnerability & threat analysis |
| Threat Intelligence | Help Net Security | Cybersecurity research & insights |
| Tech & General | TechCrunch Security | Breaking tech security incidents |
| Tech & General | Ars Technica | In-depth tech & security analysis |
| Executive News | CSO Online | Chief Security Officer news & trends |
Note
All 13 sources are tested, active, and verified to fetch articles regularly.
Customize keywords and emoji for the 7 security categories in config.yaml:
- 🔍 Threat Intelligence – APT activity, security research
- 🐛 Vulnerabilities – CVE announcements, exploits
- 🚨 Data Breaches – Corporate breaches, incidents
- 💀 Ransomware & Malware – New malware families, campaigns
- 🏛️ Industry & Policy – Regulations, government updates
- 🔧 Tools & Techniques – New security tools, methods
- 📢 Advisories – Security patches, recommendations
The system follows this pipeline:
Fetch Articles (13 sources) → Deduplicate → Categorize
↓
Format for Slack → Send to Webhook → Log Results
Process:
- Fetch – Downloads articles from 13 RSS feeds simultaneously
- Deduplicate – Removes articles already sent today
- Classify – Organizes into 7 security categories using keywords
- Format – Converts to Slack-readable newspaper layout
- Publish – Sends message to Slack webhook
- Log – Records all activity for troubleshooting
security-newspaper/
├── config.yaml # Main configuration
├── requirements.txt # Python dependencies
├── README.md # This file
│
├── src/ # Application code
│ ├── main.py # Entry point & CLI
│ ├── config.py # Config loader
│ ├── models.py # Data structures
│ ├── fetcher.py # Fetch articles
│ ├── deduplicator.py # Remove duplicates
│ ├── classifier.py # Categorize articles
│ ├── formatter.py # Format for Slack
│ ├── publisher.py # Send to Slack
│ └── orchestrator.py # Run pipeline
│
├── test/ # Testing utilities
│ ├── mock_sources.py # Fake articles for testing
│ └── __init__.py
│
└── logs/ # Runtime logs
└── newspaper.log # Main log file
Technologies:
APScheduler– Handles scheduled runsfeedparser– Parses RSS feedsrequests– Sends to SlackPyYAML– Reads configuration
Check what's happening:
python -m src.main --now --dry-run
tail -f logs/newspaper.log | grep ERRORTry test mode:
python -m src.main --now --testVerify sources:
- Is each source enabled in
config.yaml? - Is your internet connection working?
- Are the RSS URLs accessible (not blocked)?
Verify webhook:
echo $SLACK_WEBHOOK_URL
# Should print: https://hooks.slack.com/services/...Test webhook directly:
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Test message"}' \
$SLACK_WEBHOOK_URLCheck logs:
tail -f logs/newspaper.log | grep -i "slack"- Open
config.yaml - Find the
sectionsarea - Update keywords and regex patterns
- Test with
python -m src.main --now --dry-run
Verify cron is set:
crontab -lCheck system logs (macOS):
log show --predicate 'eventMessage contains "newspaper"' --last 1hTest manually:
cd /path/to/security-newspaper && python -m src.main --nowNote: System cron may not inherit environment variables. Ensure SLACK_WEBHOOK_URL is set in the cron entry or passed via .env file.
We welcome contributions! Please help improve Security Newspaper.
For major features:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
Open an Issue for:
- 🐛 Bug reports or code problems
- ✨ Feature requests
- ❓ Questions or usage clarification
- 💡 Minor improvements or suggestions
Q: Can I add my own news source?
A: Yes! Add the RSS feed URL to config.yaml in the sources section.
Q: How often can it run?
A: As often as you want. Adjust the cron expression in config.yaml. Default is weekdays at 9 AM.
Q: Does it remove duplicates across different days?
A: No, duplicates are only removed within the same day by design.
Q: Can I customize categories?
A: Yes! Edit the sections in config.yaml to add, remove, or modify categories and keywords.
Q: What Python versions are supported?
A: Python 3.8+. Check your version with python --version.
MIT License – See LICENSE file for details.
Have questions? Check logs with tail -f logs/newspaper.log or open an Issue.