Problem
There is no per-project config file. Teams must re-pass ignore patterns, workspace specs, and fail-on thresholds on every CLI invocation or encode them in GitHub Actions inputs. There is no file that gets committed to the repo and persists these settings across developers and CI runs. This prevents the "configure once, drop into any repo" story from being real.
Scope
- Detect and parse
.owasp-wtf.yml at the repo root (and optionally owasp-wtf.config.yml)
- Support keys:
ignore, workspaces, mode, fail-on, include-build-output
- Precedence: CLI flags > project-file > built-in defaults
doctor reports whether a project config was found and what it contributed
owasp-wtf init command scaffolds a minimal .owasp-wtf.yml with inline comments
- JSON output adds
config: { source, path } field to ScanReport
Acceptance Criteria
owasp-wtf scan reads .owasp-wtf.yml from cwd if present
owasp-wtf scan --ignore foo/ overrides the file's ignore list (CLI wins)
owasp-wtf doctor shows project config found/not found and what keys are active
owasp-wtf init creates .owasp-wtf.yml if absent; exits 1 with message if present
- Unit test: mock filesystem with a config file, assert parsed values flow into
ScanCommandOpts
- Integration test: fixture scan with a config that ignores a known-FP path; assert path absent from findings
- Malformed YAML prints actionable error, exits 1
- Exit codes unchanged
- SARIF output unchanged
action.yml inputs unchanged (Action inputs layer above the file)
- Expected JSON diff:
ScanReport gains config: { source: 'project-file' | 'defaults', path: string | null }
Non-goals
- Org-level config (Phase 5)
- Schema validation / JSON Schema for the YAML (separate issue)
- Encrypting secrets in the file
- Changing any action.yml input/output contract
QA Checklist
Test Plan
- Unit:
packages/cli/src/config.test.ts — parse valid/invalid YAML, assert option merging, CLI override
- Integration:
specs/fixtures/ — add fixture with .owasp-wtf.yml that ignores a subfolder; golden JSON diff
Risk
Medium — new public CLI surface (config file schema, init subcommand). Must be additive only; no existing flags changed.
Dependencies
Should land before #81 (framework-aware allowlist, which will live in this file).
Problem
There is no per-project config file. Teams must re-pass ignore patterns, workspace specs, and fail-on thresholds on every CLI invocation or encode them in GitHub Actions inputs. There is no file that gets committed to the repo and persists these settings across developers and CI runs. This prevents the "configure once, drop into any repo" story from being real.
Scope
.owasp-wtf.ymlat the repo root (and optionallyowasp-wtf.config.yml)ignore,workspaces,mode,fail-on,include-build-outputdoctorreports whether a project config was found and what it contributedowasp-wtf initcommand scaffolds a minimal.owasp-wtf.ymlwith inline commentsconfig: { source, path }field toScanReportAcceptance Criteria
owasp-wtf scanreads.owasp-wtf.ymlfromcwdif presentowasp-wtf scan --ignore foo/overrides the file'signorelist (CLI wins)owasp-wtf doctorshows project config found/not found and what keys are activeowasp-wtf initcreates.owasp-wtf.ymlif absent; exits 1 with message if presentScanCommandOptsaction.ymlinputs unchanged (Action inputs layer above the file)ScanReportgainsconfig: { source: 'project-file' | 'defaults', path: string | null }Non-goals
QA Checklist
owasp-wtf initin a fresh dir creates.owasp-wtf.ymlowasp-wtf inita second time does not overwrite (exits 1 with message)owasp-wtf doctorreports project config statusignoresuppresses expected findings in fixture scan--ignoreflag overrides config file valueconfig.sourcefield present in outputTest Plan
packages/cli/src/config.test.ts— parse valid/invalid YAML, assert option merging, CLI overridespecs/fixtures/— add fixture with.owasp-wtf.ymlthat ignores a subfolder; golden JSON diffRisk
Medium — new public CLI surface (config file schema,
initsubcommand). Must be additive only; no existing flags changed.Dependencies
Should land before #81 (framework-aware allowlist, which will live in this file).