Repository navigation
154 lines (139 loc) · 5.48 KB
/
Copy pathsecurity-scan.yml
File metadata and controls
154 lines (139 loc) · 5.48 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
name: Security scan
# Known vulnerabilities in the dependencies (NuGet, npm) and in the built container images (Trivy).
# Static analysis of our own code is in codeql.yml.
on:
pull_request:
branches: [master]
paths:
- "src/backend/**"
- "src/frontend/**"
- "themes/**"
- "deploy/azure/keycloak/**"
- "global.json"
- ".trivyignore"
- ".github/workflows/security-scan.yml"
push:
branches: [master]
paths:
- "src/backend/**"
- "src/frontend/**"
- "themes/**"
- "deploy/azure/keycloak/**"
- "global.json"
- ".trivyignore"
- ".github/workflows/security-scan.yml"
# Daily, because new advisories are published against code that hasn't changed.
schedule:
- cron: "0 4 * * *"
workflow_dispatch:
# Least privilege for the GITHUB_TOKEN; a job that needs more asks for it itself.
permissions:
contents: read
jobs:
nuget:
name: NuGet packages
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# Same SDK as the devcontainer, pinned in global.json at the repo root.
- uses: actions/setup-dotnet@0f4a354dd5547a28c70b7853dbd95d5b67886e73 # v6.1.0
with:
global-json-file: global.json
# With TreatWarningsAsErrors a vulnerable package already fails the restore (NU1901-NU1904).
# The audit is off here so the restore succeeds and the next step can list every finding.
- name: Restore
run: dotnet restore src/backend/backend.slnx -p:NuGetAudit=false
# Direct and transitive packages, any severity. Fix a transitive one with a pin in
# Directory.Packages.props ("Transitive security pins").
- name: Vulnerable packages
run: |
dotnet list src/backend/backend.slnx package --vulnerable --include-transitive
count=$(dotnet list src/backend/backend.slnx package --vulnerable --include-transitive --format json \
| jq '[.. | .vulnerabilities? // empty | .[]] | length')
if [ "$count" -gt 0 ]; then
echo "::error::$count vulnerable NuGet package advisories, listed above"
exit 1
fi
npm:
name: npm packages (${{ matrix.name }})
runs-on: ubuntu-26.04
strategy:
fail-fast: false
matrix:
include:
- name: frontend
directory: src/frontend/buddy
- name: keycloak theme
directory: themes/buddy/build
defaults:
run:
working-directory: ${{ matrix.directory }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: src/frontend/buddy/.nvmrc
# Reads package-lock.json, so nothing is installed. Dev dependencies count too: they run in
# CI and in the image builds. Low-severity advisories are listed but don't fail the job.
# Fix a transitive one with a pin in package.json "overrides".
- name: npm audit
run: npx --yes audit-ci@7.1.0 --moderate
image:
name: Container image (${{ matrix.name }})
runs-on: ubuntu-26.04
# Uploads the results to the repository's code scanning alerts.
permissions:
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
include:
# Same contexts and build arguments as deploy/docker-compose.prod.yml.
- name: api
context: src/backend
dockerfile: src/backend/buddy/Dockerfile
build-args: ""
- name: web
context: src/frontend/buddy
dockerfile: src/frontend/buddy/Dockerfile
build-args: ""
- name: keycloak
context: .
dockerfile: deploy/azure/keycloak/Dockerfile
build-args: --build-arg HEALTH_ENABLED=true
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Build image
run: >-
docker build --tag buddy-${{ matrix.name }}:scan
--file ${{ matrix.dockerfile }} ${{ matrix.build-args }} ${{ matrix.context }}
# Every severity goes to code scanning, so the Security tab shows the full picture.
- name: Scan for code scanning
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: buddy-${{ matrix.name }}:scan
scanners: vuln
format: sarif
output: trivy.sarif
trivyignores: .trivyignore
- name: Upload results
if: always() && hashFiles('trivy.sarif') != ''
uses: github/codeql-action/upload-sarif@33d7b85da1a04171e211befe2c739303b9a4c066 # v4.39.3
with:
sarif_file: trivy.sarif
category: trivy-${{ matrix.name }}
# The gate: high or critical findings that have a fixed version, i.e. a base-image digest
# bump (Dependabot) or a package update can resolve them. Accepted ones go in .trivyignore,
# each with a reason and an expiry date.
- name: Fail on fixable high and critical vulnerabilities
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: buddy-${{ matrix.name }}:scan
scanners: vuln
severity: HIGH,CRITICAL
ignore-unfixed: true
exit-code: "1"
trivyignores: .trivyignore
# Installed by the step above.
skip-setup-trivy: true