Skip to content

Commit 67d4ab2

Browse files
authored
feat: Comprehensive security upgrades and ML stack modernization (#89)
Squashing all commits into a comprehensive single commit for clean history
1 parent 002f221 commit 67d4ab2

23 files changed

+2135
-84
lines changed

.github/workflows/pre-commit.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Pre-commit Checks
2+
3+
on:
4+
push:
5+
branches: [master, main, develop]
6+
pull_request:
7+
branches: [master, main, develop]
8+
9+
jobs:
10+
pre-commit:
11+
name: Run Pre-commit Hooks
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: '3.11'
23+
cache: 'pip'
24+
25+
- name: Set up Node.js
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: '20'
29+
cache: 'npm'
30+
cache-dependency-path: frontend/package-lock.json
31+
32+
- name: Install system dependencies
33+
run: |
34+
sudo apt-get update
35+
sudo apt-get install -y shellcheck
36+
37+
- name: Install Python dependencies
38+
run: |
39+
python -m pip install --upgrade pip
40+
pip install pre-commit
41+
42+
- name: Cache pre-commit environments
43+
uses: actions/cache@v4
44+
with:
45+
path: ~/.cache/pre-commit
46+
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
47+
restore-keys: |
48+
pre-commit-
49+
50+
- name: Run pre-commit
51+
run: pre-commit run --all-files --show-diff-on-failure
52+
53+
- name: Generate pre-commit summary
54+
if: always()
55+
run: |
56+
echo "## Pre-commit Check Results" >> $GITHUB_STEP_SUMMARY
57+
echo "" >> $GITHUB_STEP_SUMMARY
58+
echo "Pre-commit hooks executed on all files." >> $GITHUB_STEP_SUMMARY
59+
echo "" >> $GITHUB_STEP_SUMMARY
60+
echo "### Hooks Executed:" >> $GITHUB_STEP_SUMMARY
61+
echo "- Code formatting (Ruff, Prettier)" >> $GITHUB_STEP_SUMMARY
62+
echo "- Linting (Ruff, mypy, ESLint)" >> $GITHUB_STEP_SUMMARY
63+
echo "- Security checks (Gitleaks, Bandit)" >> $GITHUB_STEP_SUMMARY
64+
echo "- Shell script validation (shellcheck)" >> $GITHUB_STEP_SUMMARY
65+
echo "- Dockerfile linting (Hadolint)" >> $GITHUB_STEP_SUMMARY
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
name: Security Scanning
2+
3+
on:
4+
push:
5+
branches: [master, main, develop]
6+
paths:
7+
- 'backend/**'
8+
- 'frontend/**'
9+
- '**/Dockerfile*'
10+
- '.github/workflows/security-scan.yml'
11+
pull_request:
12+
branches: [master, main, develop]
13+
paths:
14+
- 'backend/**'
15+
- 'frontend/**'
16+
- '**/Dockerfile*'
17+
- '.github/workflows/security-scan.yml'
18+
schedule:
19+
# Run weekly security scans on Sundays at 00:00 UTC
20+
- cron: '0 0 * * 0'
21+
workflow_dispatch:
22+
inputs:
23+
component:
24+
description: 'Component to scan (backend, frontend, or all)'
25+
required: false
26+
default: 'all'
27+
type: choice
28+
options:
29+
- all
30+
- backend
31+
- frontend
32+
33+
jobs:
34+
dockerfile-lint:
35+
name: Lint Dockerfiles
36+
runs-on: ubuntu-latest
37+
steps:
38+
- name: Checkout code
39+
uses: actions/checkout@v4
40+
41+
- name: Run Hadolint on backend Dockerfile
42+
uses: hadolint/hadolint-action@v3.1.0
43+
with:
44+
dockerfile: backend/Dockerfile.prod
45+
config: .hadolint.yaml
46+
failure-threshold: warning
47+
48+
- name: Run Hadolint on frontend Dockerfile
49+
uses: hadolint/hadolint-action@v3.1.0
50+
with:
51+
dockerfile: frontend/Dockerfile.prod
52+
config: .hadolint.yaml
53+
failure-threshold: warning
54+
55+
build-and-scan-backend:
56+
name: Build & Scan Backend
57+
runs-on: ubuntu-latest
58+
permissions:
59+
contents: read
60+
security-events: write
61+
steps:
62+
- name: Checkout code
63+
uses: actions/checkout@v4
64+
65+
- name: Set up Docker Buildx
66+
uses: docker/setup-buildx-action@v3
67+
68+
- name: Build backend image
69+
uses: docker/build-push-action@v5
70+
with:
71+
context: ./backend
72+
file: ./backend/Dockerfile.prod
73+
tags: opentranscribe-backend:${{ github.sha }}
74+
load: true
75+
cache-from: type=gha
76+
cache-to: type=gha,mode=max
77+
78+
- name: Run Trivy vulnerability scanner
79+
uses: aquasecurity/trivy-action@master
80+
with:
81+
image-ref: opentranscribe-backend:${{ github.sha }}
82+
format: 'sarif'
83+
output: 'trivy-backend-results.sarif'
84+
severity: 'CRITICAL,HIGH,MEDIUM'
85+
86+
- name: Upload Trivy results to GitHub Security tab
87+
uses: github/codeql-action/upload-sarif@v3
88+
if: always()
89+
with:
90+
sarif_file: 'trivy-backend-results.sarif'
91+
category: 'trivy-backend'
92+
93+
- name: Run Trivy vulnerability scanner (table output)
94+
uses: aquasecurity/trivy-action@master
95+
with:
96+
image-ref: opentranscribe-backend:${{ github.sha }}
97+
format: 'table'
98+
severity: 'CRITICAL,HIGH,MEDIUM'
99+
100+
- name: Run Dockle
101+
uses: erzz/dockle-action@v1
102+
with:
103+
image: opentranscribe-backend:${{ github.sha }}
104+
exit-code: '0'
105+
failure-threshold: warn
106+
107+
- name: Generate SBOM with Syft
108+
uses: anchore/sbom-action@v0
109+
with:
110+
image: opentranscribe-backend:${{ github.sha }}
111+
artifact-name: backend-sbom.spdx.json
112+
output-file: backend-sbom.spdx.json
113+
114+
- name: Scan SBOM with Grype
115+
uses: anchore/scan-action@v3
116+
with:
117+
sbom: backend-sbom.spdx.json
118+
fail-build: false
119+
severity-cutoff: medium
120+
121+
- name: Upload SBOM artifact
122+
uses: actions/upload-artifact@v4
123+
if: always()
124+
with:
125+
name: backend-sbom
126+
path: backend-sbom.spdx.json
127+
retention-days: 90
128+
129+
build-and-scan-frontend:
130+
name: Build & Scan Frontend
131+
runs-on: ubuntu-latest
132+
permissions:
133+
contents: read
134+
security-events: write
135+
steps:
136+
- name: Checkout code
137+
uses: actions/checkout@v4
138+
139+
- name: Set up Docker Buildx
140+
uses: docker/setup-buildx-action@v3
141+
142+
- name: Build frontend image
143+
uses: docker/build-push-action@v5
144+
with:
145+
context: ./frontend
146+
file: ./frontend/Dockerfile.prod
147+
tags: opentranscribe-frontend:${{ github.sha }}
148+
load: true
149+
cache-from: type=gha
150+
cache-to: type=gha,mode=max
151+
152+
- name: Run Trivy vulnerability scanner
153+
uses: aquasecurity/trivy-action@master
154+
with:
155+
image-ref: opentranscribe-frontend:${{ github.sha }}
156+
format: 'sarif'
157+
output: 'trivy-frontend-results.sarif'
158+
severity: 'CRITICAL,HIGH,MEDIUM'
159+
160+
- name: Upload Trivy results to GitHub Security tab
161+
uses: github/codeql-action/upload-sarif@v3
162+
if: always()
163+
with:
164+
sarif_file: 'trivy-frontend-results.sarif'
165+
category: 'trivy-frontend'
166+
167+
- name: Run Trivy vulnerability scanner (table output)
168+
uses: aquasecurity/trivy-action@master
169+
with:
170+
image-ref: opentranscribe-frontend:${{ github.sha }}
171+
format: 'table'
172+
severity: 'CRITICAL,HIGH,MEDIUM'
173+
174+
- name: Run Dockle
175+
uses: erzz/dockle-action@v1
176+
with:
177+
image: opentranscribe-frontend:${{ github.sha }}
178+
exit-code: '0'
179+
failure-threshold: warn
180+
181+
- name: Generate SBOM with Syft
182+
uses: anchore/sbom-action@v0
183+
with:
184+
image: opentranscribe-frontend:${{ github.sha }}
185+
artifact-name: frontend-sbom.spdx.json
186+
output-file: frontend-sbom.spdx.json
187+
188+
- name: Scan SBOM with Grype
189+
uses: anchore/scan-action@v3
190+
with:
191+
sbom: frontend-sbom.spdx.json
192+
fail-build: false
193+
severity-cutoff: medium
194+
195+
- name: Upload SBOM artifact
196+
uses: actions/upload-artifact@v4
197+
if: always()
198+
with:
199+
name: frontend-sbom
200+
path: frontend-sbom.spdx.json
201+
retention-days: 90
202+
203+
dependency-scan:
204+
name: Scan Dependencies
205+
runs-on: ubuntu-latest
206+
steps:
207+
- name: Checkout code
208+
uses: actions/checkout@v4
209+
210+
- name: Run Trivy vulnerability scanner on repository
211+
uses: aquasecurity/trivy-action@master
212+
with:
213+
scan-type: 'fs'
214+
scan-ref: '.'
215+
format: 'table'
216+
severity: 'CRITICAL,HIGH'
217+
skip-dirs: 'node_modules,venv,.venv'
218+
219+
- name: Run Trivy config scanner
220+
uses: aquasecurity/trivy-action@master
221+
with:
222+
scan-type: 'config'
223+
scan-ref: '.'
224+
format: 'table'
225+
severity: 'CRITICAL,HIGH'
226+
skip-dirs: 'node_modules,venv,.venv'
227+
228+
summary:
229+
name: Security Scan Summary
230+
runs-on: ubuntu-latest
231+
needs: [dockerfile-lint, build-and-scan-backend, build-and-scan-frontend, dependency-scan]
232+
if: always()
233+
steps:
234+
- name: Check scan results
235+
run: |
236+
echo "## Security Scan Summary" >> $GITHUB_STEP_SUMMARY
237+
echo "" >> $GITHUB_STEP_SUMMARY
238+
echo "All security scans completed. Check individual job logs for details." >> $GITHUB_STEP_SUMMARY
239+
echo "" >> $GITHUB_STEP_SUMMARY
240+
echo "### Completed Scans:" >> $GITHUB_STEP_SUMMARY
241+
echo "- ✅ Dockerfile Linting (Hadolint)" >> $GITHUB_STEP_SUMMARY
242+
echo "- ✅ Backend Image Scanning (Trivy, Dockle, Grype)" >> $GITHUB_STEP_SUMMARY
243+
echo "- ✅ Frontend Image Scanning (Trivy, Dockle, Grype)" >> $GITHUB_STEP_SUMMARY
244+
echo "- ✅ Dependency Scanning (Trivy)" >> $GITHUB_STEP_SUMMARY
245+
echo "" >> $GITHUB_STEP_SUMMARY
246+
echo "### Reports Available:" >> $GITHUB_STEP_SUMMARY
247+
echo "- SBOM artifacts uploaded for both backend and frontend" >> $GITHUB_STEP_SUMMARY
248+
echo "- Vulnerability results uploaded to GitHub Security tab" >> $GITHUB_STEP_SUMMARY

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# OpenTranscribe .gitignore
22

33
.github/DRAFT_ISSUES/
4+
offline-package-build/
5+
security-reports-*
46

57
# Environment variables
68
.env
@@ -238,3 +240,4 @@ frontend/static/ffmpeg/
238240

239241
# Private project management files
240242
GITHUB_OPTIMIZATION_TASKS.md
243+
security-reports/

.hadolint.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Hadolint configuration for OpenTranscribe Dockerfiles
2+
# https://github.com/hadolint/hadolint
3+
4+
# Ignore specific rules
5+
ignored:
6+
- DL3008 # Pin versions in apt-get install (Debian/Ubuntu)
7+
- DL3009 # Delete the apt-get lists after installing (already handled)
8+
- DL3015 # Additional packages by --no-install-recommends (sometimes we need them)
9+
- DL3018 # Pin versions in apk add (Alpine - can break builds)
10+
- DL3059 # Multiple consecutive RUN instructions (acceptable for layer caching)
11+
12+
# Trust specific registries
13+
trustedRegistries:
14+
- docker.io
15+
- ghcr.io
16+
- nvcr.io
17+
18+
# Override default rules severity
19+
override:
20+
error:
21+
- DL3002 # Do not switch to root USER
22+
- DL3020 # Use COPY instead of ADD for files and folders
23+
- DL4006 # Set SHELL option -o pipefail before RUN with pipe
24+
warning:
25+
- DL3003 # Use WORKDIR to switch to a directory
26+
- DL3007 # Using latest tag for image
27+
- DL3042 # Avoid cache directory with pip
28+
info:
29+
- DL3013 # Pin versions in pip install
30+
- DL3016 # Pin versions in npm install
31+
32+
# Strict mode - warn on all other issues
33+
failure-threshold: warning

0 commit comments

Comments
 (0)