Add the Darkwing vulnerability scan workflows
GE Aerospace now expects a Darkwing check on every repo. Two files rather than one, because they answer different questions and only one of them is ours. scan-darkwing-portable.yml is copied byte-for-byte from the ge-aero/darkwing README so it keeps matching the sanctioned integration. Manual dispatch only. scan-darkwing-pr.yml runs on pull requests and is ours to change. It exists because the README workflow cannot simply be given a pull_request trigger: it resolves its target as `inputs.target_ref || 'main'`, and a pull_request event carries no inputs, so the expression falls through to 'main' and the job scans the default branch instead of the code under review. That is a check that is green because it never looked. This one resolves the PR head SHA explicitly. Neither file gates a merge. Darkwing exits 0 whatever it finds, and its results vary between runs on identical code, so a passing job means the scan ran and nothing more. The SARIF-parsing step that would turn a finding into a failure is written but commented out, to be switched on once the false-positive rate on this codebase is known. Scope: product
This commit is contained in:
32
.github/workflows/scan-darkwing-portable.yml
vendored
Normal file
32
.github/workflows/scan-darkwing-portable.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Darkwing vulnerability scan, manual dispatch.
|
||||||
|
#
|
||||||
|
# Copied verbatim from the ge-aero/darkwing README so it stays byte-identical
|
||||||
|
# to the sanctioned integration. Do not edit this file to add triggers or
|
||||||
|
# gating - see scan-darkwing-pr.yml for that, which is ours to change.
|
||||||
|
#
|
||||||
|
# The file must sit on the default branch before a scan can run on ANY branch.
|
||||||
|
name: Scan (darkwing, portable)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
target_ref:
|
||||||
|
description: Ref, branch, or sha of this repo to scan
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: main
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read # checkout this repo via the ambient GITHUB_TOKEN
|
||||||
|
security-events: write # SARIF upload to the Security tab
|
||||||
|
actions: read # required by upload-sarif on private/internal repos
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
scan:
|
||||||
|
runs-on: darkwing-scan
|
||||||
|
steps:
|
||||||
|
# @v1 is a moving tag pointing to the latest release that is compatible
|
||||||
|
# with this workflow file.
|
||||||
|
- uses: ge-aero/darkwing@v1
|
||||||
|
with:
|
||||||
|
target_ref: ${{ inputs.target_ref || 'main' }}
|
||||||
62
.github/workflows/scan-darkwing-pr.yml
vendored
Normal file
62
.github/workflows/scan-darkwing-pr.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Darkwing scan on pull requests, so the "check against darkwing" is a check
|
||||||
|
# and not a thing somebody remembers to click.
|
||||||
|
#
|
||||||
|
# WHY THIS IS SEPARATE from scan-darkwing-portable.yml: that file is copied
|
||||||
|
# byte-for-byte from the ge-aero/darkwing README and is left alone so it keeps
|
||||||
|
# matching the sanctioned integration. Everything below is ours.
|
||||||
|
#
|
||||||
|
# THE TRAP THIS AVOIDS. The README workflow resolves its scan target as
|
||||||
|
# `inputs.target_ref || 'main'`. On a pull_request event there are no inputs,
|
||||||
|
# so that expression falls through to 'main' and the job scans the default
|
||||||
|
# branch instead of the code under review - a green Darkwing check that never
|
||||||
|
# looked at the change. Resolve the head SHA explicitly.
|
||||||
|
#
|
||||||
|
# Darkwing exits 0 whatever it finds (its own FAQ: "Does a finding fail my
|
||||||
|
# build? No."), so a passing job means the scan RAN, not that the code is
|
||||||
|
# clean. Findings land in Security -> Code scanning. Turning a finding into a
|
||||||
|
# hard failure means reading findings.sarif ourselves; the commented step at
|
||||||
|
# the bottom is the shape of that, deliberately left off until we have seen the
|
||||||
|
# false-positive rate on this repo.
|
||||||
|
name: Scan (darkwing, PR)
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
actions: read
|
||||||
|
|
||||||
|
# One scan per PR. A new push supersedes the old one rather than queueing a
|
||||||
|
# second Bedrock spend against a diff nobody is reviewing any more.
|
||||||
|
concurrency:
|
||||||
|
group: darkwing-pr-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
scan:
|
||||||
|
runs-on: darkwing-scan
|
||||||
|
steps:
|
||||||
|
- uses: ge-aero/darkwing@v1
|
||||||
|
with:
|
||||||
|
# The PR's head, NOT the default branch. See the note above.
|
||||||
|
target_ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|
||||||
|
# Gating, once the signal is trusted. Darkwing writes findings.sarif into
|
||||||
|
# its work dir and attaches it as the `findings` artifact; this reads the
|
||||||
|
# severities out and fails on error-level results only.
|
||||||
|
#
|
||||||
|
# - name: Fail on error-level findings
|
||||||
|
# run: |
|
||||||
|
# python - <<'PY'
|
||||||
|
# import json, pathlib, sys
|
||||||
|
# sarif = pathlib.Path('darkwing/findings.sarif')
|
||||||
|
# if not sarif.is_file():
|
||||||
|
# sys.exit('no findings.sarif: the scan did not produce results')
|
||||||
|
# doc = json.loads(sarif.read_text())
|
||||||
|
# bad = [r for run in doc.get('runs', [])
|
||||||
|
# for r in run.get('results', [])
|
||||||
|
# if r.get('level') == 'error']
|
||||||
|
# if bad:
|
||||||
|
# sys.exit(f'{len(bad)} error-level finding(s); see the Security tab')
|
||||||
|
# PY
|
||||||
Reference in New Issue
Block a user