Skip to content

chore: add Trivy security scanning and fix non-root container users#3082

Open
tac0turtle wants to merge 3 commits intomainfrom
marko/add-trivy-scan
Open

chore: add Trivy security scanning and fix non-root container users#3082
tac0turtle wants to merge 3 commits intomainfrom
marko/add-trivy-scan

Conversation

@tac0turtle
Copy link
Contributor

Add make trivy-scan (filesystem + image) via dockerized Trivy. Fix DS-0002 (HIGH): run evm, testapp, and local-da containers as non-root ev-node user, consistent with the grpc Dockerfile.

Overview

add container users

Add `make trivy-scan` (filesystem + image) via dockerized Trivy.
Fix DS-0002 (HIGH): run evm, testapp, and local-da containers as
non-root `ev-node` user, consistent with the grpc Dockerfile.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tac0turtle tac0turtle marked this pull request as ready for review February 18, 2026 14:43
@tac0turtle tac0turtle requested a review from chatton February 18, 2026 14:43
@tac0turtle tac0turtle requested a review from auricom February 18, 2026 14:43
@github-actions
Copy link
Contributor

github-actions bot commented Feb 18, 2026

The latest Buf updates on your PR. Results from workflow CI / buf-check (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed⏩ skipped✅ passed✅ passedFeb 18, 2026, 2:56 PM

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @tac0turtle, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the project's security by introducing automated vulnerability scanning with Trivy and hardening several Docker containers to run with reduced privileges. These changes aim to proactively identify and mitigate security risks, ensuring a more robust and secure application environment.

Highlights

  • Security Scanning: Integrated Trivy security scanning into the build process, allowing for both filesystem and Docker image vulnerability, misconfiguration, and secret scanning via new make trivy-scan targets.
  • Container Security Hardening: Addressed the DS-0002 (HIGH) vulnerability by configuring the evm, testapp, and local-da Docker containers to run as a dedicated non-root ev-node user, enhancing security posture.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • Makefile
    • Included the new scripts/security.mk makefile.
  • apps/evm/Dockerfile
    • Created a new ev-node user and group with UID/GID 1000.
    • Updated the working directory from /root to /home/ev-node.
    • Modified the chmod command to also chown the /home/ev-node directory to ev-node.
    • Set the container to run as the ev-node user.
  • apps/testapp/Dockerfile
    • Created a new ev-node user and group with UID/GID 1000.
    • Updated the working directory from /apps to /home/ev-node.
    • Changed ownership of /home/ev-node to ev-node.
    • Set the container to run as the ev-node user.
  • scripts/security.mk
    • Added a new makefile for Trivy security scanning.
    • Defined variables for Trivy image, severity, cache volume, and images to scan.
    • Implemented trivy-scan target to execute both filesystem and image scans.
    • Created trivy-scan-fs target for scanning the repository filesystem for vulnerabilities, misconfigurations, and secrets.
    • Created trivy-scan-image target for scanning built Docker images.
  • tools/local-da/Dockerfile
    • Created a new ev-node user and group with UID/GID 1000.
    • Updated the working directory from /root to /home/ev-node.
    • Changed ownership of /home/ev-node to ev-node.
    • Set the container to run as the ev-node user.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@claude
Copy link
Contributor

claude bot commented Feb 18, 2026

Claude finished @tac0turtle's task in 1m 17s —— View job


Code Review

  • Gather context
  • Read changed files
  • Analyze code quality and security
  • Post review feedback

Good security hardening PR overall. The non-root user changes are correct and consistent, and the Trivy scanning setup is clean. A few issues worth addressing:

Dockerfile Inconsistencies

apps/evm/Dockerfile and tools/local-da/Dockerfile-D flag on adduser

Both Alpine Dockerfiles use adduser -D which suppresses home directory creation:

# apps/evm/Dockerfile:21
# tools/local-da/Dockerfile:23
RUN addgroup -g 1000 ev-node && \
    adduser -u 1000 -G ev-node -s /bin/sh -D ev-node

With -D, Alpine's adduser does not create /home/ev-node. The subsequent WORKDIR /home/ev-node creates the directory as root, and while the chown call fixes ownership, this differs from the reference apps/grpc/Dockerfile (which also uses -D but explicitly creates a subdirectory with mkdir -p before the chown). It works, but the -D flag is misleading given the intent. Either:

  • Drop -D so adduser creates the home directory itself, or
  • Keep -D and add an explicit comment explaining the pattern

The apps/testapp/Dockerfile (Debian-based) uses useradd -m which correctly creates the home directory. The Alpine images should be consistent with the grpc Dockerfile pattern.

Fix this →


apps/evm/Dockerfilechown placement relative to COPY

# apps/evm/Dockerfile:25-28
COPY --from=build-env /src/apps/evm/evm /usr/bin/evm
COPY apps/evm/entrypoint.sh /usr/bin/entrypoint.sh
RUN chmod +x /usr/bin/entrypoint.sh && \
    chown -R ev-node:ev-node /home/ev-node

The chown /home/ev-node runs after the COPY commands but those copies target /usr/bin/, not /home/ev-node. The working directory /home/ev-node is empty at this point, so the chown is a no-op. Compare with tools/local-da/Dockerfile which has the same structure and apps/grpc/Dockerfile which uses mkdir -p /home/ev-node/.evgrpc && chown -R ev-node:ev-node /home/ev-node to ensure there's actually content to chown. This isn't a security issue since the USER ev-node directive is what matters, but the chown is unnecessary work.


scripts/security.mk — Using latest tag for Trivy

# scripts/security.mk:3
TRIVY_IMAGE := aquasec/trivy:latest

Pinning to latest is a reproducibility and supply-chain risk. Trivy releases are frequent, and a breaking change or unexpected behavior change could silently affect CI. Consider pinning to a specific version (e.g., aquasec/trivy:0.59.1) and documenting a process for bumping it. The severity variable is already overridable via ?=, which is good.

Fix this →


scripts/security.mk — Docker socket mount for image scanning

# scripts/security.mk:37
-v /var/run/docker.sock:/var/run/docker.sock \

Mounting the Docker socket gives the Trivy container full Docker daemon access (effectively root on the host). This is standard practice for Docker-in-Docker image scanning, but worth noting: if Trivy is ever run in a CI environment where the socket path differs (e.g., Podman, rootless Docker, or DinD setups), this will silently fail. Consider adding a check or a comment noting this requirement. The --rm flag is correctly set.


scripts/security.mk — Shell loop quoting

# scripts/security.mk:34-41
@for img in $(SCAN_IMAGES); do \
    echo "--> Scanning image: $$img"; \
    $(TRIVY_RUN) \
        -v /var/run/docker.sock:/var/run/docker.sock \
        $(TRIVY_IMAGE) \
        image --severity $(TRIVY_SEVERITY) \
        $$img; \
done

$$img is unquoted. If an image name contains spaces (unlikely but possible with custom values of SCAN_IMAGES), this would break. Quote it: "$$img". Minor, but it's a correctness issue.

Fix this →


Documentation

docs/guides/migrate-docker-nonroot.md — Well-written migration guide. The troubleshooting table is a nice touch. One note: the guide references ev.xyz/guides/migrate-docker-nonroot in CHANGELOG.md but doesn't verify the VitePress route is correctly configured.

docs/.vitepress/config.ts — Not shown in full context, but if the sidebar/nav entry for this guide wasn't added, the page will be unreachable from navigation. The file was listed as modified (+4/-0), so this appears to be addressed.


Summary

Area Status
Non-root user security fix Correct and consistent
Trivy filesystem scan Good
Trivy image scan Works, minor quoting issue
trivy:latest pin Should be versioned
Alpine -D flag pattern Minor inconsistency vs grpc
EVM chown placement No-op, can be cleaned up
Migration guide High quality
CHANGELOG entry Appropriate for breaking change

The core security objective (DS-0002 fix) is correctly implemented. The items above are refinements rather than blockers.

@codecov
Copy link

codecov bot commented Feb 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.16%. Comparing base (a16e4c9) to head (d4b15fc).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3082   +/-   ##
=======================================
  Coverage   61.16%   61.16%           
=======================================
  Files         113      113           
  Lines       11444    11444           
=======================================
  Hits         7000     7000           
  Misses       3655     3655           
  Partials      789      789           
Flag Coverage Δ
combined 61.16% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces Trivy security scanning capabilities and enhances container security by configuring evm, testapp, and local-da containers to run as a non-root ev-node user. The addition of scripts/security.mk provides a convenient way to perform filesystem and image scans. The changes to the Dockerfiles for evm, testapp, and local-da correctly implement the non-root user principle, which is a significant security improvement. There are minor opportunities for consistency and clarity in the Dockerfile user creation and the default image scanning configuration.


WORKDIR /root
RUN addgroup -g 1000 ev-node && \
adduser -u 1000 -G ev-node -s /bin/sh -D ev-node
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The adduser command uses the -D flag, which prevents the creation of a home directory. However, the subsequent WORKDIR /home/ev-node implies that /home/ev-node is intended to be the user's home directory. For consistency with apps/testapp/Dockerfile and clearer intent, it's better to allow adduser to create the home directory by removing the -D flag, or explicitly create it if -D is strictly necessary for other reasons. Removing -D is the most straightforward approach to align with the WORKDIR and chown commands.

    adduser -u 1000 -G ev-node -s /bin/sh ev-node

TRIVY_CACHE_VOLUME := trivy-cache

# Docker images to scan (space-separated, override or extend as needed)
SCAN_IMAGES ?= evstack:local-dev
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The SCAN_IMAGES variable defaults to evstack:local-dev. While the comment indicates it can be overridden, having a single specific image as the default might lead to other relevant images being missed during scans if the user doesn't explicitly configure this variable. Consider making this variable empty by default or providing a more generic placeholder, encouraging users to define the images they intend to scan, or adding a clear example of how to extend it for multiple images.

tac0turtle and others added 2 commits February 18, 2026 15:55
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers bind mounts, named volumes, Kubernetes init containers,
fsGroup, and docker-compose. Links from the changelog entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@alpe
Copy link
Contributor

alpe commented Feb 19, 2026

Good call to improve the Dockerfiles. The test fail due to RO volumes now.
init container: init evm-single: exit code 1: Error: error validating config: could not create directory "/root/.evm-single/config": mkdir /root/.evm-single: permission denied

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments