Skip to content

[maint-26] Vendor Vulnerability Scanning #464

[maint-26] Vendor Vulnerability Scanning

[maint-26] Vendor Vulnerability Scanning #464

# %CopyrightBegin%
#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright Ericsson AB 2024-2025. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# %CopyrightEnd%
name: Vendor Vulnerability Scanning
run-name: "[${{ inputs.version }}] Vendor Vulnerability Scanning"
description: 'Vulnerability scanning'
# 'inputs' must be repeated twice for the different use cases.
# there is no current way to share 'inputs' for workflow dispatch
# and call.
#
# version: reference branch to checkout and analyse for CVE.
#
# fail_if_cve: makes the job fail if a CVE is found.
# This is 'true' when analysing PRs, as we prefer a failure to detect that the PR
# introduces a vulnerability.
#
on:
workflow_dispatch:
inputs:
# this option is needed for scheduled scans. on pull requests (`main.yaml`)
# the PR already contains a branch on which to run and there is a known
# base_ref. on scheduled runs of this job, `base_ref` does not exist and
# we need to specify which repo branch to checkout.
checkout:
description: 'Checkout branch in version?'
required: false
default: false
type: boolean
version:
description: 'Reference branch to fetch OpenVEX statements'
required: true
default: 'master'
type: 'string'
fail_if_cve:
description: 'Fail if CVE is found and create issue'
required: true
default: false
type: boolean
workflow_call:
secrets:
# these secrets are required when doing workflow calls, e.g., main.yml
# calling this workflow directly. this is because if-condition at the step
# level are evaluated before the secrets are injected.
ERLANG_VENDOR_SCANNER_APP_ID:
required: false
ERLANG_VENDOR_SCANNER_BOT_PRIVATE_KEY:
required: false
inputs:
# this option is needed for scheduled scans. on pull requests (`main.yaml`)
# the PR already contains a branch on which to run and there is a known
# base_ref. on scheduled runs of this job, `base_ref` does not exist and
# we need to specify which repo branch to checkout.
checkout:
description: 'Checkout branch in version?'
required: false
default: false
type: boolean
version:
description: 'Reference branch to fetch OpenVEX statements'
required: true
default: 'master'
type: 'string'
fail_if_cve:
description: 'Fail if CVE is found and create issue'
required: true
default: false
type: boolean
env:
VERSION: ${{ inputs.version }}
jobs:
analysis-vendor-dependencies:
name: "Vulnerability Scanning of Vendor Dependencies"
# This job always fetches otp-compliance escript from `master`.
# internally, the job downloads OpenVEX statements from `vex` folder.
# the main reason is that maint-25, maint-26, etc do not have this file
# committed into them. thus, a workflow_dispatch or workflow_call would
# not work, and we would not be able to analyse vendor dependecies there.
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
permissions:
actions: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/[email protected]
with:
ref: ${{ inputs.checkout && inputs.version || ''}} # '' = default branch
- uses: erlef/setup-beam@5304e04ea2b355f03681464e683d92e3b2f18451 # racket:actions/checkout@v1
with:
otp-version: '28'
- name: Set flag if it is not a forked PR
run: echo "IS_NOT_FORKED_PR=$([[ -n '${{ secrets.ERLANG_VENDOR_SCANNER_APP_ID }}' && -n '${{ secrets.ERLANG_VENDOR_SCANNER_BOT_PRIVATE_KEY }}' ]] && echo true || echo false)" >> $GITHUB_ENV
# Conditionally generate GitHub App token if secrets are available
# this step will only work for scheduled and workflow dispatch jobs,
# so we need to use the condition below for PRs based on a fork
- name: "Generate GitHub App Token (if secrets exist)"
if: ${{ env.IS_NOT_FORKED_PR == 'true' }}
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42
id: app-token
with:
app-id: ${{ secrets.ERLANG_VENDOR_SCANNER_APP_ID }}
private-key: ${{ secrets.ERLANG_VENDOR_SCANNER_BOT_PRIVATE_KEY }}
# PRs comming from a fork can use their own GH_TOKEN instead.
# this is for security reasons that forked PRs cannot work with Github App tokens
# generated by Erlang/OTP, as that could leak secrets.
- name: "Set GH_TOKEN for steps"
run: |
if [ -n "${{ steps.app-token.outputs.token }}" ]; then
echo "Using GitHub App Token"
echo "GH_TOKEN=${{ steps.app-token.outputs.token }}" >> $GITHUB_ENV
else
echo "Using default GITHUB_TOKEN"
echo "GH_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
fi
- name: 'Analysis of dependencies from OpenVEX in ${{ inputs.version }}'
run: |
curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GH_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/erlang/otp/contents/.github/scripts/otp-compliance.es \
| jq -r '.content' | base64 -d > otp-compliance.es
chmod +x otp-compliance.es
cp otp-compliance.es /home/runner/work/otp/otp/.github/scripts/otp-compliance.es
cd /home/runner/work/otp/otp && \
GH_TOKEN="${{ steps.app-token.outputs.token }}" .github/scripts/otp-compliance.es sbom osv-scan \
--version ${{ inputs.version }} \
--fail_if_cve ${{ inputs.fail_if_cve }}