Documentation / SwarmHack
Tuning & Troubleshooting
Operational Tuning
Parallelism
KillChainOrchestrator creates an agent-pool coordinator with a 64-slot semaphore. The 25→64 raise in v2.6.0 closed a deadlock against the 28-agent full-discovery fan-out. Not currently a CLI flag.
Rate limiting
GlobalRateLimiter::new(50, 50.0) — 50 concurrent in-flight requests, 50 req/s token bucket. Per-agent overrides read from config/swarmhack.yaml rate_limiting: block (default requests_per_second: 10, burst_size: 20). For WAF-friction targets, use the more conservative config/pentest_rate_limited.yaml (requests_per_second: 5, burst_size: 10) via --config.
Timeouts
Per-request HTTP timeouts floored at 10 s and capped at 30 s.
| Agent / vuln type | HTTP per-request (s) |
| --- | --- |
| SQLInjection | 20 |
| XSS, CSRF, IDOR, AuthBypass, WebCrawler, CommandInjection | 10 |
| HTTPSmuggling | 15 |
| DefaultCredentials, PrivilegeEscalation, LateralMovement | 30 |
| LdapSpray, LdapEnum, SmbEnum, KerberosAttack, Kerbrute, AuthCoercion, NtlmDowngrade, TLSVulnerability | 15 |
Adjust --timeout for the whole mission budget (default 3600 s).
GOAP planner
A* planner with a HashSet<WorldState> closed-set, parent-pointer path reconstruction, and goal-scoped action pruning. Opt in to A* for phase planning with --use-goap-planning.
Logging
Default: ./logs/{session-uuid}.jsonl, rotated at 100 MB, retained 30 days.
| Flag / env | Default | Effect |
| --- | --- | --- |
| --log-level <LVL> | info | trace, debug, info, warn, error. |
| --log-dir <PATH> | ./logs | Output directory. |
| --log-max-size-mb <N> | 100 | Rotate threshold. |
| --log-retention-days <N> | 30 | Compressed retention. |
| --log-file <PATH> | auto | Custom path. |
| --no-file-logging | off | Stdout only. |
| RUST_LOG | swarmhack=info | tracing-subscriber env filter; takes precedence over --log-level. |
Troubleshooting
| Symptom | Likely cause | Fix |
| --- | --- | --- |
| ERROR: Cannot Connect to Prancer Portal | Token expired, network blocked, wrong portal URL. | Re-issue token; verify --portal-url; check DNS / proxy. |
| ERROR: Invalid Token | Token is not 32 hex chars. | Copy the full token; strip whitespace. |
| ERROR: Invalid Customer | Wrong case or prancer- prefix. | Use the lowercase tenant slug (xforia, not XFORIA or prancer-xforia). |
| Exit status 2 immediately | No --authz-doc and no opt-out. | Pass --authz-doc <PATH>; or --authz-skip AND SWARMHACK_ALLOW_NO_AUTHZ=1. |
| Exit status 3 immediately | Target is not in authz-doc targets[]. | Add the host (label-strict). |
| Target '…' is public; --allow-public required | Non-RFC1918 / non-loopback target without the opt-in. | Pass --allow-public AND confirm the host is in authz-doc targets[]. |
| authz doc … expired | Doc expires_at past Now. | Reissue with a new expires_at ≤ 24 h ahead. |
| TLS handshake failures against a lab cert | Self-signed cert; default TLS verification. | Lab only: SWARMHACK_INSECURE_PREFLIGHT_TLS=1 SWARMHACK_INSECURE_BANNER_TLS=1. Never set in production. |
| Agent pool exhausted / mission stalls | Pre-v2.6.0 semaphore deadlock. | Upgrade to v2.6.0 — pool raised to 64, acquire_slot bounded at 30 s. |
| Mission completes with 0 findings | Well-hardened target, wrong agent set, aggressive WAF. | Try --agents crawler,sqli,xss; --rate-limit 5; use config/pentest_rate_limited.yaml. |
| agents that found nothing in summary | Correct behaviour — agents emit zero when nothing is exploitable. | No action; documented as a feature. |
| NTLM relay agent emits "skip" finding | Default-deny; --allow-ntlm-relay not set. | Confirm engagement letter authorises NTLM relay, then re-run with the flag. |
| ZerOlogon refuses host even with X8 bypass | Per-host scope gate (defence in depth). | Add the DC host to authz-doc targets[]. |
| Reports written but no SSE Markdown | --report does not list sse. | Pass --report sse; it auto-promotes to sse,ocsf,html. |
| swarmhack lint --pentest-mode exits 1 | Finding has no crown jewel or severity_id < 3. | Inspect the finding; upgrade evidence trail or accept the linter's invariant. |