threat-intel: Comprehensive Threat Intelligence Framework for Rust
Red Asgard's threat-intel provides multi-source threat aggregation, CVE integration, and automated risk assessment for security operations teams.
threat-intel: Comprehensive Threat Intelligence Framework
Security operations require real-time threat intelligence from multiple sources. threat-intel is Red Asgard's open-source Rust framework for aggregating, analyzing, and acting on threat data.
Package: threat-intel on crates.io
Repository: github.com/redasgard/threat-intel
License: MIT
Version: 0.1.0
Downloads: 174+
The Problem: Fragmented Threat Intelligence
Security teams face information overload:
Multiple Data Sources:
- CVE databases (NVD, MITRE)
- Threat feeds (AlienVault OTX, abuse.ch)
- OSINT (Twitter, Telegram, forums)
- Vendor advisories
- Internal telemetry
Integration Challenges:
- Different formats and APIs
- Inconsistent data quality
- No unified schema
- Manual correlation required
- Alert fatigue from duplicates
Analysis Gaps:
- Relevant vs noise filtering
- Risk scoring inconsistency
- No automated enrichment
- Slow incident response
Solution: Unified Threat Intelligence Platform
1. Multi-Source Aggregation
use threat_intel::{ThreatIntel, sources::*};
let ti = ThreatIntel::builder()
.add_source(NvdSource::new(api_key))
.add_source(MitreAttackSource::new())
.add_source(AbuseIpDb::new(api_key))
.add_source(OtxAlienVault::new(api_key))
.build()?;
// Fetch indicators from all sources
let indicators = ti.fetch_all().await?;
2. CVE Integration
use threat_intel::cve::{CveClient, Severity};
let client = CveClient::new()?;
// Query CVEs
let recent_critical = client
.query()
.severity(Severity::Critical)
.published_after("2025-10-01")
.fetch()
.await?;
for cve in recent_critical {
println!("CVE-{}: {} (CVSS: {})",
cve.id,
cve.description,
cve.cvss_score
);
}
3. Automated Risk Assessment
use threat_intel::risk::{RiskAssessor, Context};
let assessor = RiskAssessor::new();
let context = Context {
asset_criticality: Criticality::High,
exposure: Exposure::Internet,
existing_controls: vec!["WAF", "IDS"],
};
let risk = assessor.assess_vulnerability(&cve, &context)?;
match risk.level {
RiskLevel::Critical => emergency_patch(),
RiskLevel::High => schedule_patch(24.hours()),
RiskLevel::Medium => schedule_patch(7.days()),
RiskLevel::Low => add_to_backlog(),
}
Core Features
Threat Feed Sources
Built-in Integrations:
- NVD (National Vulnerability Database)
- MITRE ATT&CK
- AlienVault OTX
- abuse.ch (malware, botnet, ransomware)
- VirusTotal
- Shodan
- URLhaus
- ThreatFox
Custom Sources:
use threat_intel::sources::Source;
struct CustomFeed {
api_client: HttpClient,
}
#[async_trait]
impl Source for CustomFeed {
async fn fetch_indicators(&self) -> Result<Vec<Indicator>> {
// Your custom logic
}
}
ti.add_source(CustomFeed::new());
Indicator Types
pub enum Indicator {
IpAddress { ip: IpAddr, reputation: i8, tags: Vec<String> },
Domain { domain: String, malicious: bool, category: ThreatCategory },
FileHash { hash: Hash, malware_family: Option<String> },
Url { url: Url, phishing: bool, category: ThreatCategory },
Email { email: String, spam: bool },
Cve { id: String, severity: Severity, exploited: bool },
Certificate { hash: String, revoked: bool },
}
Enrichment Pipeline
use threat_intel::enrichment::*;
let enriched = ti
.enrich_indicator(&ip_address)
.with_geolocation()
.with_reverse_dns()
.with_asn_lookup()
.with_reputation_check()
.with_historical_activity()
.execute()
.await?;
println!("IP {} is in {}, ASN: {}, Reputation: {}/100",
enriched.ip,
enriched.country,
enriched.asn,
enriched.reputation_score
);
Use Cases
1. Security Operations Center (SOC)
use threat_intel::ThreatIntel;
#[tokio::main]
async fn main() {
let ti = ThreatIntel::new().await;
// Monitor for new threats
ti.subscribe_to_feed("cve-critical").await;
while let Some(alert) = ti.next_alert().await {
match alert.severity {
Severity::Critical => {
notify_team(&alert);
create_incident(&alert);
}
_ => log_for_review(&alert),
}
}
}
2. Incident Response
use threat_intel::investigation::*;
async fn investigate_suspicious_ip(ip: IpAddr) -> InvestigationReport {
let ti = ThreatIntel::new().await;
let report = ti.investigate()
.target(ip)
.check_reputation()
.check_malware_distribution()
.check_c2_communication()
.check_scanning_activity()
.get_historical_incidents()
.execute()
.await?;
report
}
3. Vulnerability Management
use threat_intel::vuln::{VulnerabilityScanner, Asset};
let scanner = VulnerabilityScanner::new();
let assets = vec![
Asset::new("web-server-1", "nginx/1.18.0"),
Asset::new("db-server", "postgresql/13.0"),
];
for asset in assets {
let vulns = scanner.scan_asset(&asset).await?;
for vuln in vulns.filter(|v| v.exploited_in_wild) {
alert_security_team(&asset, &vuln);
}
}
Configuration
use threat_intel::{ThreatIntel, Config};
let config = Config {
// Data sources
enable_nvd: true,
enable_mitre: true,
enable_osint: true,
// API keys
nvd_api_key: env::var("NVD_API_KEY").ok(),
vt_api_key: env::var("VT_API_KEY").ok(),
// Caching
cache_ttl: Duration::hours(24),
cache_directory: "/var/cache/threat-intel",
// Filtering
min_severity: Severity::Medium,
relevant_cpes: vec!["cpe:2.3:a:nginx:*"],
// Performance
max_concurrent_requests: 10,
timeout: Duration::seconds(30),
};
let ti = ThreatIntel::with_config(config).await?;
Data Model
Structured Threat Data
pub struct ThreatIndicator {
pub id: String,
pub indicator_type: IndicatorType,
pub value: String,
pub confidence: f32, // 0.0 - 1.0
pub severity: Severity,
pub first_seen: DateTime,
pub last_seen: DateTime,
pub sources: Vec<String>,
pub tags: Vec<String>,
pub related_cves: Vec<String>,
pub iocs: Vec<IoC>,
}
pub struct Cve {
pub id: String, // CVE-2025-12345
pub description: String,
pub cvss_score: f32, // 0.0 - 10.0
pub severity: Severity,
pub published: DateTime,
pub modified: DateTime,
pub cwe: Vec<String>, // CWE-79, etc.
pub affected_products: Vec<Cpe>,
pub references: Vec<Url>,
pub exploited_in_wild: bool,
pub exploit_available: bool,
}
Performance
Throughput:
- 1,000+ CVE queries/second
- 10,000+ indicator lookups/second
- 100+ concurrent source fetches
Latency:
- Local cache hit: <1ms
- API call with cache miss: 50-500ms
- Full enrichment: 1-2 seconds
Resource Usage:
- Memory: ~50MB base + caches
- Disk: Configurable (cache size)
- CPU: Minimal (async I/O bound)
Deployment Patterns
Standalone Service
use threat_intel::server::ThreatIntelServer;
#[tokio::main]
async fn main() {
let server = ThreatIntelServer::new()
.bind("0.0.0.0:8080")
.with_api_auth(api_key)
.start()
.await?;
// REST API available at:
// GET /api/cve/{id}
// GET /api/indicator/{type}/{value}
// POST /api/enrich
}
Library Integration
// Integrate into existing Rust applications
use threat_intel::ThreatIntel;
let ti = ThreatIntel::new().await;
// Use in your security logic
if ti.is_malicious_ip(&client_ip).await? {
return Err("Blocked: IP on threat list");
}
Installation
[dependencies]
threat-intel = "0.1"
# With tracing
threat-intel = { version = "0.1", features = ["tracing"] }
cargo add threat-intel
Why Open Source?
Threat intelligence improves with community collaboration:
Benefits:
- Crowdsourced threat feeds
- Community validation
- Faster vulnerability coverage
- Broader platform support
Our Commitment:
- Regular updates with latest threats
- Security-first development
- Professional support available
About Red Asgard
threat-intel powers our security operations and client services. We're open-sourcing it to help the broader security community.
Related Open-Source Libraries:
- llm-security - AI/LLM protection
- path-security - Path traversal defense
- quantum-shield - Post-quantum crypto
- blockchain-runtime - Blockchain testing
- module-registry - Plugin architecture
Released: October 24, 2025
Version: 0.1.0
CVE Database: Up to date
Threat Feeds: 8+ sources integrated
Share this article
Help spread the word about security best practices.
Related Articles
A Fake Coding Interview Is an Execution Request: Developer Safety Checklist
A coding interview repo is a request to run unknown code on a machine that holds your browser sessions, SSH keys, GitHub tokens, and cloud credentials. This checklist covers what to check before the call, what to look for in the repo, and what to do if you already ran it.
Hunting Lazarus Part IX: The Google Mirror
Five trojanized browser extensions extracted Google profile identity through chrome.identity and routed it through an Aptos blockchain dead drop. Before any wallet artifact moved, the extension asked Chrome who owned the browser.
Need Security Help?
Our team can help secure your blockchain, web applications, and infrastructure.