Skip to content

WAF v1 compliance definition-of-done (PCI 6.4.2: audit logging, redaction, rule-change trail, health signal, monitor mode, starter pack) #518

Description

@kriszyp

Context

Security/compliance review of the WAF proposal (Aron, 2026-07-02; design doc: Confluence SD "Harper WAF — Design Proposal"; component PR: #517). Verdict: the enforcement engineering is strong, but a WAF that regulated customers can buy has three legs — enforce, prove, operate — and v1 currently only stands up the first. PCI DSS 4.0 Req 6.4.2 (mandatory since 2025-03) requires the automated solution to be actively running, generating audit logs, and configured to block or alert for immediate investigation — that makes several "productize-later" items part of what "WAF" means, not polish.

v1 definition-of-done (moved up from "productize")

  • Blocked/logged-request audit logging ships with the component: structured records (timestamp, source IP, rule id, action, request summary) durable enough for assessment evidence, with a path to alerting. Without this a customer cannot pass a PCI assessment using our WAF.
  • Log content redaction policy before any logging ships: WAF logs capture paths, query strings, and headers → tokens, PII, potentially PANs. PCI forbids logging PAN; GDPR expects minimization. Define masking rules now — retrofitting redaction into a shipped log format is miserable.
  • Rule-change audit trail: who changed which rule, when, before/after values (SOC 2 change management; PCI Req 10). Cheap while rule management is four registered operations. Investigate first: Harper table-level audit on system.hdb_waf_rules may provide most of this natively (read_audit_log records operations with originating user) — if so this is enablement + documentation, not new machinery.
  • Enforcement health signal: "actively running" is literal requirement language. Fail-open on subscription/compile failure is the chosen default — it must be documented, ideally configurable, and observable (a health/status surface proving the WAF is enforcing, e.g. rules loaded + last-recompile timestamp + subscription liveness).
  • Global monitor mode (detection-only): per-rule log action gets most of the way; name it as an explicit mode — every customer expects a tuning period, every QSA asks.
  • Default starter rule pack: an empty rule table "detects and prevents" nothing (6.4.2). Ship OWASP-Top-10-injection-floor coverage on path/query. Note this also pressures the requestBody phase priority — most real injection arrives in POST bodies, and the label "WAF" carries assessor expectations; be careful with the word in customer-facing material until coverage matches.

Open-question resolutions (from the same review)

Plan-for-later (decisions now must not preclude)

  • RBAC below super_user for rule management (separation of duties; today one compromised super_user on any node controls traffic fleet-wide via replication). Don't freeze the rule schema/authz in a way that blocks it.
  • Compliance reporting: rule-set export, config attestation, blocked-traffic summaries (customers must show auditors the control exists and operates; Studio UI is planned, reporting isn't).

Symphony-side counterparts: HarperFast/symphony#11 (hot-swappable protection config — also a prerequisite for the WAF→Symphony blocklist feed), #12 (JA4), #13 (deployment security docs).


Filed by KrAIs (Claude) on Kris's behalf, digesting Aron's review.

🤖 Generated with Claude Code

Activity

  1. kriszyp commented on Jul 3, 2026

    @kriszyp
    MemberAuthor

    Updates from the 2026-07-03 review fold + audit investigation (design doc v7)

    Two additions to the DoD list (from Jeff's inline engineering review, folded into the design doc):

    1. Load-shedding for WAF event logging — blocked-event records must sample/aggregate under attack load. One analytics row per blocked request during an attack is self-inflicted volumetric write load at exactly the moment the cluster is under pressure.
    2. SIEM export path (may ship post-v1, but the design must not preclude it) — enterprises stream security events to their SIEM (Datadog/Splunk); analytics-only is not creditable to a SOC, and export also turns out to be required for tamper-evidence (see below).

    Item 3 (rule-change audit trail) — "investigate first" is now done. Code-verified against #517 + core:

    • ✅ Native table audit fires for the WAF ops write path (hdb_waf_rules inherits logging.auditLog, default true; table.put/table.delete go through the standard audited path) — records when + operation type + before/after images.
    • ❌ No who: registered operations execute outside contextStorage.run(), so the audit record's user field is undefined for all four WAF ops (and read_audit_log username searches never match). This is a platform-level gap affecting all registerOperation-based ops — filed as harper#1591, core fix in progress. Local mitigation available in WAF component: rule-table-driven request filtering with live updates, reserved v1 schema, shadow/monitor mode, and activation gating #517 meanwhile: pass { user: request.hdb_user } as the write context.
    • ⚠️ Retention: default is 3 days (logging.auditRetention) — nowhere near PCI Req 10's 12-month horizon. Must be configured and exported.
    • ⚠️ Tamperability: any super_user can purge audit history via delete_audit_logs_before with no trace of the purge. Native audit is not append-only — an external export sink is mandatory for tamper-evidence, not optional.
    • ❌ Structurally invisible to table audit: denied attempts (a 403 never becomes a table write — must be logged at the op layer) and provenance (origin/approver for feed- or agent-written rules — schema slot reserved in the freeze checklist).

    Conclusion for item 3 (decomposition, not either/or): native table audit (once harper#1591 or the local context fix lands) for the change record + explicit op-layer records for denials/provenance + SIEM/archival export for retention and tamper-evidence.

    Full detail: design doc, open question 3 (v7).

    — KrAIs (Claude), for Kris

  2. added theissue type on Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    Priority

    P2

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions