Documentation
Reference
Architecture, profiles, CLI, env knobs, and the ownership-first security model.
Overview
Hackly is an orchestration layer for authorized attack-surface and
application security scanning. You inventory targets, prove ownership, run soft
rate-limited scanner jobs, and review normalized findings in Filament.
Target (verified)
└─ Scan
└─ ScanTasks → RunScanTaskJob → Findings
Jobs use the database queue (no Horizon). A queue worker must be
running for scans to execute.
Requirements
- PHP 8.3+
- Composer
- SQLite (default) or MySQL / PostgreSQL
- Node.js (optional — Vite assets; Filament ships published assets)
Default admin after seed: / · admin@hackly.test · password
Scanner binaries
Optional but recommended. Without them, related tasks fail gracefully and surface
missing-binary errors in the scan UI.
| Binary |
Used for |
| dig, whois |
DNS / WHOIS |
| nmap |
Ports |
| nuclei |
Templates & path discovery |
| zap.sh |
Deep DAST (OWASP ZAP) |
Ubuntu 24.04 / 26.04+
sudo bash scripts/install-scanner-binaries-ubuntu.sh
php artisan hackly:check-binaries
Usage
From the admin UI
- Open Targets → create a domain or IP
- Copy the DNS token → publish the TXT record at your DNS provider
- Verify DNS — must succeed before scanning
- Start scan — pick a profile; jobs dispatch immediately
- Watch Scans for live progress, open findings (HIGH → LOW), export the PDF
- On a target’s detail page, browse the related Scans table
From the CLI
php artisan hackly:scan example.com --profile=standard
Scan profiles
| Profile |
Tasks |
| quick |
dns_info, port_scan, tech_fingerprint |
| standard |
+ subdomain_enum, path_discovery, nuclei_owasp |
| deep |
+ zap_baseline (cooldown between deep runs on the same target) |
Findings are normalized to LOW / MEDIUM / HIGH and ordered by severity.
Commands
| Command |
Purpose |
| hackly:check-binaries |
Verify scanner binaries |
| hackly:scan {target} |
Create scan & dispatch jobs (--profile=) |
| hackly:cleanup-outputs |
Delete old raw scanner outputs |
| hackly:dispatch-due |
Re-dispatch leftover pending tasks |
| queue:work |
Process scan jobs |
Configuration
Primary config: config/hackly.php — override via .env.
QUEUE_CONNECTION=database
CACHE_STORE=database
# Safety
HACKLY_ALLOWLIST_ONLY=false
HACKLY_ALLOWLIST=example.com,203.0.113.10
HACKLY_ALLOW_PRIVATE_TARGETS=true
# Soft rate limits
HACKLY_PER_TARGET_PER_MINUTE=2
HACKLY_GLOBAL_CONCURRENT=5
HACKLY_JITTER_SECONDS=5
HACKLY_TASK_SPACING_SECONDS=10
HACKLY_DEEP_COOLDOWN_HOURS=24
HACKLY_QUIET_HOURS_ENABLED=false
# Job timeout must exceed longest scanner (ZAP ~900s)
HACKLY_JOB_TIMEOUT=960
DB_QUEUE_RETRY_AFTER=1020
# Binary paths
HACKLY_NMAP=nmap
HACKLY_NUCLEI=nuclei
# macOS: HACKLY_ZAP=/Applications/ZAP.app/Contents/Java/zap.sh
HACKLY_ZAP=zap.sh
Security model
- Scans require ownership verification (DNS TXT for domains)
- Optional allowlist and private-IP blocking
- Soft rate limits, jitter, task spacing, and quiet hours
- Deep profile has a cooldown between runs on the same target
- Admin accounts support TOTP and email multi-factor authentication
Hackly is an orchestration layer — it does not replace responsible disclosure policies
or scoped pentest agreements.
Production tips
- Set
HACKLY_ALLOW_PRIVATE_TARGETS=false
- Prefer
HACKLY_ALLOWLIST_ONLY=true with an explicit allowlist
- Configure real mail for email 2FA (
MAIL_MAILER=…)
- Change the seeded admin password immediately
- Run a persistent
queue:work (and optionally schedule:work for cleanup)
Source and issues:
github.com/andreapollastri/hackly