Skip to content

Commit

Permalink
feat: add automatic vulnerability reports
Browse files Browse the repository at this point in the history
Add the option to report vulnerabilities automatically via Github issues.

Fixes #69
  • Loading branch information
DnPlas committed Oct 8, 2024
1 parent e6d94ca commit fb912a3
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ name: Build, scan, and test ROCK
on:
workflow_call:
inputs:
report-vulnerabilities:
description: "Whether to report security vulnerabilities through Github issues."
required: false
default: false
type: boolean
rock-dir:
description: "Path to rock directory, i.e. directory containing rockcraft.yaml"
required: true
Expand All @@ -27,8 +32,12 @@ on:
default: ""
required: false
type: string
severity:
description: "Comma separated list of severities of vulnerabilities to scanned for and displayed"
required: false
type: string
default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL"
jobs:

build:
uses: ./.github/workflows/build-rock.yaml
with:
Expand All @@ -43,6 +52,17 @@ jobs:
rock-artifact: ${{ needs.build.outputs.rock-artifact}}
rock-reference: ${{ needs.build.outputs.rock-reference }}
rock-filename: ${{ needs.build.outputs.rock-filename }}
report-vulnerabilities: ${{ inputs.report-vulnerabilities }}
severity: ${{ inputs.severity }}

report-vulnerability:
needs: [scan, build]
uses: ./.github/workflows/report-vulnerability-in-gh.yaml
secrets: inherit
if: ${{ always() && (needs.scan.result == 'failure' && needs.build.result == 'success') }}
with:
issue-title: 'Vulnerabilities found for'
rock-reference: ${{ needs.build.outputs.rock-reference }}

sanity-tests:
needs: build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ name: Get ROCKs modified and build-scan-test-publish them

on:
workflow_call:
secrets:
GH_TOKEN:
required: true
inputs:
report-vulnerabilities:
description: "Whether to report security vulnerabilities through Github issues."
required: false
default: false
type: boolean
rockcraft-channel:
description: "Rockcraft channel e.g. latest/stable"
required: false
Expand All @@ -23,6 +31,12 @@ on:
default: ""
required: false
type: string
severity:
description: "Comma separated list of severities of vulnerabilities to scanned for and displayed"
required: false
type: string
default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL"


jobs:
get-rock-paths-modified:
Expand All @@ -35,11 +49,13 @@ jobs:
fail-fast: false
matrix:
rock-dir: ${{ fromJson(needs.get-rock-paths-modified.outputs.paths) }}
uses: ./.github/workflows/build-scan-test-publish-rock.yaml
uses: ./.github/workflows/build-scan-test-report-issue-publish-rock.yaml
secrets: inherit
with:
report-vulnerabilities: ${{ inputs.report-vulnerabilities }}
rock-dir: ${{ matrix.rock-dir }}
microk8s-channel: ${{ inputs.microk8s-channel }}
juju-channel: ${{ inputs.juju-channel }}
rockcraft-channel: ${{ inputs.rockcraft-channel }}
python-version: ${{ inputs.python-version }}
severity: ${{ inputs.severity }}
79 changes: 79 additions & 0 deletions .github/workflows/report-vulnerability-in-gh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Report vulnerability issues via Github
on:
workflow_call:
inputs:
issue-title:
description: The title of the issue to be created/edited
required: true
type: string
issue-labels:
description: A comma separated list of labels
required: false
type: string
default: "bug"
rock-reference:
description: "Rock reference to be used in order to copy the image to docker cache.
It consists of <rock-name>:<rock-version>."
required: true
type: string

jobs:
report-vulns:
name: Create or edit issues for reporting vulnerabilities
runs-on: ubuntu-22.04
steps:
- name: Install tools
run: |
sudo snap install gh
sudo snap install jq
- name: Generate image name
id: image-name
run: |
IMAGE_NAME=$(echo ${{ inputs.rock-reference }} | sed 's/\:/-/g')
echo "image-name=${IMAGE_NAME}" >> "$GITHUB_OUTPUT"
- name: Get issue number if exists
id: get-issue-number
run: |
set -xeu
export GH_TOKEN=${{ secrets.GH_TOKEN }}
EXPECTED_TITLE=$(echo "${{ inputs.issue-title }} ${{ inputs.rock-reference }}")
ISSUE_NUMBER=$(gh issue list --repo $GITHUB_REPOSITORY --limit 500 --json "number,title" | jq -r --arg expected_title "$EXPECTED_TITLE" '.[] | select(.title == $expected_title) | .number')
echo "issue-number=$ISSUE_NUMBER" >> $GITHUB_OUTPUT
- name: Download report
uses: actions/download-artifact@v4
with:
name: trivy-report-${{ steps.image-name.outputs.image-name }}

