Nightly Code Security Scan #462
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Nightly Code Security Scan | |
on: | |
schedule: | |
- cron: '0 20 * * *' | |
workflow_dispatch: | |
env: | |
GO_VERSION: 1.22.5 | |
DOCKER_HUB_REPO: portainerci/portainer-ce | |
DOCKER_HUB_IMAGE_TAG: develop | |
jobs: | |
client-dependencies: | |
name: Client Dependency Check | |
runs-on: ubuntu-latest | |
if: >- # only run for develop branch | |
github.ref == 'refs/heads/develop' | |
outputs: | |
js: ${{ steps.set-matrix.outputs.js_result }} | |
steps: | |
- name: checkout repository | |
uses: actions/checkout@master | |
- name: scan vulnerabilities by Snyk | |
uses: snyk/actions/node@master | |
continue-on-error: true # To make sure that artifact upload gets called | |
env: | |
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | |
with: | |
json: true | |
- name: upload scan result as develop artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: js-security-scan-develop-result | |
path: snyk.json | |
- name: develop scan report export to html | |
run: | | |
$(docker run --rm -v ${{ github.workspace }}:/data portainerci/code-security-report:latest summary --report-type=snyk --path="/data/snyk.json" --output-type=table --export --export-filename="/data/js-result") | |
- name: upload html file as artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: html-js-result-${{github.run_id}} | |
path: js-result.html | |
- name: analyse vulnerabilities | |
id: set-matrix | |
run: | | |
result=$(docker run --rm -v ${{ github.workspace }}:/data portainerci/code-security-report:latest summary --report-type=snyk --path="/data/snyk.json" --output-type=matrix) | |
echo "js_result=${result}" >> $GITHUB_OUTPUT | |
server-dependencies: | |
name: Server Dependency Check | |
runs-on: ubuntu-latest | |
if: >- # only run for develop branch | |
github.ref == 'refs/heads/develop' | |
outputs: | |
go: ${{ steps.set-matrix.outputs.go_result }} | |
steps: | |
- name: checkout repository | |
uses: actions/checkout@master | |
- name: install Go | |
uses: actions/setup-go@v3 | |
with: | |
go-version: ${{ env.GO_VERSION }} | |
- name: download Go modules | |
run: cd ./api && go get -t -v -d ./... | |
- name: scan vulnerabilities by Snyk | |
continue-on-error: true # To make sure that artifact upload gets called | |
env: | |
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | |
run: | | |
yarn global add snyk | |
snyk test --file=./go.mod --json-file-output=snyk.json 2>/dev/null || : | |
- name: upload scan result as develop artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: go-security-scan-develop-result | |
path: snyk.json | |
- name: develop scan report export to html | |
run: | | |
$(docker run --rm -v ${{ github.workspace }}:/data portainerci/code-security-report:latest summary --report-type=snyk --path="/data/snyk.json" --output-type=table --export --export-filename="/data/go-result") | |
- name: upload html file as artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: html-go-result-${{github.run_id}} | |
path: go-result.html | |
- name: analyse vulnerabilities | |
id: set-matrix | |
run: | | |
result=$(docker run --rm -v ${{ github.workspace }}:/data portainerci/code-security-report:latest summary --report-type=snyk --path="/data/snyk.json" --output-type=matrix) | |
echo "go_result=${result}" >> $GITHUB_OUTPUT | |
image-vulnerability: | |
name: Image Vulnerability Check | |
runs-on: ubuntu-latest | |
if: >- | |
github.ref == 'refs/heads/develop' | |
outputs: | |
image-trivy: ${{ steps.set-trivy-matrix.outputs.image_trivy_result }} | |
image-docker-scout: ${{ steps.set-docker-scout-matrix.outputs.image_docker_scout_result }} | |
steps: | |
- name: scan vulnerabilities by Trivy | |
uses: docker://docker.io/aquasec/trivy:latest | |
continue-on-error: true | |
with: | |
args: image --ignore-unfixed=true --vuln-type="os,library" --exit-code=1 --format="json" --output="image-trivy.json" --no-progress ${{ env.DOCKER_HUB_REPO }}:${{ env.DOCKER_HUB_IMAGE_TAG }} | |
- name: upload Trivy image security scan result as artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: image-security-scan-develop-result | |
path: image-trivy.json | |
- name: develop Trivy scan report export to html | |
run: | | |
$(docker run --rm -v ${{ github.workspace }}:/data portainerci/code-security-report:latest summary --report-type=trivy --path="/data/image-trivy.json" --output-type=table --export --export-filename="/data/image-trivy-result") | |
- name: upload html file as Trivy artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: html-image-result-${{github.run_id}} | |
path: image-trivy-result.html | |
- name: analyse vulnerabilities from Trivy | |
id: set-trivy-matrix | |
run: | | |
result=$(docker run --rm -v ${{ github.workspace }}:/data portainerci/code-security-report:latest summary --report-type=trivy --path="/data/image-trivy.json" --output-type=matrix) | |
echo "image_trivy_result=${result}" >> $GITHUB_OUTPUT | |
- name: scan vulnerabilities by Docker Scout | |
uses: docker/scout-action@v1 | |
continue-on-error: true | |
with: | |
command: cves | |
image: ${{ env.DOCKER_HUB_REPO }}:${{ env.DOCKER_HUB_IMAGE_TAG }} | |
sarif-file: image-docker-scout.json | |
dockerhub-user: ${{ secrets.DOCKER_HUB_USERNAME }} | |
dockerhub-password: ${{ secrets.DOCKER_HUB_PASSWORD }} | |
- name: upload Docker Scout image security scan result as artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: image-security-scan-develop-result | |
path: image-docker-scout.json | |
- name: develop Docker Scout scan report export to html | |
run: | | |
$(docker run --rm -v ${{ github.workspace }}:/data portainerci/code-security-report:latest summary --report-type=docker-scout --path="/data/image-docker-scout.json" --output-type=table --export --export-filename="/data/image-docker-scout-result") | |
- name: upload html file as Docker Scout artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: html-image-result-${{github.run_id}} | |
path: image-docker-scout-result.html | |
- name: analyse vulnerabilities from Docker Scout | |
id: set-docker-scout-matrix | |
run: | | |
result=$(docker run --rm -v ${{ github.workspace }}:/data portainerci/code-security-report:latest summary --report-type=docker-scout --path="/data/image-docker-scout.json" --output-type=matrix) | |
echo "image_docker_scout_result=${result}" >> $GITHUB_OUTPUT | |
result-analysis: | |
name: Analyse Scan Results | |
needs: [client-dependencies, server-dependencies, image-vulnerability] | |
runs-on: ubuntu-latest | |
if: >- | |
github.ref == 'refs/heads/develop' | |
strategy: | |
matrix: | |
js: ${{fromJson(needs.client-dependencies.outputs.js)}} | |
go: ${{fromJson(needs.server-dependencies.outputs.go)}} | |
image-trivy: ${{fromJson(needs.image-vulnerability.outputs.image-trivy)}} | |
image-docker-scout: ${{fromJson(needs.image-vulnerability.outputs.image-docker-scout)}} | |
steps: | |
- name: display the results of js, Go, and image scan | |
run: | | |
echo "${{ matrix.js.status }}" | |
echo "${{ matrix.go.status }}" | |
echo "${{ matrix.image-trivy.status }}" | |
echo "${{ matrix.image-docker-scout.status }}" | |
echo "${{ matrix.js.summary }}" | |
echo "${{ matrix.go.summary }}" | |
echo "${{ matrix.image-trivy.summary }}" | |
echo "${{ matrix.image-docker-scout.summary }}" | |
- name: send message to Slack | |
if: >- | |
matrix.js.status == 'failure' || | |
matrix.go.status == 'failure' || | |
matrix.image-trivy.status == 'failure' || | |
matrix.image-docker-scout.status == 'failure' | |
uses: slackapi/slack-github-action@v1.23.0 | |
with: | |
payload: | | |
{ | |
"blocks": [ | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": "Code Scanning Result (*${{ github.repository }}*)\n*<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|GitHub Actions Workflow URL>*" | |
} | |
} | |
], | |
"attachments": [ | |
{ | |
"color": "#FF0000", | |
"blocks": [ | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": "*JS dependency check*: *${{ matrix.js.status }}*\n${{ matrix.js.summary }}" | |
} | |
}, | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": "*Go dependency check*: *${{ matrix.go.status }}*\n${{ matrix.go.summary }}" | |
} | |
}, | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": "*Image Trivy vulnerability check*: *${{ matrix.image-trivy.status }}*\n${{ matrix.image-trivy.summary }}\n" | |
} | |
}, | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": "*Image Docker Scout vulnerability check*: *${{ matrix.image-docker-scout.status }}*\n${{ matrix.image-docker-scout.summary }}\n" | |
} | |
} | |
] | |
} | |
] | |
} | |
env: | |
SLACK_WEBHOOK_URL: ${{ secrets.SECURITY_SLACK_WEBHOOK_URL }} | |
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK |