-
-
Notifications
You must be signed in to change notification settings - Fork 8
129 lines (116 loc) · 5.3 KB
/
action_publish-images-security-updates.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
name: Docker Publish (Security Updates)
on:
workflow_dispatch:
inputs:
force_build:
description: 'Force build even if no vulnerabilities found'
type: boolean
default: false
skip_scan:
description: 'Skip vulnerability scanning (for testing)'
type: boolean
default: false
schedule:
- cron: '0 0 * * *' # Daily at midnight UTC
permissions:
contents: write
jobs:
scan-vulnerabilities:
runs-on: ubuntu-24.04
outputs:
has_vulnerabilities: ${{ steps.scan.outputs.has_vulnerabilities || inputs.force_build }}
steps:
# Single scan for both vulnerabilities and dependencies
- id: scan
if: inputs.skip_scan != true
uses: aquasecurity/trivy-action@0.29.0
with:
image-ref: 'ghcr.io/serversideup/docker-ssh'
format: 'json'
output: 'trivy-results.json'
github-pat: ${{ secrets.GITHUB_TOKEN }}
ignore-unfixed: true
severity: 'CRITICAL,HIGH'
hide-progress: true
- name: Upload trivy report as a Github artifact
uses: actions/upload-artifact@v4
with:
name: trivy-results-json
path: '${{ github.workspace }}/trivy-results.json'
retention-days: 20
# Parse results to set has_vulnerabilities (for workflow control)
- if: inputs.skip_scan != true
id: parse
shell: bash
run: |
if [ -f trivy-results.json ]; then
# Count both vulnerabilities and secrets
VULN_COUNT=$(jq -r '[.Results[] | (.Vulnerabilities, .Secrets) | select(. != null) | length] | add // 0' trivy-results.json)
if [ "${VULN_COUNT:-0}" -gt 0 ]; then
echo "has_vulnerabilities='true'" >> "$GITHUB_OUTPUT"
echo "# Security Findings Found" >> $GITHUB_STEP_SUMMARY
# Handle OS/Package Vulnerabilities
if jq -e '.Results[] | select(.Vulnerabilities != null)' trivy-results.json > /dev/null; then
echo "## Package Vulnerabilities" >> $GITHUB_STEP_SUMMARY
echo "| Severity | Package | Installed Version | Fixed Version | Vulnerability ID |" >> $GITHUB_STEP_SUMMARY
echo "|----------|---------|-------------------|---------------|-----------------|" >> $GITHUB_STEP_SUMMARY
jq -r '.Results[] | select(.Vulnerabilities != null) | .Vulnerabilities[] | "| \(.Severity) | \(.PkgName) | \(.InstalledVersion) | \(.FixedVersion) | \(.VulnerabilityID) |"' trivy-results.json >> $GITHUB_STEP_SUMMARY
fi
# Handle Secrets
if jq -e '.Results[] | select(.Secrets != null)' trivy-results.json > /dev/null; then
echo "## Secrets" >> $GITHUB_STEP_SUMMARY
echo "| Severity | Category | Title | Target | Rule ID |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-----------|--------|---------|----------|" >> $GITHUB_STEP_SUMMARY
jq -r '.Results[] | select(.Secrets != null) | .Secrets[] | "| \(.Severity) | \(.Category) | \(.Title) | \(.Target) | \(.RuleID) |"' trivy-results.json >> $GITHUB_STEP_SUMMARY
fi
echo "::notice::Found ${VULN_COUNT} security findings that need to be addressed."
else
echo "has_vulnerabilities='false'" >> "$GITHUB_OUTPUT"
echo "No security findings found." >> $GITHUB_STEP_SUMMARY
fi
else
echo "has_vulnerabilities='false'" >> "$GITHUB_OUTPUT"
echo "::error::trivy-results.json not found"
exit 1
fi
get-latest-release:
runs-on: ubuntu-24.04
outputs:
release_version: ${{ steps.get-version.outputs.release_version }}
steps:
- name: Get Latest Release
id: get-version
run: |
LATEST_RELEASE=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name)
echo "release_version=${LATEST_RELEASE}" >> "$GITHUB_OUTPUT"
build-security-updates:
needs: [scan-vulnerabilities, get-latest-release]
if: needs.scan-vulnerabilities.outputs.has_vulnerabilities == 'true' || inputs.force_build == true
uses: ./.github/workflows/service_docker-build-and-publish.yml
secrets: inherit
with:
release_type: 'security'
ref_type: 'tag'
version: "${{ needs.get-latest-release.outputs.release_version }}"
notify:
needs: [build-security-updates]
runs-on: ubuntu-24.04
if: always()
steps:
- name: Notify maintainers privately
if: needs.build-security-updates.result == 'success'
uses: actions/github-script@v7
with:
script: |
await github.rest.securityAdvisories.createPrivateVulnerabilityReport({
owner: context.repo.owner,
repo: context.repo.name,
title: 'Automated Security Updates Applied',
description: `Security updates were automatically applied.\n\nAction Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.name}/actions/runs/${context.runId}`,
state: 'closed',
severity: 'low',
identifiers: [{
type: 'GHSA',
value: `GHSA-auto-${context.runId}`
}]
});