Skip to content

rollout: adopt OWASP.WTF as the security gate in Dial-WTF/PeerSpeak #33

Description

@jeremyjs

Tracks adoption of OWASP.WTF as the Security gate in Dial-WTF/PeerSpeak, a pnpm Next.js monorepo. PeerSpeak currently has zero security scanning — OWASP.WTF integration is greenfield, no overlap with any existing tool.

Consuming-side tracker: Dial-WTF/PeerSpeak#1365 — "consolidate PR checks into 6-stage gate chain". OWASP.WTF owns stage 3 (Security), one of five required PR checks.

Why this rollout matters for OWASP.WTF

PeerSpeak is the first Next.js app to adopt OWASP.WTF as a binding PR gate, and exercises parts of the scanner that the dogfood self-scan (#28) won't:

  • Real Next.js build output.next/, .turbo/, dist/, storybook-static/ directories generate false-positive secrets in obfuscated JS. Default-ignore work in fix(cli): add default ignore patterns for build output dirs (.next/, dist/) to suppress FP secrets #30 is a hard prereq.
  • Cross-org consumption — PeerSpeak is in Dial-WTF org, OWASP.WTF in DecOperations. Without fix(cli): publish CLI to public npm registry to enable zero-config npx owasp-wtf #32 (public npm publish), every CI run needs a cross-org PAT or a manual GitHub Packages auth dance. Hard prereq.
  • Monorepo with cross-workspace dependenciesapps/* + packages/* + experiments/* + tooling/*. Scope of a scan needs to follow changed workspaces, not blindly recurse from root.
  • WebRTC + wallet auth surface — stress test for the auth (A07), access control (A01), and crypto (A02) rule paths once they land beyond stubs.
  • Real run cadence — high PR volume means the action download / scanner install adds up. CLI tarball caching becomes a real performance concern.

Adoption checklist

Run in a fresh Claude Code / Codex session against the PeerSpeak checkout:

  • OWASP.WTF appears as stage 3 in PeerSpeak's pr-gates.yml (Security gate). Single required PR check: OWASP — Security.
  • Action runs on self-hosted runner labels [self-hosted, linux, x64, dial-lab, peerspeak].
  • mode: scan, format: sarif, fail-on: high. SARIF uploaded to GitHub code scanning.
  • Permissions: security-events: write, contents: read, pull-requests: write.
  • First scan results triaged into baseline (see engine gap #G3).
  • Security check added to main branch protection rules.
  • First post-baseline PR is opened with Security gate green.
  • deep mode scheduled nightly on main (separate workflow app-gate-full.yml or similar).
  • fix-plan --agent claude artifact attached to failing PRs.

Hard prereqs (existing issues in this repo)

Engine gaps surfaced by this rollout

New items beyond the existing issue tracker:

G1. Baseline / snapshot mode

PeerSpeak has never had security scanning. The first scan will surface a long tail of pre-existing findings that need to be triaged, not block PRs. Need a baseline mechanism:

owasp-wtf scan . --baseline owasp-baseline.json

The baseline file records findings accepted at a point in time; PRs are graded only against new findings since the baseline. Without this, the gate either floods reviewers on day one or starts non-blocking forever.

Related: --accept-finding <id> to suppress a specific finding with a reason field, written into the baseline.

G2. Workspace-aware scan

Monorepo support: owasp-wtf scan --workspace apps/dial.wtf to scope the scan to one workspace, and --changed-workspaces to scope based on a git base. Today --ignore globbing is the only knob; explicit workspace selection is cleaner and easier to wire into CI.

Proposal:

owasp-wtf scan . --workspace apps/dial.wtf --workspace packages/shared

or:

owasp-wtf scan . --changed-workspaces --base origin/main

G3. Cache CLI tarball between action runs

The composite action downloads the CLI tarball from a GitHub Release every run. On a self-hosted runner with high PR throughput, that's ~30s of avoidable network per job. Cache by version + checksum in ~/.cache/owasp-wtf/ and only re-download on version change.

Low effort; meaningful saving on a busy repo.

G4. Action input UX for monorepos

With G2 landed, surface the same in action.yml:

with:
  workspace: apps/dial.wtf
  changed-workspaces: 'true'
  base: origin/main

Lets PeerSpeak's pr-gates.yml pass through the scope-computed workspace list without shell glue.

G5. Next.js / React rule pack

Nice-to-have, not prereq. Once native A03 rules graduate from regex to AST, ship a Next.js-aware pack:

  • App Router server-action auth-guard checks
  • dangerouslySetInnerHTML with non-sanitized input
  • Middleware bypass patterns
  • Public env var leakage (NEXT_PUBLIC_* containing secret-shaped values)
  • Server-only imports in client components (security boundary)

PeerSpeak would be the natural validation repo.

Open questions

  • Does the existing semgrep adapter (called via --config p/owasp-top-ten) cover Next.js patterns sufficiently, or do we want --config p/nextjs added as a default when a Next.js project is detected?
  • For the first PR-blocking week, should fail-on start at critical and tighten to high once the baseline is stable, or start at high and triage aggressively?
  • Where should the fix-plan --agent claude artifact be uploaded — PR comment, workflow artifact, or both?

Done when

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedBlocked — see commentenhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions