Named after Rankle, Master of Pranks from Magic: The Gathering - a legendary faerie who excels at uncovering secrets.
A comprehensive web infrastructure analyzer using 100% Open Source Python libraries with no API keys required.
Features: Modular architecture with centralized configuration, retry logic, and concurrent scanning!
Rankle follows Python 3.11+ best practices with modern packaging:
rankle/
βββ pyproject.toml # Modern Python packaging (PEP 621)
βββ main.py # Entry point
βββ rankle/ # Main package
β βββ core/ # Scanner & session management
β β βββ scanner.py # RankleScanner - orchestrates all modules
β β βββ session.py # SessionManager - HTTP with retry logic
β βββ modules/ # Reconnaissance modules
β β βββ dns.py # DNS enumeration
β β βββ ssl.py # TLS/SSL certificate analysis
β β βββ subdomains.py # Subdomain discovery via CT logs
β β βββ whois.py # WHOIS lookup
β β βββ geolocation.py # IP geolocation & cloud detection
β β βββ http_fingerprint.py # HTTP fingerprinting (concurrent)
β β βββ security_headers.py # Security headers analysis
β βββ detectors/ # Technology detectors
β β βββ technology.py # CMS, frameworks, libraries detection
β β βββ cdn.py # CDN detection (20+ providers)
β β βββ waf.py # WAF detection (15+ solutions)
β β βββ origin.py # Origin discovery behind CDN/WAF
β βββ utils/ # Utilities
β β βββ validators.py # Domain/IP validation
β β βββ helpers.py # JSON save, truncate utilities
β β βββ rate_limiter.py # Request rate limiting
β βββ reports/ # Report generation
βββ config/ # Configuration
β βββ settings.py # Timeouts, User-Agent, DNS servers
β βββ patterns.py # Cloud providers, subdomains, ASN patterns
β βββ tech_signatures.json # Technology detection signatures
βββ tests/ # Unit tests (pytest)
Standards Compliance:
- β Python 3.11+ compatible (tested on 3.11, 3.12, 3.13)
- β
PEP 621 - Modern packaging with
pyproject.toml - β PEP 517/518 - Build system specification
- β Type hints - Full typing support
- β Ruff formatted - Code style consistency (replaces Black, isort, flake8)
Benefits: Better collaboration, easier testing, cleaner code, extensible architecture.
- π¬ Enhanced Technology Detection - Confidence scoring (0-100%), version detection, 30+ technologies with signature-based identification
- Enhanced CMS Detection - 16+ systems including Drupal (15+ patterns), WordPress, Joomla, Magento, TYPO3, Concrete5
- Advanced Fingerprinting - 8 techniques: HTTP methods, server versions, API discovery, exposed files, cookies, error pages, headers, response timing
- Cloud Provider Detection - 14+ providers: AWS, Azure, GCP, DigitalOcean, OVH, Hetzner, Linode, Vultr, Alibaba, Oracle, IBM, Scaleway
- Origin Infrastructure Discovery - Find real servers behind WAF/CDN using 5 passive techniques (MX, SPF, subdomains, SSL SANs, patterns)
- CDN Detection - 20+ providers: TransparentEdge, Cloudflare, Akamai, Fastly, Azure, Google Cloud, MaxCDN
- WAF Detection - 15+ solutions: Imperva, Sucuri, ModSecurity, PerimeterX, DataDome, F5 BIG-IP
- API Endpoint Discovery - Automatic detection of /api, /graphql, /swagger, /actuator, /health, and 15+ common endpoints
- DNS Enumeration - Complete configuration analysis (A, AAAA, MX, NS, TXT, SOA, CNAME)
- Subdomain Discovery - Via Certificate Transparency logs (crt.sh)
- JavaScript Libraries - Detect 15+ libraries: jQuery, Bootstrap, React, Vue, Angular, D3.js
- TLS/SSL Analysis - Certificate inspection, cipher suites, protocol versions
- Security Headers - HTTP security headers audit
- WHOIS Lookup - Enhanced with fallback methods
- Geolocation - Hosting provider and geographic information with reverse DNS
- Export Options - JSON (machine-readable) and text (human-readable) formats
- Centralized Configuration: Cloud providers, subdomains, and ASN patterns in
config/patterns.py - Automatic Retry Logic: HTTP requests with exponential backoff (429, 500, 502, 503, 504)
- Concurrent Scanning: ThreadPoolExecutor for parallel path checking (~60-70% faster)
- Connection Pooling: Optimized HTTP sessions with 10 connections, 20 max pool size
- Enhanced Technology Detection: Confidence scoring (0-100%), version detection, 30+ technologies
- Quick Start
- Installation
- Usage
- Output Formats
- Detection Capabilities
- Integration Examples
- Version History
- Repository Information
- Security & Best Practices
- Contributing
- License
# Install dependencies
pip install -r requirements.txt
# Run scan (prints to terminal only)
python main.py example.com
# Save results to file
python main.py example.com -o json # Save JSON
python main.py example.com -o text # Save text report
python main.py example.com -o both # Save both formats
# Verbose output
python main.py example.com -v# Build locally
docker build -t rankle .
docker run --rm rankle example.compython main.py example.com
# Expected output:
# CMS: Drupal
# CDN: TransparentEdge
# WAF: TransparentEdge WAF- Python 3.11+
- Docker (optional, for containerized usage)
# Required libraries
pip install requests dnspython beautifulsoup4
# Optional (enhanced features)
pip install python-whois
# Or install all at once
pip install -r requirements.txt
# For development (includes linting, formatting, pre-commit)
pip install -r requirements.txt
pre-commit install# Clone repository
git clone https://github.com/javicosvml/rankle.git
cd rankle
# Build Docker image
docker build -t rankle .
# Image size: ~370MB (Alpine-based with all dependencies)
# Note: Runs as non-root user (rankle:1000) for enhanced securityRankle's Docker image implements security best practices:
- Non-root User: Runs as dedicated
rankleuser (UID 1000) instead of root - Healthcheck: Built-in health monitoring for container orchestrators
- OCI Metadata: Complete OCI-compliant image annotations
- Minimal Base: Alpine Linux for reduced attack surface
- No Privileged Ports: No exposed ports required
# Clone repository
git clone https://github.com/javicosvml/rankle.git
cd rankle
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Run
python main.py example.com# Basic scan (terminal output only - default)
python main.py example.com
# Save as JSON (for automation)
python main.py example.com -o json
# Save as text report (human-readable)
python main.py example.com -o text
# Save both formats
python main.py example.com -o both
# Verbose output (show debug info)
python main.py example.com -v
# Show help
python main.py --help# Basic scan (terminal output only)
docker run --rm rankle example.com
# Save JSON output
docker run --rm -v $(pwd)/output:/output rankle example.com -o json
# Save text report
docker run --rm -v $(pwd)/output:/output rankle example.com -o text
# Save both formats
docker run --rm -v $(pwd)/output:/output rankle example.com -o both
# Interactive mode
docker run --rm -it rankle example.com-o, --output TYPE Save output to file (json/text/both)
If not specified, only prints to terminal
-v, --verbose Enable verbose output with debug info
--output-dir PATH Output directory (default: ./output)
--version Show version number
-h, --help Show help message
Purpose: Machine-readable structured data for automation and integration
Use Cases:
- Automated processing with
jq - Integration with security tools (Nuclei, Nmap, Metasploit)
- Database storage (PostgreSQL JSONB, Elasticsearch)
- Comparison and monitoring (diff between scans)
- Pipeline integration (SIEM/SOAR)
Example:
# Extract IPs
cat scan.json | jq -r '.dns.A[]'
# Count subdomains
cat scan.json | jq '.subdomains | length'
# Get detected CMS
cat scan.json | jq -r '.technologies_web.cms'
# Feed subdomains to other tools
cat scan.json | jq -r '.subdomains[]' | nuclei -l -Purpose: Human-readable technical report
Characteristics:
- Compact, technical format
- Section-based layout
- grep/awk friendly
- Quick manual review
Structure:
DOMAIN: example.com
SCAN_TIME: 2025-11-12 02:00:00
STATUS: 200
[INFRASTRUCTURE] - IPs, DNS, geolocation, ISP
[TECHNOLOGY] - CMS, frameworks, server software
[SECURITY] - TLS, certificates, headers, CDN/WAF
[SUBDOMAINS] - Certificate transparency results
[WHOIS] - Registration information
[DNS_RECORDS] - TXT, SPF records
Example:
# Extract security section
grep -A 10 "^\[SECURITY\]" report.txt
# Filter subdomains
awk '/^\[SUBDOMAINS\]/,/^\[/' report.txt | grep -v "^\["- 15+ detection patterns:
/core/misc/drupal.js,/user/login,/sites/default/ - HTML attributes:
data-drupal-*,views-,block-,node- - robots.txt analysis
- Meta generator tags
- Successfully detects Drupal even behind WAF protection
- WordPress (wp-content, wp-includes, wp-json)
- Joomla (option=com_, joomla!)
- Magento (mage/cookies, skin/frontend)
- Shopify (cdn.shopify.com)
- TYPO3 (typo3conf)
- Concrete5 (ccm_)
- ModX, Wix, Squarespace, Ghost, Hugo, Jekyll, Webflow, PrestaShop, OpenCart
Detection Methods:
- ASN (Autonomous System Number) matching
- ISP/Organization name patterns
- Reverse DNS hostname analysis
- Confidence scoring (low/medium/high)
Supported Providers:
- AWS (Amazon Web Services) - AS16509, AS14618, AS8987
- Azure (Microsoft Azure) - AS8075, AS8068
- GCP (Google Cloud Platform) - AS15169, AS19527, AS396982
- DigitalOcean - AS14061
- OVH - AS16276
- Hetzner - AS24940
- Linode (Akamai) - AS63949
- Vultr - AS20473
- Cloudflare - AS13335
- Akamai - AS20940, AS16625
- Alibaba Cloud - AS45102, AS37963
- Oracle Cloud - AS31898, AS792
- IBM Cloud / Softlayer - AS36351
- Scaleway - AS12876
- TransparentEdge (tp-cache, tedge, edge2befaster) - Enhanced with 6 indicators
- Cloudflare (cf-ray, cloudflare)
- Akamai (akamaighost, edgesuite, edgekey)
- Fastly (x-fastly, x-timer)
- Amazon CloudFront (x-amz-cf, x-cache)
- Azure CDN (azureedge)
- Google Cloud CDN
- MaxCDN, CDN77, KeyCDN, StackPath, BunnyCDN, Netlify, jsDelivr
- Varnish (x-varnish, via headers)
- TransparentEdge WAF (Voight-Kampff test detection)
- Cloudflare WAF / Bot Management
- Imperva/Incapsula (visid_incap)
- PerimeterX (_px, px-)
- DataDome
- Sucuri WAF (cloudproxy)
- ModSecurity
- AWS WAF (x-amzn-waf)
- F5 BIG-IP ASM (bigip, f5-trace)
- Fortinet FortiWeb
- Barracuda, Reblaze, Wallarm, Radware, Citrix NetScaler, Wordfence
- jQuery, Bootstrap
- React, Vue, Angular
- D3.js, Three.js, Chart.js
- Axios, Lodash, Moment.js
- Swiper, Slick
- AOS, GSAP
- Modernizr, Popper.js
Purpose: Find real infrastructure behind WAF/CDN protection
Passive Detection Methods:
- Subdomain Analysis - Check non-CDN subdomains (origin, direct, admin, mail, ftp, vpn, cpanel)
- MX Records - Mail servers often reveal origin network/ASN
- SPF/TXT Records - Parse SPF records for authorized IP ranges (ip4: directives)
- SSL Certificate SANs - Analyze Subject Alternative Names for direct-access domains
- Common Patterns - Test predictable origin domains (origin., direct., admin., backend., api.*)
Example Output:
π― ORIGIN INFRASTRUCTURE (Behind WAF/CDN)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Detection Methods: mx_records, spf_records, pattern_discovery
Origin IPs Found: 4
Origin Hosting:
β’ 148.163.154.111 β AWS (high confidence)
β’ 148.163.150.174 β AWS (high confidence)
Direct Access Domains (1 found):
β’ api.example.com
Use Cases:
- Penetration testing (authorized)
- Security research
- Infrastructure analysis
- Attack surface mapping
- Competitor analysis
Ethical Considerations:
β οΈ All methods are passive and use public DNS/SSL data- β No active attacks or unauthorized access attempts
- β Complies with responsible disclosure practices
- β Do not use for unauthorized security testing
8 Advanced Techniques to identify infrastructure:
- Tests: OPTIONS, HEAD, TRACE, PUT, DELETE, PATCH
- Identifies: Misconfigurations, API capabilities, server behavior
- Example:
api.example.comallows OPTIONS, HEAD, TRACE, PUT, DELETE, PATCH
- Extracts version numbers from Server/X-Powered-By headers
- Pattern matching for: Apache, Nginx, IIS, LiteSpeed, Tomcat, Node.js, Express
- Example:
Server: nginx/1.21.6β Nginx version 1.21.6
- Probes 15+ common endpoints:
- REST APIs:
/api,/api/v1,/api/v2,/rest - GraphQL:
/graphql - Documentation:
/swagger,/api-docs,/openapi.json - Health checks:
/health,/status,/metrics,/actuator - Configuration:
/config.json,/.well-known/security.txt - CMS:
/wp-json,/api/users
- REST APIs:
- Reports: endpoint, status code, content-type
- Checks for common security issues:
- Development files:
/phpinfo.php,/info.php - Version control:
/.git/config,/.git/HEAD,/.svn/entries - Configuration:
/.htaccess,/web.config,/.env - Dependencies:
/composer.json,/package.json,/yarn.lock - Backups:
/backup.sql,/database.sql - System files:
/.DS_Store
- Development files:
β οΈ Security Risk: Reports exposed files
- Analyzes cookie names to identify technologies:
PHPSESSIDβ PHPJSESSIONIDβ Java/TomcatASP.NET_SessionIdβ ASP.NET__cfduidβ Cloudflare_gaβ Google Analyticswordpress_*β WordPressdrupalβ Drupal
- Checks security attributes: Secure, HttpOnly, SameSite
- Analyzes 404/error pages to identify:
- Web Servers: Apache, Nginx, IIS, Tomcat
- Frameworks: Django, Flask, Express, Rails
- Example: Django error pages reveal "DisallowedHost" and framework version
- Detects headers that reveal infrastructure:
X-AspNet-Versionβ ASP.NET versionX-Drupal-Cacheβ Drupal CMSX-Varnishβ Varnish cachingX-Nginx-Cache-Statusβ Nginx cachingCF-Cache-Statusβ CloudflareX-Amz-Cf-Idβ Amazon CloudFrontX-Azure-Refβ Microsoft Azure
- Measures server response time in milliseconds
- Can indicate:
- Server location (latency)
- Server load
- Caching status
- Example: 40ms (fast, likely cached or nearby)
Example Output:
π¬ ADVANCED FINGERPRINTING
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Server Versions:
β’ Nginx: 1.21.6
Allowed HTTP Methods: OPTIONS, HEAD, TRACE, PUT, DELETE, PATCH
Discovered API Endpoints (2):
β’ /graphql [403] - application/json
β’ /status [200] - text/plain
Technology from Cookies:
β’ Google Analytics
Response Time: 40.60ms
- TLS/SSL: Certificate analysis, cipher suites, protocol versions
- Security Headers: X-Frame-Options, CSP, HSTS, X-XSS-Protection, etc.
- DNS Records: A, AAAA, MX, NS, TXT, SOA, CNAME
- Subdomains: Certificate Transparency log mining
- WHOIS: Enhanced with socket fallback for reliability
- Geolocation: ISP, ASN, country, city
# Direct subdomain pipe
python main.py example.com --output json | \
jq -r '.subdomains[]' | \
nuclei -l - -t nuclei-templates/
# Technology-based scanning
CMS=$(cat scan.json | jq -r '.technologies_web.cms' | cut -d' ' -f1 | tr '[:upper:]' '[:lower:]')
cat scan.json | jq -r '.subdomains[]' | \
nuclei -l - -t nuclei-templates/$CMS/# Scan all discovered IPs
cat scan.json | jq -r '.dns.A[]' | nmap -iL - -sV -oA nmap_scan
# IPv6 scan
cat scan.json | jq -r '.dns.AAAA[]' | nmap -6 -iL - -sV
# Targeted port scanning based on detected services
cat scan.json | jq -r '.dns.A[]' | \
nmap -iL - -p 80,443,8080,8443 -sV --script=http-enum# Verify live hosts before scanning
cat scan.json | jq -r '.subdomains[]' | \
httpx -silent | \
nuclei -l -#!/bin/bash
DOMAIN=$1
OUTPUT_DIR="recon_${DOMAIN}"
# 1. Rankle reconnaissance
python main.py $DOMAIN --output json
# 2. Extract and verify subdomains
cat ${DOMAIN/./_}_rankle.json | jq -r '.subdomains[]' | \
httpx -silent -o ${OUTPUT_DIR}/live_subdomains.txt
# 3. Port scanning on live hosts
nmap -iL ${OUTPUT_DIR}/live_subdomains.txt -oA ${OUTPUT_DIR}/nmap_results
# 4. Vulnerability scanning with Nuclei
nuclei -l ${OUTPUT_DIR}/live_subdomains.txt \
-t nuclei-templates/ \
-o ${OUTPUT_DIR}/nuclei_results.txt
# 5. Generate report
echo "Reconnaissance complete for ${DOMAIN}"- β Modular Architecture - Separated modules for DNS, SSL, subdomains, detection
- β
Centralized Configuration -
config/patterns.pywith cloud providers, subdomains, ASN patterns - β Automatic Retry Logic - Exponential backoff for transient HTTP errors (429, 5xx)
- β Concurrent Scanning - ThreadPoolExecutor for parallel path checking
- β Connection Pooling - Optimized HTTP sessions (10 connections, 20 pool size)
- β Code Quality - Ruff linting, mypy type checking, pre-commit hooks
- Complete DNS enumeration (A, AAAA, MX, NS, TXT, SOA, CNAME)
- Subdomain discovery via Certificate Transparency
- Technology detection with confidence scoring (CMS, frameworks, libraries)
- TLS/SSL certificate analysis
- HTTP security headers audit
- CDN Detection (20+ providers)
- WAF Detection (15+ solutions)
- Origin infrastructure discovery (passive techniques)
- Geolocation and cloud provider detection
- WHOIS lookup with fallback methods
- JSON and text export formats
rankle/
βββ main.py # Entry point
βββ rankle/ # Main package (modular architecture)
β βββ core/ # Scanner & session management (with retry logic)
β βββ modules/ # Reconnaissance modules (concurrent scanning)
β βββ detectors/ # Technology detectors (CDN, WAF, origin)
β βββ utils/ # Utilities, validators, rate limiter
βββ config/ # Configuration & centralized patterns
β βββ settings.py # Timeouts, headers, DNS servers
β βββ patterns.py # Cloud providers, subdomains, ASN data
βββ tests/ # Unit tests (pytest)
βββ requirements.txt # Python dependencies
βββ pyproject.toml # Modern Python packaging (PEP 621)
βββ Dockerfile # Alpine-based container (~370MB, non-root user)
βββ README.md # This file
βββ CHANGELOG.md # Detailed version history
βββ LICENSE # MIT License
βββ SECURITY.md # Security policy
βββ CONTRIBUTING.md # Contribution guidelines
βββ .gitignore # Git exclusions
βββ .dockerignore # Docker build exclusions
βββ .pre-commit-config.yaml # Pre-commit hooks (ruff, mypy, bandit)
βββ .github/
β βββ workflows/
β βββ docker-build.yml # CI/CD automation
βββ examples/ # Integration scripts
# Clone repository
git clone https://github.com/javicosvml/rankle.git
cd rankle
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
pre-commit install
# Test your changes
python main.py example.com
# Commit and push
git add .
git commit -m "Description of changes"
git push# Create and push a tag
git tag -a v1.2.0 -m "Release v1.2.0 - New features"
git push origin v1.2.0
# Or use GitHub CLI
gh release create v1.2.0 --title "v1.2.0" --notes "Release notes here"Rankle implements several security measures:
- No shell injection - Never uses
shell=True - Input validation - Regex-based domain validation
- Timeout controls - Prevents hanging requests
- Error handling - Graceful degradation on failures
- Realistic User-Agent - Stealth reconnaissance
- Bot protection awareness - Handles WAF challenges
Authorized Use Only:
- β Authorized penetration testing
- β Bug bounty programs (with permission)
- β Security research (on your own systems)
- β Educational purposes
Prohibited Use:
- β Unauthorized access attempts
- β Malicious reconnaissance
- β Illegal activities
- β Violating terms of service
- Always obtain proper authorization before scanning any target
- Respect rate limits and server resources
- Implement delays for large-scale scans
- Use realistic headers to avoid detection
- Check robots.txt and respect directives
- Handle data securely especially when containing sensitive information
- Comply with laws and regulations in your jurisdiction
Rankle uses a modular architecture with specialized classes:
Main orchestrator class that coordinates all reconnaissance modules.
from rankle.core.scanner import RankleScanner
# Basic usage
with RankleScanner("example.com", verbose=True) as scanner:
results = scanner.run_full_scan()
# Methods:
# - run_full_scan() -> dict[str, Any] # Execute all modules
# - close() # Cleanup resourcesHTTP session with automatic retry and connection pooling.
from rankle.core.session import SessionManager
with SessionManager(timeout=45, retries=3) as session:
response = session.get("https://example.com")
# Features:
# - Exponential backoff for 429, 500, 502, 503, 504
# - Connection pooling (10 connections, 20 max)
# - Realistic browser headers| Module | Class | Description |
|---|---|---|
dns.py |
DNSAnalyzer |
DNS enumeration (A, AAAA, MX, NS, TXT, SOA, CNAME) |
ssl.py |
SSLAnalyzer |
TLS/SSL certificate analysis |
subdomains.py |
SubdomainDiscovery |
Subdomain discovery via Certificate Transparency |
whois.py |
WHOISLookup |
WHOIS lookup with fallback methods |
geolocation.py |
GeolocationLookup |
IP geolocation & cloud provider detection |
http_fingerprint.py |
HTTPFingerprinter |
HTTP fingerprinting (concurrent) |
security_headers.py |
SecurityHeadersAuditor |
Security headers audit |
| Detector | Class | Description |
|---|---|---|
technology.py |
TechnologyDetector |
CMS, frameworks, libraries detection |
cdn.py |
CDNDetector |
CDN detection (20+ providers) |
waf.py |
WAFDetector |
WAF detection (15+ solutions) |
origin.py |
OriginDiscovery |
Origin infrastructure discovery |
| File | Description |
|---|---|
settings.py |
Timeouts, User-Agent, DNS servers, rate limits |
patterns.py |
Cloud providers, subdomains, ASN patterns (centralized) |
tech_signatures.json |
Technology detection signatures |
Contributions are welcome! Please see CONTRIBUTING.md for detailed guidelines.
High Priority:
- Additional CMS fingerprints (Django, Laravel, Rails)
- More CDN providers (regional CDNs)
- Enhanced WAF detection patterns
- Version detection improvements
- Performance optimizations
Medium Priority:
- Additional JavaScript library detection
- Server-side technology detection
- Database detection (via error messages)
- Framework detection (Flask, FastAPI, Express)
- API detection
Documentation:
- Usage examples
- Integration guides
- Video tutorials
- Translations
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Test:
python main.py example.com - Commit:
git commit -m "Add: Amazing feature" - Push:
git push origin feature/amazing-feature - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
This tool is provided for educational and authorized security testing purposes only.
Users must:
- Obtain proper authorization before scanning any target
- Comply with all applicable laws and regulations
- Use the tool responsibly and ethically
- Not use it for malicious purposes
The authors and contributors are not responsible for any misuse or damage caused by this software. Unauthorized access to computer systems is illegal.
- Named after Rankle, Master of Pranks from Magic: The Gathering
- Built with 100% Open Source libraries
- No API keys required
- Community-driven development
- Issues: GitHub Issues
- Pull Requests: GitHub PRs
- Security: See SECURITY.md for vulnerability reporting
- Discussions: GitHub Discussions
- Repository: https://github.com/javicosvml/rankle
- Documentation: https://github.com/javicosvml/rankle/blob/main/README.md
- Changelog: https://github.com/javicosvml/rankle/blob/main/CHANGELOG.md
- License: https://github.com/javicosvml/rankle/blob/main/LICENSE