- name: Issue body
id: issue-body
run: |
set -xeu
EXPECTED_TITLE=$(echo "${{ inputs.issue-title }} ${{ inputs.rock-reference }}")
echo "## $EXPECTED_TITLE" > issue.md
echo "" >> issue.md
echo "\`\`\`" >> issue.md
cat trivy-report-${{ steps.image-name.outputs.image-name }}.txt >> issue.md
echo "\`\`\`" >> issue.md
echo "" >> issue.md
echo -e "\nDetails: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> issue.md
echo "issue-body-file=issue.md" >> "$GITHUB_OUTPUT"
- name: Report failures via Github issue
run: |
export GH_TOKEN=${{ secrets.GH_TOKEN }}
EXPECTED_TITLE=$(echo "${{ inputs.issue-title }} ${{ inputs.rock-reference }}")
if [ -z ${{ steps.get-issue-number.outputs.issue-number }} ]; then
echo "---- Creating issue ----"
gh issue create --repo $GITHUB_REPOSITORY \
--title "$EXPECTED_TITLE" \
--label "${{ inputs.issue-labels }}" \
--body-file "${{ steps.issue-body.outputs.issue-body-file }}"
else
echo "---- Editing issue ${{ steps.get-issue-number.outputs.issue-number }}----"
gh issue edit --repo $GITHUB_REPOSITORY ${{ steps.get-issue-number.outputs.issue-number }} \
--title "$EXPECTED_TITLE" \
--body-file "${{ steps.issue-body.outputs.issue-body-file }}"
fi
58 changes: 50 additions & 8 deletions .github/workflows/scan-rock.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ name: Scan
on:
workflow_call:
inputs:
report-vulnerabilities:
description: "Whether to report security vulnerabilities through Github issues."
required: false
default: false
type: boolean
rock-artifact:
description: "Name of the artifact from which the ROCK will be downloaded."
required: true
Expand All @@ -16,10 +21,19 @@ on:
description: "Filename of the .rock file"
required: true
type: string
severity:
description: "Comma separated list of severities of vulnerabilities to scanned for and displayed"
required: false
type: string
default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL"
jobs:
scan:
name: Scan ${{ inputs.rock-reference }}
runs-on: ubuntu-22.04
outputs:
image-name: ${{ steps.image-name.outputs.image-name }}
strategy:
fail-fast: false
steps:
# Ideally we'd use self-hosted runners, but this effort is still not stable.
# This action will remove unused software (dotnet, haskell, android libs, codeql,
Expand All @@ -38,7 +52,7 @@ jobs:
- name: Install Rockcraft
run: sudo snap install rockcraft --classic --edge

- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: ${{ inputs.rock-artifact }}

Expand All @@ -48,22 +62,50 @@ jobs:
sudo rockcraft.skopeo --insecure-policy copy oci-archive:${{ inputs.rock-filename }} docker-daemon:rock:tag
echo "image=rock:tag" >> "$GITHUB_OUTPUT"
- name: Set up inputs for scan
id: set-up-inputs
run: |
echo "exit-code=1" >> "$GITHUB_OUTPUT"
if ${{ inputs.report-vulnerabilities == 'false' }}; then
echo "exit-code=0" >> "$GITHUB_OUTPUT"
fi
- name: Generate image name
id: image-name
run: |
IMAGE_NAME=$(echo ${{ inputs.rock-reference }} | sed 's/\:/-/g')
echo "image-name=${IMAGE_NAME}" >> "$GITHUB_OUTPUT"
- name: Scan for vulnerabilities
id: scan
uses: aquasecurity/trivy-action@master
uses: aquasecurity/[email protected]
# Workaround for https://github.com/aquasecurity/trivy-action/issues/389
env:
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db:2
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db:1
with:
scan-type: 'image'
image-ref: '${{ steps.rock_in_docker.outputs.image }}'
format: 'json'
output: 'trivy-report-${{ inputs.rock-artifact }}.json'
format: 'table'
output: 'trivy-report-${{ steps.image-name.outputs.image-name }}.txt'
ignore-unfixed: true
timeout: '50m0s'
exit-code: ${{ steps.set-up-inputs.outputs.exit-code }}
severity: ${{ inputs.severity }}
# NOTE: pebble is flagged with a HIGH vuln because of golang.org/x/crypto
# CVE-2021-43565, CVE-2022-27191
skip-files: '/bin/pebble,/usr/bin/pebble,usr/bin/pebble,bin/pebble'

- name: Print vulnerabilities report
run: cat trivy-report-${{ inputs.rock-artifact }}.json
# The report should be printed regardless of the success of the previous step
if: success() || failure()
run: cat trivy-report-${{ steps.image-name.outputs.image-name }}.txt

- name: Upload Trivy reports
uses: actions/upload-artifact@v3
# The report should be uploaded regardless of the success of the previous steps
if: success() || failure()
uses: actions/upload-artifact@v4
with:
name: trivy-report-${{ inputs.rock-artifact }}
path: trivy-report-${{ inputs.rock-artifact }}.json
compression-level: 0
name: trivy-report-${{ steps.image-name.outputs.image-name }}
path: trivy-report-${{ steps.image-name.outputs.image-name }}.txt

0 comments on commit fb912a3

Please sign in to comment.