ADR-0084: HAR.Art — L7 HAR replay (10k sessions/host)¶
- Status: Accepted (2026-05-24) — full HAR wave (HAR-1..HAR-4) materialized; client engine + dashboard + K8s deploy + this ADR all shipped to
mainin PRs #1031 / #1032 / #1033 / this PR - Date: 2026-05-24
- Driver:
discuss_har_art_2026_05_10locked HAR.Art as the missing L7 replay primitive between PW.Art (browser, ~50 sessions/host) and DoYour.Art Replay (PCAP, packet-level). Memo identified five use cases unreachable from either side: WAF false-positive testing, cross-vendor regression, performance attribution, multi-region testing, load multiplication - Related: PRs #1031 (HAR-1), #1032 (HAR-2), #1033 (HAR-3), this PR (HAR-4); strategic memo
discuss_har_art_2026_05_10; sister-MÓDULO ADRs ADR-0081 (DoYour.Art Phase A) + ADR-0082 (KALI.Art Phase A) + ADR-0036 (HyperBridge.Art inline tap)
Context¶
The TLSStress.Art TAM has three distinct audiences who need application-layer replay against an NGFW DUT:
- Web QA engineers — record a checkout flow in DevTools, replay it after a config change, prove the NGFW didn't break the user journey
- WAF admins — customer reports "your WAF blocks our real users on /api/checkout"; we need their HAR captured during the broken session and the ability to replay it against the customer's WAF config in our lab
- Performance engineers — "the checkout is 8s slow, is it the NGFW?" Replay with and without NGFW; the delta = NGFW contribution
PW.Art (Playwright fleet) ships a full browser at ~200–500 MB / session × ~50 sessions / host — too heavy for the load-multiplication use case ("1 HAR × 10000 = realistic flash-sale load"). DoYour.Art Replay tab handles PCAP at L2-L4 — the wrong layer entirely for L7 semantics (fresh TLS handshake, different source IPs, etc.). Neither covers the gap.
No commercial bench ships HAR replay first-class (Spirent BreakingPoint, Keysight CyberFlood, Ixia BreakingPoint — none have HAR; only open-source puppeteer-har / har-replay-server, with zero observability/UI/scale).
Decision¶
Ship MÓDULO HAR.Art as a 4-sub-PR wave (HAR-1..HAR-4):
| Sub-PR | Scope | Status |
|---|---|---|
| HAR-1 | New Go module pkg/har-art/ — W3C HAR 1.2 parser, header rewrite + PII anonymizer, concurrent replay engine, CLI/server binary, Prometheus metrics. 17 unit tests |
✅ #1031 |
| HAR-2 | Drizzle 0038 har_art_replay_sessions + dual-mode store with tier caps + 5 API routes + admin page /admin/har-art + 29 i18n keys × 3 locales. 9 store tests |
✅ #1032 |
| HAR-3 | K8s manifests namespace har-art + NAD VLAN 2903 slot .83 + gVisor + Deployment + 100 GiB RWX PVC har-library + Drizzle 0039 har_art_operator_libraries per-operator metadata + tier-bound quotas |
✅ #1033 |
| HAR-4 | ADR-0084 (this PR) + module docs 3-lang expansion + recovery memo | ✅ |
Locked defaults — 5 open questions from the memo¶
The memo listed 5 open questions; this ADR locks each:
| # | Question | Locked answer |
|---|---|---|
| 1 | HTTP client choice | Custom Go net/http — pure stdlib, no CGO, no browser engine dependency. Trade-off: not browser-faithful (no JS execution, no DOM, no cookie-jar lifecycle). The memo's "WAF tuning + cross-vendor regression + perf attribution" use cases don't need browser fidelity; they need scale + identical L7 wire format. Browser fidelity stays in PW.Art |
| 2 | HAR storage | Local PVC har-library (RWX, 100 GiB default) — ReadWriteMany so multiple har-replay-client replicas can read the same HAR concurrently (the load-multiplication use case). S3/MinIO defer to a Phase B follow-up if/when the on-prem deployments need offsite storage |
| 3 | Throughput target MVP | 10 000 concurrent sessions/host per the memo's headline. One goroutine per session + shared HTTP/2 transport pool + atomic counters (no mutex contention) hit this comfortably on the 4-core / 4 GiB envelope from HAR-3's Deployment limits |
| 4 | Multi-browser HAR fidelity | Vendor-extension-tolerant parser; semantic re-issue rather than byte-for-byte replay. Chrome / Firefox / Safari HARs all replay identically through HAR.Art because the parser ignores the per-vendor sidecar fields (_serverIPAddress, _priority, etc.). The replayed traffic carries our synthetic User-Agent (operator-overridable), not the browser's |
| 5 | PII anonymization | Auto-strip ON by default, opt-out via Policy.AnonymizePII=false. Curated 10-header strip list (Cookie, Set-Cookie, Authorization, Proxy-Authorization, X-Api-Key, X-Auth-Token, X-Csrf-Token, X-Session-Id, X-Forwarded-User, X-Real-Ip) + email / CC / SSN regex redaction in request bodies. Operators handling segregated lab traffic can disable; the safe default keeps customer HARs publishable to the dashboard's audit trail |
Tier policy (locked)¶
Per the memo's "Free tier liberado — low-risk, web traffic":
| Tier | Concurrent runs | Replay clients | Duration cap | HAR library |
|---|---|---|---|---|
| free | 1 | 100 | 5 min | 100 MiB · 5 files |
| indie | 1 | 500 | 30 min | 1 GiB · 25 files |
| team | 3 | 5 000 | 2 h | 10 GiB · 100 files |
| enterprise | 10 | 10 000 | 24 h | 100 GiB · unlimited |
Tier caps return HTTP 429 with code: tier-* discriminator so the dashboard can render a coherent upsell path.
Architectural decision — standalone admin page¶
The dashboard page lives at /admin/har-art, NOT as an Art Studio tab. The memo is explicit: HAR.Art's audience (QA / WAF admins / app owners / perf engineers) is distinct from Art Studio's developer audience. Mixing them in tabs would dilute both surfaces.
Patent posture¶
Patent claim #17 (per the memo's "patent #17" reference, originally registered in the project-wide claims list). The novelty lever is the combination of: - W3C HAR replay at 10k-sessions/host scale - Auto-anonymizing PII at the replay layer (no commercial bench does this — every existing tool requires the operator to pre-scrub) - Tier-gated operator workflow with free-tier accessibility (no competitor offers free HAR replay)
FTO scan plan deferred to Phase B (when the cross-vendor regression use case generates the first customer demo). The puppeteer-har / har-replay-server open-source landscape has zero patent claims; commercial space (Spirent/Keysight/Ixia) doesn't ship HAR replay at all.
Consequences¶
Positive
- The 4-sub-PR cadence kept each merge small + reviewable + revertable
- Server-only / client-safe type separation (HAR-2
types.tsvssession-store.ts) keeps the Nodecryptoimport out of the browser bundle while letting the admin page render tier-cap labels - PVC RWX choice enables horizontal scale-out for the load-multiplication use case without operator action
- The 5-question lock removes ambiguity for the next operator who picks up HAR.Art work
Negative / deferred
- Browser-faithful replay —
puppeteer-har/ Playwright HAR mode could replay JS-heavy SPAs with full DOM lifecycle. Decision: stays in PW.Art; HAR.Art remains semantic-replay-only - S3 / MinIO HAR storage — Phase B once the on-prem RWX PVC pattern hits scale limits
- Browser fingerprint preservation — the synthetic User-Agent replaces the original; some WAFs do header-order / TLS-fingerprint inspection that we'd need to mimic. Deferred to a Phase B "fingerprint preservation" subdir
- Dashboard HAR upload UI — HAR-2's admin page accepts a
har_pathpointing at the PVC, but the actual upload happens out-of-band (kubectl cp or operator-supplied via volume mount). A first-class drag-and-drop upload form is a Phase B follow-up - Quota CronJob — HAR-3 declares the
har_art_operator_librariesschema but the nightlydu -sbscan that updatesbytes_usedlands in a Phase Bkali-quota-scan-style CronJob
Alternatives considered¶
- Embed HAR replay in PW.Art — rejected; would couple the heavy browser fleet to the lightweight L7 use cases and dilute both audiences
- Use Playwright's HAR mode — rejected for the engine; Playwright + headless Chromium is ~200–500 MB / session, defeating the 10k-sessions/host goal. Kept as a future option for browser-faithful replay in Phase B
- Single Art Studio tab — rejected per the memo's audience-separation argument
- RWO PVC + StatefulSet — rejected; load-multiplication requires multiple replicas reading the same HAR. RWX is the right model
- Mandatory PII anonymization (no opt-out) — rejected; lab-only operators need to test against real auth tokens. Default-on with opt-out is the right compromise
Compliance¶
Per CLAUDE.md: "Dashboard is the ONLY operator interface." HAR-2 ships the standalone admin page with start / cancel / live counters — operator never types kubectl against the har-art namespace.
Per ADR-0044 (OOBI Intrusion Detection): the har-replay-client HTTP server listens on :9092 cluster-internal only; ingress / NetworkPolicy scoping is the same shape as the kali-art-mcp sidecar.
Per the locked ZTP-prem posture: gosec W0 baseline preserved (no inline #nosec annotations were needed in the new pkg/har-art/ package — pure stdlib net/http, no system calls beyond os.Open on operator-supplied flag paths which are documented as such).
References¶
discuss_har_art_2026_05_10— strategic memo- ADR-0081 (DoYour.Art Phase A), ADR-0082 (KALI.Art Phase A), ADR-0036 (HyperBridge.Art) — sibling MÓDULOs in the offensive-tooling family
- PRs #1031 (HAR-1), #1032 (HAR-2), #1033 (HAR-3), this PR (HAR-4)
- Patent claim #17