Run megalinter as non-root in container#8120
Merged
nvuillam merged 20 commits intoJun 20, 2026
Merged
Conversation
Member
…ce and SSH (oxsecurity#1975) For each of PHP, .NET, Rust, npm and Salesforce add a test which runs the tool. Each tool is tested twice: - direct 'docker run' - through 'megalinter' For SSH server add only a direct 'docker run' test as 'megalinter' does not provide a surface to test.
…urity#1975) Add --user-map and --no-user-map to control whether the container runs as root or as a non-root user. The default is root. On POSIX systems, --user-map uses the current user. On other hosts, it falls back to uid/gid 1000:1000.
…rity#1975) Generated with 'make megalinter-build'.
8a97189 to
9d914e6
Compare
Contributor
Author
Done. I had 2 "baseline" commits which are now removed from this PR. |
…urity#1975) Follow up triggered by linter errors: - Remove accidentally added LOGNAME env var - Whitelist adduser, deluser, and delgroup in cspell for 'sh/setup-runtime-user'
Contributor
Author
|
I added 3 commits to address linter errors:
|
nvuillam
approved these changes
Jun 20, 2026
nvuillam
left a comment
Member
There was a problem hiding this comment.
I think it was one of the most requested update for years, thanks a lot for the PR :)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Run megalinter as non-root in container
This PR adds an opt-in mode to run
megalinteras a non-root user inside the container.Problem
Currently
megalinteralways runs as root in containers.For users on POSIX systems (Linux and macOS) this causes problems as files on host created by
megalinterwill be owned by root and thus not writable for normal users.Especially in automated environments this can be a real problem as the host user might not have
sudopermissions.I tested this and files on host changed by
megalinteras root keep their owner. Currently this affects generated files.Also running processes as root in containers is considered bad practice.
Solution
For a software like
megalinterto properly share files with the host, this is needed:/rootHardcoding
1000:1000does not work. It is the default only for the very first user on Linux.docker run --user $UID:$GIDSoftware and processes
I identified the installations of PHP, .NET, Rust, npm and Salesforce to use
/rootand thus cause problems. And additionally the SSH server feature in the container neededroot.For each of these there are 2 commits:
Run processes as non-root in containers
This PR follows the 3.2 pattern: start the container as root and switch to the target runtime user in the entrypoint.
The logic was carried over from the
aicage entrypoint.sh:244.
Commit overview
The commits follow a TDD order where tests are added early and fail first. Then they gradually start to pass. This may help retrace during review why parts of the change are necessary.
If review would be easier in smaller steps, the runtime-specific fixes for PHP, .NET, Rust, npm, Salesforce, and SSH can also be split into separate precursor PRs which would need to be merged first.
I kept them together here because the non-root mode and the runtime fixes are closely connected and the test progression is easier to follow in one series even though intermediate commits intentionally contain failing tests.
Commit overview: 0. Baseline (no commits)
Before any other changes I ran:
hatch run build:build-py -- --delete-dockerfileswhich both updated some files and gave me a stable baseline.
Those changes/commits are not part of this PR and now removed form this PR.
Commit overview: 1. Runtime image tests for root user (1st commit)
Commit:
For each of PHP, .NET, Rust, npm and Salesforce add a test which runs the tool. Each tool is tested twice:
For SSH server add only a direct 'docker run' test as 'megalinter' does not provide a surface to test.
Commit overview: 2. Run container processes as non-root (2nd and 3rd commit)
Commits:
The
definitioncommit changes:entrypoint.sh: sets up the user by a separate scriptsh/setup-runtime-user.rootthe entrypoint runs through directlynon-rootusers:exec) with a process running thesetup-runtime-userscriptsetup-runtime-usersets up the user and replaces its process with a fresh call toentrypoint.shas thenon-rootuserentrypoint.shruns through the end of the entrypoint scriptrootuser remains in the container.megalinteron host: passes the correct user UID:GID as env vars when running the container. On non-POSIX (Windows) it uses1000:1000.build.py: Add newsh/setup-runtime-userwhen building imagesThe follow-up
generatedcommit applies thedefinitionchanges throughout the project.Commit overview: 3. Runtime image tests for non-root user (4th commit)
Commits:
This expands those tests so each scenario is also executed for
non-rootuser in container.Commit overview: 4. Fix PHP, .NET, Rust, npm, Salesforce and SSH (6x2 = 12 commits)
The fix for each of PHP, .NET, Rust, npm, Salesforce and SSH is again split into 2 commits:
definition: the actual changegenerated: thedefinitionchanges appliedRisks and Arguments
entrypoint.shmight cause problems with the changeentrypoint.shitself is smallroottonon-rootfails during container startnon-rootuser in container/rootfound in the codenon-rootFixes
Proposed Changes
/rootReadiness Checklist
Author/Contributor
Reviewing Maintainer
breakingif this is a large fundamental changeautomation,bug,documentation,enhancement,infrastructure, orperformance