From 81eda53a594f446d5926b014352a3f6ad16f3def Mon Sep 17 00:00:00 2001 From: Timo Behrendt Date: Fri, 10 Apr 2026 18:43:03 +0200 Subject: [PATCH] refactor(setup-db): to run trivy in docker (#54) As part of our safety initiative, I'm refactoring setup-db to run trivy inside a Docker container with minimal privileges, reducing leakage of secrets, files, etc. to a minimum in case the dependency gets compromised. Additionally, we are always pinning the trivy docker image to a fixed digest. Renovate has been configured to keep the Trivy image version up-to-date. Reviewed-on: https://gitea.t000-n.de/t.behrendt/sec-actions/pulls/54 Reviewed-by: branch-buddy Co-authored-by: Timo Behrendt Co-committed-by: Timo Behrendt --- renovate.json | 11 +++++++++++ setup-db/README.md | 13 +++++++++---- setup-db/action.yaml | 23 ++++++++++++++++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/renovate.json b/renovate.json index 75c1077..f2dade3 100644 --- a/renovate.json +++ b/renovate.json @@ -4,6 +4,17 @@ "local>t.behrendt/renovate-configs:common", "local>t.behrendt/renovate-configs:action" ], + "customManagers": [ + { + "customType": "regex", + "description": "Update Trivy docker image", + "managerFilePatterns": ["/(^|/)setup-db/action\\.ya?ml$/"], + "datasourceTemplate": "docker", + "matchStrings": [ + "default:\\s*\"(?ghcr\\.io/aquasecurity/trivy):(?[\\d\\.]+)(?:@(?sha256:[a-f0-9]+))?\"" + ] + } + ], "packageRules": [ { "matchManagers": ["dockerfile", "kubernetes", "helmfile", "helm-values"], diff --git a/setup-db/README.md b/setup-db/README.md index 4f59fa2..d6028ba 100644 --- a/setup-db/README.md +++ b/setup-db/README.md @@ -2,7 +2,9 @@ A reusable Gitea Action that sets up the Trivy vulnerability database, restoring from cache if available. -**Note:** This action only sets up the database. Trivy itself must be installed separately (e.g., using the `setup-trivy` action). +The action runs Trivy inside **Docker** with a restricted container configuration so the Trivy runtime is isolated from the host while the database is downloaded into your cache directory. + +**Note:** This action only prepares the vulnerability database. If you run Trivy on the runner host for scans (for example `trivy fs .`), install Trivy separately (e.g. with a `setup-trivy` action or your own step). ## Usage @@ -36,6 +38,9 @@ jobs: ## Inputs -| Input | Description | Required | Default | -| ----------- | --------------------------------- | -------- | ---------------- | -| `cache-dir` | Path to the Trivy cache directory | No | `~/.cache/trivy` | +| Input | Description | Required | Default | +| ---------------- | --------------------------------------------------------------------------- | -------- | ------- | +| `cache-dir` | Path to the Trivy cache directory | No | `${{ runner.temp }}/trivy` | +| `trivy-version` | Docker image reference for Trivy (digest pin recommended) | No | Pinned `ghcr.io/aquasecurity/trivy` image in `action.yaml` | + +**`trivy-version` is optional.** If you omit it, the action uses the default image (version and digest) from `action.yaml`. Set it only when you need a different Trivy image or your own digest pin. diff --git a/setup-db/action.yaml b/setup-db/action.yaml index 889f3bd..8f4ac21 100644 --- a/setup-db/action.yaml +++ b/setup-db/action.yaml @@ -10,6 +10,10 @@ inputs: description: "Path to the Trivy cache directory (default: ${{runner.temp}}/trivy)" required: false default: "${{ runner.temp }}/trivy" + trivy-version: + description: "Trivy docker image version to use (full image reference including digest is recommended)" + required: false + default: "ghcr.io/aquasecurity/trivy:0.69.3@sha256:bcc376de8d77cfe086a917230e818dc9f8528e3c852f7b1aff648949b6258d1c" outputs: cache-dir: @@ -32,4 +36,21 @@ runs: trivy-db-${{ steps.current-date.outputs.current-date }} - if: steps.restore-db.outputs.cache-hit != 'true' shell: bash - run: trivy fs --download-db-only --cache-dir "${{ inputs.cache-dir }}" + run: | + docker run --rm \ + --name trivy-db-download \ + --user "$(id -u):$(id -g)" \ + --read-only \ + --env-file /dev/null \ + --cap-drop ALL \ + --pids-limit 64 \ + --memory=512m \ + --memory-swap=512m \ + --cpus=1 \ + --ipc private \ + --cgroupns private \ + --security-opt no-new-privileges \ + --security-opt apparmor=docker-default \ + --tmpfs /tmp:rw,noexec,nosuid,nodev,size=1g \ + --mount type=bind,src=${{ inputs.cache-dir }},dst=/cache \ + ${{ inputs.trivy-version }} fs --download-db-only --cache-dir /cache