Skip to content

Commit 6382517

Browse files
committed
feat(ci): add multi-flavor image scanning and webhook triggers
1 parent 409e705 commit 6382517

2 files changed

Lines changed: 105 additions & 12 deletions

File tree

.github/workflows/container-build.yml

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ on:
1313
# Allow manual triggering
1414
workflow_dispatch:
1515

16+
# Allow triggering via external webhooks (e.g., to rebuild images regularly)
17+
repository_dispatch:
18+
types: [ trigger-container-build ]
19+
1620
permissions:
1721
contents: read
1822
packages: write
23+
# REQUIRED: Allow uploading security results to the Security tab
24+
security-events: write
1925

2026
env:
2127
REGISTRY: ghcr.io
@@ -33,6 +39,7 @@ jobs:
3339
contents: read
3440
packages: write
3541
id-token: write
42+
security-events: write # Required within the job context as well
3643

3744
steps:
3845
- name: Checkout repository
@@ -48,7 +55,7 @@ jobs:
4855
username: ${{ github.actor }}
4956
password: ${{ secrets.GITHUB_TOKEN }}
5057

51-
# Set up QEMU to enable multi-platform emulation (required for building arm64 on amd64 runners)
58+
# Set up QEMU to enable multi-platform emulation
5259
- name: Set up QEMU
5360
uses: docker/setup-qemu-action@v3
5461
with:
@@ -78,13 +85,31 @@ jobs:
7885
file: flavors/hermes/Containerfile
7986
platforms: linux/amd64,linux/arm64
8087
push: true
81-
# Instructs Buildx to map the local base image reference to the newly built GHCR image
8288
build-contexts: |
8389
ai-agent-sandbox:base=docker-image://ghcr.io/migoller/ai-agent-sandbox-base:latest
8490
tags: |
8591
ghcr.io/migoller/ai-agent-sandbox-hermes:latest
8692
ghcr.io/migoller/ai-agent-sandbox-hermes:${{ github.sha }}
8793
94+
# Step 2.5: Trivy Image Scan for Hermes
95+
- name: Run Trivy scanner on Hermes image
96+
uses: aquasecurity/trivy-action@v0.36.0
97+
with:
98+
scan-type: 'image'
99+
image-ref: '${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.HERMES_IMAGE_NAME }}:latest'
100+
format: 'sarif'
101+
output: 'trivy-hermes-results.sarif'
102+
exit-code: '0'
103+
ignore-unfixed: true
104+
severity: 'CRITICAL,HIGH'
105+
106+
- name: Upload Hermes scan results to GitHub Security tab
107+
uses: github/codeql-action/upload-sarif@v3
108+
if: always()
109+
with:
110+
sarif_file: 'trivy-hermes-results.sarif'
111+
category: 'image-hermes'
112+
88113
# Step 3: Build & Push Multi-Architecture Aider Flavor Image
89114
- name: Build and push Aider flavor
90115
uses: docker/build-push-action@v6
@@ -93,13 +118,31 @@ jobs:
93118
file: flavors/aider/Containerfile
94119
platforms: linux/amd64,linux/arm64
95120
push: true
96-
# Map the local base reference for dependency resolution
97121
build-contexts: |
98122
ai-agent-sandbox:base=docker-image://ghcr.io/migoller/ai-agent-sandbox-base:latest
99123
tags: |
100124
ghcr.io/migoller/ai-agent-sandbox-aider:latest
101125
ghcr.io/migoller/ai-agent-sandbox-aider:${{ github.sha }}
102126
127+
# Step 3.5: Trivy Image Scan for Aider
128+
- name: Run Trivy scanner on Aider image
129+
uses: aquasecurity/trivy-action@v0.36.0
130+
with:
131+
scan-type: 'image'
132+
image-ref: '${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.AIDER_IMAGE_NAME }}:latest'
133+
format: 'sarif'
134+
output: 'trivy-aider-results.sarif'
135+
exit-code: '0'
136+
ignore-unfixed: true
137+
severity: 'CRITICAL,HIGH'
138+
139+
- name: Upload Aider scan results to GitHub Security tab
140+
uses: github/codeql-action/upload-sarif@v3
141+
if: always()
142+
with:
143+
sarif_file: 'trivy-aider-results.sarif'
144+
category: 'image-aider'
145+
103146
# Step 4: Build & Push Multi-Architecture Claude-Code Flavor Image
104147
- name: Build and push Claude-Code flavor
105148
uses: docker/build-push-action@v6
@@ -108,14 +151,32 @@ jobs:
108151
file: flavors/claude-code/Containerfile
109152
platforms: linux/amd64,linux/arm64
110153
push: true
111-
# Map the local base reference for dependency resolution
112154
build-contexts: |
113155
ai-agent-sandbox:base=docker-image://ghcr.io/migoller/ai-agent-sandbox-base:latest
114156
tags: |
115157
ghcr.io/migoller/ai-agent-sandbox-claude-code:latest
116158
ghcr.io/migoller/ai-agent-sandbox-claude-code:${{ github.sha }}
159+
160+
# Step 4.5: Trivy Image Scan for Claude-Code
161+
- name: Run Trivy scanner on Claude-Code image
162+
uses: aquasecurity/trivy-action@v0.36.0
163+
with:
164+
scan-type: 'image'
165+
image-ref: '${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.CLAUDE_IMAGE_NAME }}:latest'
166+
format: 'sarif'
167+
output: 'trivy-claude-results.sarif'
168+
exit-code: '0'
169+
ignore-unfixed: true
170+
severity: 'CRITICAL,HIGH'
171+
172+
- name: Upload Claude-Code scan results to GitHub Security tab
173+
uses: github/codeql-action/upload-sarif@v3
174+
if: always()
175+
with:
176+
sarif_file: 'trivy-claude-results.sarif'
177+
category: 'image-claude-code'
117178

