Scan Docker images before deploy with the new Security Audit action

Buddy now has a Security Audit action that scans your Docker image with Trivy between the build and the push to the registry. If it finds a vulnerability that already has a fix, it fails the run.

What the action does

Security Audit is Trivy configured in a form instead of CLI flags. You set:

  • scan type - image, filesystem, or rootfs,
  • scanners - vulnerabilities, secrets, misconfigurations, licenses,
  • severities - from UNKNOWN to CRITICAL,
  • fail only on fixable - fail only on vulnerabilities with a fix available,
  • ignore rules - for a CVE, a rule, a secret, or a license, with a statement and an expiry date.

Image loading...Security Audit action settings

Pick the scan type based on the pipeline stage:

Type What it checks When
Container image OS packages and dependencies baked into the image after the build, before the push
Filesystem manifests and lockfiles in the repo (package-lock.json, pom.xml, go.mod), excluding .jar, .war, and .ear files before the build
Rootfs build output or an unpacked image, including binaries such as JARs after the build

The image can come from a previous action, a public or private registry, or the Artifact Registry. If you prefer to write trivy commands yourself, use the Trivy CLI action. Security Audit needs no script and no .trivyignore file.

Demo

The project is an orders API on Express 4.17.1, built on node:18.12-alpine. The pipeline has three actions: image build, Security Audit, and push to the Buddy registry.

Image loading...Pipeline: build, Security Audit, push

yaml
- action: Build Docker image type: DOCKERFILE dockerfile_path: Dockerfile context_path: . docker_image_tag: $BUDDY_RUN_ID - action: Security audit type: SECURITY_AUDIT scan: type: IMAGE image: image_location: ACTION from_action: Build Docker image scanners: - VULNERABILITY - SECRET severities: - MEDIUM - HIGH - CRITICAL fail_only_on_fixable: true - action: Push Docker image type: DOCKER_PUSH docker_build_action_name: Build Docker image docker_registry: ARTIFACT_REGISTRY artifact: orders-api

image_location: ACTION scans the image built earlier in the same run, so the push only happens after the scan.

Image loading...Push Docker image action settings

Run 1: push blocked

The scan reported dozens of vulnerabilities:

  • base image: openssl, musl, busybox,
  • app dependencies: express, body-parser, path-to-regexp, qs,
  • npm bundled in the image: tar, including one CRITICAL.

The push never ran.

Image loading...Run failed on the Security Audit action

Vulnerabilities in ip and http-cache-semantics have no fix yet, so with fail_only_on_fixable: true they don't fail the run.

The fix

dockerfile
FROM node:24-alpine WORKDIR /app COPY package.json ./ RUN npm install --omit=dev && rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx COPY server.js ./ USER node EXPOSE 3000 CMD ["node", "server.js"]
  • newer base image,
  • npm removed after installing dependencies, since the app doesn't need it at runtime,
  • USER node instead of root,
  • express bumped to ^4.21.2.

Run 2: one CVE left

After the fix, one finding remained: CVE-2026-85091 in zlib, MEDIUM, fixed in 1.3.2-r1. The node:24-alpine image still ships 1.3.2-r0, so the fix has to wait for an upstream rebuild.

Until then, the CVE goes into an ignore rule with a statement and an expiry date:

Image loading...Ignore rule for a CVE with a statement and an expiry date

Ignore rules for misconfigurations, secrets, and licenses work the same way. In the first field, enter the rule ID or the license name instead of a CVE number.

Rule expiry

On the expiry date, the same commit failed on zlib again.

Image loading...CVE with an expired ignore rule, push skipped

The base image still had no fix, so the rule was extended by a month:

yaml
ignore: vulnerabilities: - id: CVE-2026-85091 statement: "zlib fix not yet in node:24-alpine, waiting for the upstream rebuild" expires_at: 2026-11-13

An entry in .trivyignore never expires. Here, every extension is a deliberate decision.

Run 3: green

Build, scan, and push take just over a minute. The orders-api image is in the Buddy registry.

Image loading...Green run: build, Security Audit, and push

The JSONL report is saved to .buddy/output/trivy/, and its path is available in $BUDDY_ACTION_TRIVY_OUTPUT_FILE.

What's next

  • Filesystem - lockfiles and secrets in the repo, before the build.
  • Rootfs - JARs and WARs, after the build.
  • Registry - scheduled scans of images already in the registry.
  • Licenses - the LICENSE scanner with ignore rules per SPDX ID.

All fields are covered in the action docs.

Jarek Dylewski

Jarek Dylewski

Customer Support

A journalist and an SEO specialist trying to find himself in the unforgiving world of coders. Gamer, a non-fiction literature fan and obsessive carnivore. Jarek uses his talents to convert the programming lingo into a cohesive and approachable narration.

Oct 15, 2026
Share