-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: [SRE-830] Add trivy docker scan configuration and matrix outputs (
#7) Adds docker scan functionality. Sample usage/outputs: [app-base-image](https://github.com/stordco/app-base-image/pull/12) [matrix job usage- app-build-image](https://github.com/stordco/app-build-image/pull/27) [logiwa_writer](https://github.com/stordco/logiwa_writer/pull/108) [Sample slack notifications](https://stord-team.slack.com/archives/C079PF36UTC/p1719331554969529) --------- Co-authored-by: Parker DeBardelaben <[email protected]> Co-authored-by: Parker DeBardelaben <[email protected]>
- Loading branch information
1 parent
05d56e0
commit 98c14a2
Showing
2 changed files
with
153 additions
and
26 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,18 +8,24 @@ description: >- | |
GitHub Composite Action for running Trivy scans | ||
inputs: | ||
scan-type: | ||
description: >- | ||
"Specify the type of scan to be perforemed (e.g., 'fs' for filesystem scan)." | ||
type: string | ||
required: true | ||
github-token: | ||
description: "GitHub token for authentication." | ||
type: string | ||
required: false | ||
image-ref: | ||
description: "Specify the local Docker image to be scanned. This value needs to be set if the scan-type = image." | ||
required: false | ||
matrix-id: | ||
description: "Specify the matrix indicator to be leveraged on notification steps." | ||
required: false | ||
scan-type: | ||
description: >- | ||
"Specify the type of scan to be perforemed (e.g., 'fs' for filesystem scan, `image` for image scan)." | ||
required: true | ||
slack-bot-token: | ||
description: "Slackbot token for sending notifications." | ||
type: string | ||
required: false | ||
slack-channel-id: | ||
description: "Slack channel ID for sending notifications." | ||
required: false | ||
|
||
outputs: | ||
|
@@ -36,13 +42,17 @@ runs: | |
if [[ '${{ inputs.scan-type }}' == 'fs' ]]; then | ||
echo "config_file_type=fs" >> "$GITHUB_OUTPUT" | ||
fi | ||
if [[ '${{ inputs.scan-type }}' == 'image' ]]; then | ||
echo "config_file_type=image" >> "$GITHUB_OUTPUT" | ||
fi | ||
shell: bash | ||
|
||
- name: Run Trivy vulnerability scanner in ${{ inputs.scan-type }} mode | ||
id: trivy_scan | ||
uses: aquasecurity/[email protected] | ||
with: | ||
scan-type: ${{ inputs.scan-type }} | ||
image-ref: ${{ inputs.image-ref }} | ||
trivy-config: .trivy/${{ steps.configuration_file.outputs.config_file_type }}-config.yaml | ||
continue-on-error: true | ||
|
||
|
@@ -56,29 +66,35 @@ runs: | |
echo "Keep trivy artifact for 1 day on PR builds" | ||
echo "days=1" >> "$GITHUB_OUTPUT" | ||
fi | ||
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | ||
sha_short=$(git rev-parse --short HEAD) | ||
sanitized_ref_name=$(echo "${{ github.ref_name }}" | sed 's/[\\\/:*?<>|]/-/g') | ||
echo "ref_name=${sanitized_ref_name}" >> $GITHUB_OUTPUT | ||
if [[ -z '${{ inputs.matrix-id }}' ]]; then | ||
echo "name=trivy-${{ inputs.scan-type }}-results-${sha_short}-${sanitized_ref_name}" >> $GITHUB_OUTPUT | ||
else | ||
echo "name=trivy-${{ inputs.scan-type }}-results-${sha_short}-${sanitized_ref_name}-${{ inputs.matrix-id }}" >> $GITHUB_OUTPUT | ||
fi | ||
shell: bash | ||
|
||
- name: Upload Trivy report to artifacts | ||
uses: actions/upload-artifact@v4 | ||
id: trivy_artifact_upload | ||
with: | ||
name: trivy-${{ inputs.scan-type }}-results-${{ steps.artifact_metadata.outputs.sha_short }}-${{ steps.artifact_metadata.outputs.ref_name }} | ||
name: ${{ steps.artifact_metadata.outputs.name }} | ||
path: trivy-${{ inputs.scan-type }}-results.json | ||
retention-days: ${{ steps.artifact_metadata.outputs.days }} | ||
if-no-files-found: ignore | ||
overwrite: true | ||
|
||
- name: Upload Trivy Report as PR Comment and parse Critical vulnerabilities | ||
id: trivy_report_notification | ||
if: ${{ inputs.github-token }} | ||
if: ${{ inputs.github-token && github.event_name == 'pull_request' }} | ||
uses: actions/github-script@v7 | ||
env: | ||
GITHUB_TOKEN: ${{ inputs.github-token }} | ||
SCAN_TYPE: ${{ inputs.scan-type }} | ||
MATRIX_ID: ${{ inputs.matrix-id }} | ||
with: | ||
script: | | ||
const fs = require('fs'); | ||
|
@@ -93,7 +109,12 @@ runs: | |
const owner = context.repo.owner; | ||
const repo = context.repo.repo; | ||
const commentIdentifier = `<!-- trivyReportComment-${process.env.SCAN_TYPE}-->`; | ||
let commentIdentifier; | ||
if (!process.env.MATRIX_ID) { | ||
commentIdentifier = `<!-- trivyReportComment-${process.env.SCAN_TYPE}-->`; | ||
} else { | ||
commentIdentifier = `<!-- trivyReportComment-${process.env.SCAN_TYPE}-${process.env.MATRIX_ID}-->`; | ||
} | ||
const filePath = path.join(process.env.GITHUB_WORKSPACE, `trivy-${process.env.SCAN_TYPE}-results.json`); | ||
const fileContent = fs.readFileSync(filePath, 'utf8'); | ||
|
@@ -148,9 +169,11 @@ runs: | |
const botComment = comments.data.find(comment => comment.body.includes(commentIdentifier)); | ||
core.info(`Parsed Vulnerabilities: ${JSON.stringify(vulnerabilities)}`) | ||
const scanTypeName = process.env.SCAN_TYPE === 'fs' ? 'filesystem' : 'image'; | ||
if (vulnerabilities.flatMap(result => result.Vulnerabilities).length === 0) { | ||
if (botComment) { | ||
const noErrorsComment = `No vulnerabilities to be reported.\n${commentIdentifier}`; | ||
const noErrorsComment = `No Trivy ${scanTypeName} vulnerabilities to be reported${process.env.MATRIX_ID ? ` for ${process.env.MATRIX_ID}` : ''}.\n${commentIdentifier}`; | ||
await github.rest.issues.updateComment({ | ||
owner, | ||
|
@@ -178,15 +201,16 @@ runs: | |
if (formattedContent.length > MAX_COMMENT_LENGTH) { | ||
fullCommentBody = ` | ||
The Trivy scan report is too large to display here. Please view the detailed output from the job: | ||
The Trivy ${scanTypeName} scan report${process.env.MATRIX_ID ? ` for ${process.env.MATRIX_ID}` : ''} is too large to display here. Please view the detailed output from the job: | ||
[View Trivy Report](https://github.com/${owner}/${repo}/actions/runs/${context.runId}) | ||
${commentIdentifier} | ||
`; | ||
} else { | ||
fullCommentBody = ` | ||
View the Trivy scan report below. Click on the dropdown to expand the report. | ||
View the Trivy ${scanTypeName} scan report${process.env.MATRIX_ID ? ` for ${process.env.MATRIX_ID}` : ''} below. Click on the dropdown to expand the report. | ||
${formattedContent} | ||
`; | ||
} | ||
|
@@ -206,25 +230,65 @@ runs: | |
issue_number, | ||
body: fullCommentBody, | ||
}); | ||
core.info('Created new Pr comment'); | ||
core.info('Created new PR comment'); | ||
} | ||
} | ||
- name: Notify Slack of critical vulnerabilities | ||
if: ${{ steps.trivy_report_notification.outputs.critical_vulnerabilities_count != '0' && github.ref_name == 'main' && inputs.slack-bot-token }} | ||
if: ${{ steps.trivy_report_notification.outputs.critical_vulnerabilities_count != '0' && github.ref_name == 'main' && inputs.slack-bot-token && !inputs.matrix-id }} | ||
uses: slackapi/[email protected] | ||
env: | ||
SLACK_BOT_TOKEN: ${{ inputs.slack-bot-token }} | ||
with: | ||
channel-id: ${{ inputs.slack-channel-id }} | ||
payload: | | ||
{ | ||
"blocks": [ | ||
{ | ||
"type": "section", | ||
"text": { | ||
"type": "mrkdwn", | ||
"text": ":alert: *Critical vulnerabilities detected* in Trivy ${{ inputs.scan-type }} scan. `${{ steps.trivy_report_notification.outputs.critical_vulnerabilities_count }}` critical vulnerabilities detected." | ||
} | ||
}, | ||
{ | ||
"type": "section", | ||
"fields": [ | ||
{ | ||
"type": "mrkdwn", | ||
"text": "*Repository:*\n`${{ github.repository }}`" | ||
}, | ||
{ | ||
"type": "mrkdwn", | ||
"text": "*Branch:*\n`${{ github.ref_name }}`" | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "section", | ||
"text": { | ||
"type": "mrkdwn", | ||
"text": "<${{ steps.trivy_artifact_upload.outputs.artifact-url }}|View Artifacts>" | ||
} | ||
} | ||
] | ||
} | ||
- name: Notify Slack of critical vulnerabilities (${{ inputs.matrix-id }}) | ||
if: ${{ steps.trivy_report_notification.outputs.critical_vulnerabilities_count != '0' && github.ref_name == 'main' && inputs.slack-bot-token && inputs.matrix-id }} | ||
uses: slackapi/[email protected] | ||
env: | ||
SLACK_BOT_TOKEN: ${{ inputs.slack-bot-token }} | ||
with: | ||
channel-id: "C078TPMGC21" | ||
channel-id: ${{ inputs.slack-channel-id }} | ||
payload: | | ||
{ | ||
"blocks": [ | ||
{ | ||
"type": "section", | ||
"text": { | ||
"type": "mrkdwn", | ||
"text": ":alert: *Critical vulnerabilities detected* in Trivy ${{ inputs.scan-type }} scan. ${{ steps.trivy_report_notification.outputs.critical_vulnerabilities_count }} critical vulnerabilities detected." | ||
"text": ":alert: *Critical vulnerabilities detected* in Trivy ${{ inputs.scan-type }} scan. `${{ steps.trivy_report_notification.outputs.critical_vulnerabilities_count }}` critical vulnerabilities detected." | ||
} | ||
}, | ||
{ | ||
|
@@ -237,6 +301,10 @@ runs: | |
{ | ||
"type": "mrkdwn", | ||
"text": "*Branch:*\n`${{ github.ref_name }}`" | ||
}, | ||
{ | ||
"type": "mrkdwn", | ||
"text": "*Matrix ID:*\n`${{ inputs.matrix-id }}`" | ||
} | ||
] | ||
}, | ||
|