Skip to content

fix(ci): stop DAST workflow reporting red on a passing ZAP scan#34

Merged
jeffgicharu merged 1 commit into
mainfrom
fix/dast-workflow-false-red
May 19, 2026
Merged

fix(ci): stop DAST workflow reporting red on a passing ZAP scan#34
jeffgicharu merged 1 commit into
mainfrom
fix/dast-workflow-false-red

Conversation

@jeffgicharu
Copy link
Copy Markdown
Owner

Why

The scheduled DAST (OWASP ZAP) workflow shows red on the Actions tab even though ZAP genuinely passes:

FAIL-NEW: 0  FAIL-INPROG: 0  WARN-NEW: 2  WARN-INPROG: 0  INFO: 0  IGNORE: 0  PASS: 65
...
##[error]File /home/runner/work/ContractorOS/ContractorOS/report_md.md does not exist

Root cause: the zaproxy/action-api-scan@v0.9.0 step ran with format: openapi against http://localhost:3001/api/v1/health. That endpoint is not an OpenAPI document — the app exposes no OpenAPI/Swagger spec at all — so ZAP had nothing to import, produced no report, and the action's hardcoded artifact upload failed on the missing report_md.md. A passing scan was rendered red by an infrastructure bug, not a finding.

fail_action: true is not the fix: per the action's own docs it fails the build on any alert, including the informational passive-scan WARNs this scan legitimately has (WARN-NEW: 2) — that would just be a different false red.

What

  • Removed the invalid OpenAPI api-scan step.
  • Replaced the marketplace baseline action with a direct zap-baseline.py invocation using -I (do not fail on warnings). The scan's own exit code is now the single source of truth:
    • clean / warnings-only → exit 0 → job green
    • genuine new FAIL-level alert → non-zero → job red
  • The HTML/Markdown/JSON report is uploaded as the zap-baseline-report artifact by an explicit upload-artifact step (always runs), so report-file naming can never fail the job again.

Verification

  • dast-zap.yml validated as well-formed YAML.
  • Triggered via workflow_dispatch on this branch; the run is green with the ZAP report attached as an artifact (linked in the final report).
  • Semantics match the requirement: green when ZAP reports zero new failures, red only on a genuine finding.

The scheduled DAST job was red even though ZAP reported FAIL-NEW: 0 /
PASS: 65. Root cause: the `zaproxy/action-api-scan` step used
`format: openapi` against `/api/v1/health`, which is not an OpenAPI
document. With no API definition to import the step produced no report,
and the action's hardcoded artifact upload then failed with
"File report_md.md does not exist" — turning a genuinely passing scan
red.

`fail_action: true` is not a fix here: that action fails on *any* alert,
including informational passive-scan WARNs (the scan legitimately had
WARN-NEW: 2), which would also be a false red.

Run zap-baseline.py directly with `-I` so warnings stay informational
and the scan's own exit code is the single source of truth: the job is
green on a clean/warn-only scan and red only on a genuine FAIL-level
finding. The HTML/MD/JSON report is uploaded as an artifact by us.
@gemini-code-assist
Copy link
Copy Markdown

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

@jeffgicharu jeffgicharu merged commit e5d480d into main May 19, 2026
20 checks passed
@jeffgicharu jeffgicharu deleted the fix/dast-workflow-false-red branch May 19, 2026 01:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant