Documentation / SwarmHack

Authorization Model

Authorization Model

Every SwarmHack engagement enforces a two-layer safety contract. There are no exceptions for production targets.

Two layers

| Layer | Flags | Purpose |

| --- | --- | --- |

| Prancer Portal identity | --token <T> --customer <C> (optional --portal-url) | Authenticates the operator with Prancer's identity service. Token is a 32-character hex string; customer is the lowercase tenant slug. |

| Per-engagement authorization | --authz-doc <PATH> (env: SWARMHACK_AUTHZ_DOC) | Defines in-scope hostnames / IPs, engagement expiry, and authorised tester identity. Required for every spawn. |

The authorization document

JSON or YAML; format auto-detected by file extension.

{
  "client": "Acme Corp",
  "targets": ["app.acme.com", "*.staging.acme.com"],
  "expires_at": "2026-05-26T08:00:00Z",
  "scope": ["full_pentest"],
  "tester": "[email protected]",
  "document_id": "AUTHZ-ACME-POV-20260525",
  "notes": "POV-01 reference contract MSA-2026-0517"
}

| Field | Notes |

| --- | --- |

| targets | Hostnames / IPs. Wildcards (*.acme.com) are label-strictdev.acme.com.evil.com does NOT match. |

| expires_at | RFC 3339 UTC. Engagement length capped at ≤ 24 h. Past timestamps rejected. |

| tester | Surfaced verbatim into the SSE upsell report footer for legal countersignature. |

| document_id | Free-form; logged at startup for audit trace. |

| notes | Free-form; do NOT paste credentials or PII — the field is rendered into customer-facing reports. |

When --authz-doc is absent and --authz-skip is not set, swarmhack spawn exits with status 2. To bypass (unit tests / lab harnesses only), pass both --authz-skip and set SWARMHACK_ALLOW_NO_AUTHZ=1.

Public-target rule

Lab targets (RFC1918 IPv4, RFC4193 IPv6 ULA, loopback) are always allowed. Every other target requires --allow-public in addition to an authz-doc whose targets[] list contains the host. Drift between the CLI --target and authz-doc targets[] is fatal — exits 3.

Runtime scope check

The authz-doc targets[] list is stamped onto every per-agent AgentContext. 61 networking agents call AgentContext::is_host_in_scope before every cross-origin probe — robots.txt-discovered hosts, CT-log hostnames, cloud IMDS endpoints, third-party callbacks. Wildcard matching is label-strict (no suffix-attack *.acme.com → dev.acme.com.evil.com).

The sse_swg agent carries a documented exemption corpus so it can still probe EICAR and standard URL-category test domains without violating scope.

Destructive-attack gates

| Flag | Default | What it unlocks |

| --- | --- | --- |

| --blast-radius {recon,exploit,destructive} | exploit | Policy ceiling for payload SafetyClass. Recon blocks Modifying + Destructive; Exploit blocks Destructive; Destructive allows all. |

| --allow-ntlm-relay | false | Binds NTLM relay HTTP listener and forwards captured authenticators. Required for ntlm_relay. |

| --allow-public | false | Required for any non-lab target. |

| --pci-compliance | false | Emits PCI DSS pci_summary block via the 10-rule auto-fail engine (ADR-007). |

| --allow-legacy-tools | false | Allows Tier-3 legacy tools (impacket, certipy, responder). Default quarantines all Tier-3 binaries. |

[!WARNING]
--blast-radius destructive permits payloads that destroy target state (rm / DROP TABLE / executable webshell upload). Pair only with a lab target and an authz-doc whose notes field explicitly authorises destructive payloads.

TLS verification

TLS verification is on by default at every layer (webpki-roots Mozilla CA bundle). Two opt-in env vars relax it for self-signed lab certs:

| Env var | Effect |

| --- | --- |

| SWARMHACK_INSECURE_PREFLIGHT_TLS=1 | Disables TLS verification for the pre-flight target reachability probe. |

| SWARMHACK_INSECURE_BANNER_TLS=1 | Disables TLS verification for the recon banner-fetch client. |

Pass --strict-tls to refuse invalid TLS certs regardless of env-var opt-ins.