Compare commits

..

1 Commits

Author SHA1 Message Date
Paperclip c85c9b12a7 feat(ci): add Trivy image vulnerability scanning to all Docker builds
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-14 15:21:08 +00:00
6 changed files with 48 additions and 76 deletions
+36 -43
View File
@@ -163,20 +163,20 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Scan frontend image for vulnerabilities
uses: anchore/scan-action@v5
id: scan
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.28.0
with:
image: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ github.sha }}"
fail-build: true
severity-cutoff: high
output-format: sarif
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ github.sha }}
format: 'sarif'
output: 'trivy-results-frontend.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'
- name: Upload frontend scan results to GitHub Security
- name: Upload Trivy scan results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
sarif_file: 'trivy-results-frontend.sarif'
- name: Push Docker image
if: github.event_name == 'push'
@@ -186,7 +186,6 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
target: prod
cache-from: type=gha
- name: Create git tag
@@ -256,23 +255,21 @@ jobs:
load: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Scan auth image for vulnerabilities
uses: anchore/scan-action@v5
id: scan
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.28.0
with:
image: "${{ env.REGISTRY }}/${{ env.AUTH_IMAGE_NAME }}:sha-${{ github.sha }}"
fail-build: true
severity-cutoff: high
output-format: sarif
image-ref: ${{ env.REGISTRY }}/${{ env.AUTH_IMAGE_NAME }}:sha-${{ github.sha }}
format: 'sarif'
output: 'trivy-results-auth.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'
- name: Upload auth scan results to GitHub Security
- name: Upload Trivy scan results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
sarif_file: 'trivy-results-auth.sarif'
- name: Push Docker image
if: github.event_name == 'push'
@@ -341,23 +338,21 @@ jobs:
load: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Scan receiptwitness image for vulnerabilities
uses: anchore/scan-action@v5
id: scan
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.28.0
with:
image: "${{ env.REGISTRY }}/${{ env.RECEIPTWITNESS_IMAGE_NAME }}:sha-${{ github.sha }}"
fail-build: true
severity-cutoff: high
output-format: sarif
image-ref: ${{ env.REGISTRY }}/${{ env.RECEIPTWITNESS_IMAGE_NAME }}:sha-${{ github.sha }}
format: 'sarif'
output: 'trivy-results-receiptwitness.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'
- name: Upload receiptwitness scan results to GitHub Security
- name: Upload Trivy scan results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
sarif_file: 'trivy-results-receiptwitness.sarif'
- name: Push Docker image
if: github.event_name == 'push'
@@ -426,23 +421,21 @@ jobs:
load: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Scan api image for vulnerabilities
uses: anchore/scan-action@v5
id: scan
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.28.0
with:
image: "${{ env.REGISTRY }}/${{ env.API_IMAGE_NAME }}:sha-${{ github.sha }}"
fail-build: true
severity-cutoff: high
output-format: sarif
image-ref: ${{ env.REGISTRY }}/${{ env.API_IMAGE_NAME }}:sha-${{ github.sha }}
format: 'sarif'
output: 'trivy-results-api.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'
- name: Upload api scan results to GitHub Security
- name: Upload Trivy scan results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
sarif_file: 'trivy-results-api.sarif'
- name: Push Docker image
if: github.event_name == 'push'
+6 -12
View File
@@ -4,23 +4,17 @@ import pg from "pg";
const { Pool } = pg;
const pool = new Pool({
connectionString:
process.env.DATABASE_URL ??
"postgresql://cartsnitch:cartsnitch@localhost:5432/cartsnitch",
});
const secret = process.env.BETTER_AUTH_SECRET;
if (!secret) {
throw new Error("BETTER_AUTH_SECRET environment variable is required");
}
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
console.warn(
"WARNING: DATABASE_URL is not set — using default localhost connection. " +
"Set DATABASE_URL for production deployments."
);
}
export const pool = new Pool({
connectionString: databaseUrl ?? "postgresql://cartsnitch:cartsnitch@localhost:5432/cartsnitch",
});
export const auth = betterAuth({
database: pool,
basePath: "/auth",
+3 -17
View File
@@ -1,6 +1,6 @@
import { createServer } from "node:http";
import { toNodeHandler } from "better-auth/node";
import { auth, pool } from "./auth.js";
import { auth } from "./auth.js";
const port = parseInt(process.env.PORT ?? "3001", 10);
@@ -9,22 +9,8 @@ const handler = toNodeHandler(auth);
const server = createServer(async (req, res) => {
// Health check
if (req.url === "/health" && req.method === "GET") {
try {
const client = await pool.connect();
try {
await Promise.race([
client.query("SELECT 1"),
new Promise((_, reject) => setTimeout(() => reject(new Error("DB timeout")), 2000)),
]);
} finally {
client.release();
}
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ status: "ok", db: "connected" }));
} catch {
res.writeHead(503, { "Content-Type": "application/json" });
res.end(JSON.stringify({ status: "error", db: "unreachable" }));
}
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ status: "ok" }));
return;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Submodule cartsnitch deleted from a53daddb9a
+3 -3
View File
@@ -9805,9 +9805,9 @@
}
},
"node_modules/vite": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz",
"integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==",
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"devOptional": true,
"license": "MIT",
"dependencies": {