118-
# 5. Generate Dynamic Release Summary (Directly visible in GitHub Actions UI)
179+
# 5. Generate Dynamic Release Summary
119180
- name: Create release notes summary
120181
run: |
121182
{
@@ -128,4 +189,4 @@ jobs:
128189
echo "- **Hermes:** \`${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.HERMES_IMAGE_NAME }}:latest\`"
129190
echo "- **Aider:** \`${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.AIDER_IMAGE_NAME }}:latest\`"
130191
echo "- **Claude Code:** \`${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ env.CLAUDE_IMAGE_NAME }}:latest\`"
131-
} >> $GITHUB_STEP_SUMMARY
192+
} >> $GITHUB_STEP_SUMMARY

.github/workflows/security-scan.yml

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,67 @@ on:
99
repository_dispatch:
1010
types: [ trigger-security-scan ]
1111

12+
env:
13+
REGISTRY: ghcr.io
14+
IMAGE_OWNER: migoller
15+
1216
jobs:
17+
# Job 1: Our existing repository file scan
1318
static-analysis:
1419
name: Repository Static Scan
1520
runs-on: ubuntu-latest
1621
permissions:
1722
security-events: write
1823
contents: read
19-
2024
steps:
2125
- name: Checkout repository
2226
uses: actions/checkout@v4
2327

24-
# Scan the repository and output findings as a SARIF file
2528
- name: Run Trivy vulnerability scanner (SARIF Mode)
2629
uses: aquasecurity/trivy-action@v0.36.0
2730
with:
2831
scan-type: 'fs'
2932
scan-ref: '.'
3033
format: 'sarif'
3134
output: 'trivy-results.sarif'
32-
# Always use '0' to guarantee that the SARIF report is generated and uploaded successfully
3335
exit-code: '0'
3436
ignore-unfixed: true
3537
severity: 'CRITICAL,HIGH'
3638
scanners: 'vuln,misconfig,secret'
3739

38-
# Upload the SARIF file directly into GitHub's Native Security Dashboard
3940
- name: Upload Trivy scan results to GitHub Security tab
4041
uses: github/codeql-action/upload-sarif@v3
41-
if: always() # Ensures reports are uploaded even if something else unexpected happens
42+
if: always()
43+
with:
44+
sarif_file: 'trivy-results.sarif'
45+
46+
# Job 2: New periodic scan for published GHCR images
47+
registry-image-scan:
48+
name: GHCR Registry Image Scan
49+
runs-on: ubuntu-latest
50+
permissions:
51+
security-events: write
52+
packages: read
53+
strategy:
54+
fail-fast: false
55+
matrix:
56+
flavor: [hermes, aider, claude-code]
57+
steps:
58+
# We don't even need to checkout the code here, we just pull and check the image directly!
59+
- name: Run Trivy scanner on GHCR ${{ matrix.flavor }} image
60+
uses: aquasecurity/trivy-action@v0.36.0
61+
with:
62+
scan-type: 'image'
63+
image-ref: '${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/ai-agent-sandbox-${{ matrix.flavor }}:latest'
64+
format: 'sarif'
65+
output: 'trivy-${{ matrix.flavor }}-registry.sarif'
66+
exit-code: '0'
67+
ignore-unfixed: true
68+
severity: 'CRITICAL,HIGH'
69+
70+
- name: Upload Registry scan results to GitHub Security tab
71+
uses: github/codeql-action/upload-sarif@v3
72+
if: always()
4273
with:
43-
sarif_file: 'trivy-results.sarif'
74+
sarif_file: 'trivy-${{ matrix.flavor }}-registry.sarif'
75+
category: 'registry-${{ matrix.flavor }}'

0 commit comments

Comments
 (0)