Skip to content

Commit 8ac6dfa

Browse files
authored
Merge branch 'master' into main
2 parents f5b54a8 + 82a8bc6 commit 8ac6dfa

File tree

7 files changed

+122
-7
lines changed

7 files changed

+122
-7
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- [ ] CI build and Trivy scan passed
2+
- [ ] No CRITICAL or HIGH vulnerabilities reported in Trivy artifact (check `trivy-report.json`)
3+
- [ ] If vulnerabilities exist, describe mitigation plan in PR body (package bump, patch, or suppression rationale)
4+
- [ ] Tag security owner for review if findings are non-trivial
5+
6+
Note: The workflow uploads `trivy-report.json` as an artifact on each run. Use that JSON for automated parsing or manual triage.

.github/workflows/docker-build-scan-publish.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,18 @@ jobs:
4141
uses: aquasecurity/trivy-action@v2
4242
with:
4343
image-ref: secure-gemini-cli:latest
44-
format: table
44+
format: json
45+
output: trivy-report.json
4546
severity: CRITICAL,HIGH
4647
exit-code: '1'
4748

49+
- name: Upload Trivy JSON report
50+
if: always()
51+
uses: actions/upload-artifact@v4
52+
with:
53+
name: trivy-report
54+
path: trivy-report.json
55+
4856
release-publish:
4957
name: Release: build, scan and publish
5058
runs-on: ubuntu-latest
@@ -73,10 +81,18 @@ jobs:
7381
uses: aquasecurity/trivy-action@v2
7482
with:
7583
image-ref: secure-gemini-cli:latest
76-
format: table
84+
format: json
85+
output: trivy-report.json
7786
severity: CRITICAL,HIGH
7887
exit-code: '1'
7988

89+
- name: Upload Trivy JSON report
90+
if: always()
91+
uses: actions/upload-artifact@v4
92+
with:
93+
name: trivy-report
94+
path: trivy-report.json
95+
8096
- name: Login to GHCR
8197
uses: docker/login-action@v2
8298
with:

.github/workflows/docker-build-scan.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ jobs:
3131
uses: aquasecurity/trivy-action@v2
3232
with:
3333
image-ref: secure-gemini-cli:latest
34-
format: table
34+
format: json
35+
output: trivy-report.json
3536
severity: CRITICAL,HIGH
3637
exit-code: '1'
38+
39+
- name: Upload Trivy JSON report
40+
if: always()
41+
uses: actions/upload-artifact@v4
42+
with:
43+
name: trivy-report
44+
path: trivy-report.json

.github/workflows/release.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# .github/workflows/release.yml
2+
3+
name: Secure Release Publisher
4+
5+
# This workflow is triggered ONLY when a new release is created in the GitHub UI.
6+
# This provides a manual gate for production releases.
7+
on:
8+
release:
9+
types: [created]
10+
11+
# CRITICAL: Define the permissions for the job.
12+
# This enforces the Principle of Least Privilege. The GITHUB_TOKEN will have ONLY these permissions.
13+
permissions:
14+
contents: read # Required to check out the repository's code.
15+
packages: write # Required to publish packages (Docker images) to GHCR.
16+
17+
jobs:
18+
build-and-publish:
19+
runs-on: ubuntu-latest
20+
steps:
21+
# 1. Check out the repository code
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
# 2. Log in to the Container Registry
26+
# --- CHOOSE ONE OF THE FOLLOWING TWO OPTIONS ---
27+
28+
# OPTION A: Log in to GitHub Container Registry (GHCR)
29+
# This is the most secure and integrated method if using GHCR.
30+
- name: Log in to GHCR
31+
uses: docker/login-action@v3
32+
with:
33+
registry: ghcr.io
34+
username: ${{ github.repository_owner }}
35+
password: ${{ secrets.GITHUB_TOKEN }} # Use the auto-generated, scoped token
36+
37+
# OPTION B: Log in to Docker Hub
38+
# Uncomment this step if you are using Docker Hub.
39+
# - name: Log in to Docker Hub
40+
# uses: docker/login-action@v3
41+
# with:
42+
# username: ${{ secrets.DOCKERHUB_USERNAME }}
43+
# password: ${{ secrets.DOCKERHUB_TOKEN }}
44+
45+
# 3. Generate metadata for the Docker image (tags, labels)
46+
# This action creates tags based on the Git release version (e.g., v1.0.0)
47+
- name: Extract Docker metadata
48+
id: meta
49+
uses: docker/metadata-action@v5
50+
with:
51+
images: |
52+
# For GHCR, format is ghcr.io/OWNER/REPO_NAME
53+
ghcr.io/${{ github.repository }}
54+
# For Docker Hub, format is USERNAME/REPO_NAME
55+
# kalvinparker/secure-gemini
56+
57+
# 4. Build and Push the Docker Image
58+
# This step re-uses our approved, secure Dockerfile. It will run 'npm audit' as a security gate.
59+
# If the audit fails, this step will fail, and the insecure image will not be published.
60+
- name: Build and push Docker image
61+
uses: docker/build-push-action@v5
62+
with:
63+
context: .
64+
push: true
65+
tags: ${{ steps.meta.outputs.tags }}
66+
labels: ${{ steps.meta.outputs.labels }}

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ RUN npm audit
2121

2222
# Set the final entrypoint for the CLI
2323
ENTRYPOINT ["npx", "gemini"]
24+

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 kalvinparker
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ This repository contains a minimal, security-conscious Docker image for running
1414
```markdown
1515
# secure-gemini
1616
17-
![CI](https://img.shields.io/badge/CI-GitHub%20Actions-blue)
18-
![Trivy](https://img.shields.io/badge/Trivy-Scan%20Saved-brightgreen)
19-
2017
This repository contains a minimal, security-conscious Docker image for running the Google Gemini CLI (`@google/gemini-cli`). The image is built on `node:22-alpine`, uses a non-root user, upgrades base packages, updates npm, and runs `npm audit` during the image build as a security gate.
2118
2219
## What is included
@@ -60,7 +57,7 @@ If `npm audit` fails during the Docker build (it may, depending on transient vul
6057
RUN npm audit --audit-level=moderate || true
6158
```
6259

63-
We recommend addressing audit findings before publishing the image.
60+
I recommend addressing audit findings before publishing the image.
6461

6562
## Run
6663

0 commit comments

Comments
 (0)