Skip to content

[RAPTOR-12499] SemGrep detected root user in dronin environments #1423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions custom_model_runner/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

#### [1.16.14] - in progress

##### Changed
- Non-root user is configured for drop-in environments

#### [1.16.13] - 2025-05-12
##### Added
- Request ID for logging messages
Expand Down
2 changes: 1 addition & 1 deletion custom_model_runner/datarobot_drum/drum/description.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
This is proprietary source code of DataRobot, Inc. and its affiliates.
Released under the terms of DataRobot Tool and Utility Agreement.
"""
version = "1.16.13"
version = "1.16.14"
__version__ = version
project_name = "datarobot-drum"
5 changes: 5 additions & 0 deletions example_dropin_environments/julia_mlj/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ ENV WITH_ERROR_SERVER=1
#Uncomment the following line to switch to production mode
#ENV PRODUCTION=1 MAX_WORKERS=4 SHOW_STACKTRACE=1

RUN chmod -R 777 $HOME

# Security scanners require non-root user to be explicitly specified for the Docker image
USER nobody
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might not matter too much. In LRS we run the container with a specific set of user id / group id (defaults are 1000:1000), also we force chown on the /opt/code to these.
I'm not sure if setting USER to something else would do it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

can you test building such image and testing on staging and/or locally?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure I can test this on staging before merging the PR. Will try

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@klichukb I tested this image on Staging. It really lacks permissions if running for any non-root user (when tried to install model dependencies in the exec env).
The only solution to this is to grant permissions to all users for the $HOME directory which is "/opt". That directory keeps pip cache, virtualenvs the the code.

We can't know which user will run this container but we definitely can't run the containers from root. Chainguard will never let us to use 1000 as a user - there is no way to create custom users, it only gives us nonroot user that we can use when running the container - that's requirement from STIG/FIPS compliance.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also sorry, I didnt realize I commented on specifically julia.. Its an irrelevant env, so if any tests - definitely not the Julia one

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, for that reason I updated all the Dockerfiles in this PR.


ENTRYPOINT ["/opt/code/start_server.sh"]
4 changes: 4 additions & 0 deletions example_dropin_environments/python311_genai-gpu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ COPY ./*.sh ${CODE_DIR}/

ENV WITH_ERROR_SERVER=1

RUN chmod -R 777 $HOME

USER nobody

ENTRYPOINT ["/opt/code/start_server.sh"]
4 changes: 4 additions & 0 deletions example_dropin_environments/python39_genai/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ ENV WITH_ERROR_SERVER=1
# Uncomment the following line to switch from Flask to production mode
#ENV PRODUCTION=1 MAX_WORKERS=4 SHOW_STACKTRACE=1

RUN chmod -R 777 $HOME
# Security scanners require non-root user to be explicitly specified for the Docker image
USER nobody

ENTRYPOINT ["/opt/code/start_server.sh"]
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ cp -r custom_model_runner/ $tmp_py3_sklearn_env_dir

constants_file="tests/constants.py"
image_name=$(grep -oP '^DOCKER_PYTHON_SKLEARN\s*=\s*"\K[^"]+' "$constants_file")
image_name="python3_sklearn_test_env"
[ -z $image_name ] && echo "DOCKER_PYTHON_SKLEARN is not set in $constants_file" && exit 1

pushd $tmp_py3_sklearn_env_dir
# remove DRUM from requirements file to be able to install it from source
sed -i "s/^datarobot-drum.*//" requirements.txt
# Update the Dockerfile to install the custom model runner
echo -e "RUN pip uninstall -y datarobot-drum || true\nCOPY ./custom_model_runner /tmp/custom_model_runner\nRUN pip install /tmp/custom_model_runner" >> Dockerfile
docker build -t $image_name .
echo -e "RUN pip uninstall -y datarobot-drum || true\nCOPY ./custom_model_runner /tmp/custom_model_runner\nRUN pip install /tmp/custom_model_runner" >> Dockerfile.tests
docker build -t $image_name -f Dockerfile.tests .
popd

docker images
Expand Down
35 changes: 18 additions & 17 deletions public_dropin_environments/java_codegen/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@ FROM ${BASE_ROOT_IMAGE} AS build

USER root

# The JDK (not just JRE) is required because Py4J calls a Java method (o0.configure) that tries to execute 'javac'.
RUN apk add --no-cache openjdk-11

ENV VIRTUAL_ENV=/opt/venv

RUN python -m venv ${VIRTUAL_ENV} && \
${VIRTUAL_ENV}/bin/python -m ensurepip --default-pip --upgrade

COPY requirements.txt requirements.txt
RUN ${VIRTUAL_ENV}/bin/python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} +

# The JDK (not just JRE) is required because Py4J calls a Java method (o0.configure) that tries to execute 'javac'.

# This is a private production chain-guard image that is stored in DataRobot's private registry.
# Replace it with your own production chain-gaurd image if you build your own.
FROM datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11

USER root

# Copy the JRE from the development stage
COPY --from=build /usr/lib/jvm/java-11-openjdk /usr/lib/jvm/java-11-openjdk

Expand All @@ -32,25 +40,13 @@ COPY --from=build /bin/mkdir /bin/mkdir
# Required for custom-models to install dependencies
COPY --from=build /usr/bin/pip /usr/bin/pip

# Cleanup '__pycache__' directories. It solves an AsymmetricPrivateKey scanning error.
COPY --from=build /usr/bin/rm /usr/bin/rm
COPY --from=build /usr/bin/find /usr/bin/find
Comment on lines -36 to -37
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No cleanup needed as we remove __pycache__ in the build stage. The rm and find commands won't be needed in the runtime image


# Just for convenience
COPY --from=build /bin/ls /bin/ls


COPY requirements.txt requirements.txt

ENV VIRTUAL_ENV=/opt/venv

RUN sh -c "python -m venv ${VIRTUAL_ENV} && \
. ${VIRTUAL_ENV}/bin/activate && \
python -m ensurepip --default-pip && \
python -m pip install --upgrade pip && \
python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} + && \
rm -rf /usr/bin/rm /usr/bin/find"
Comment on lines -46 to -53
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All that commands do not need a separate shell when building Docker image. I moved the dependencies installation step into build stage.

# Copy preinstalled virtualenv
COPY --from=build --chown=nonroot ${VIRTUAL_ENV} ${VIRTUAL_ENV}
Copy link
Collaborator

Choose a reason for hiding this comment

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

this definitely needs testing with actual datarobot. we use 1000:1000 to run by default.


ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk
ENV PATH=${VIRTUAL_ENV}/bin:${JAVA_HOME}/bin:${PATH}
Expand All @@ -68,4 +64,9 @@ ENV WITH_ERROR_SERVER=1 \
COPY ./*.sh ${CODE_DIR}/
WORKDIR ${CODE_DIR}

USER root
RUN chmod -R 777 $HOME
# Security scanners require non-root user to be explicitly specified for the Docker image
USER nonroot

ENTRYPOINT ["sh", "-c", "exec ${CODE_DIR}/start_server.sh \"$@\"", "--"]
34 changes: 18 additions & 16 deletions public_dropin_environments/python311/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@
ARG BASE_ROOT_IMAGE=datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11-dev
FROM ${BASE_ROOT_IMAGE} AS build

USER root

ENV VIRTUAL_ENV=/opt/venv

RUN python -m venv ${VIRTUAL_ENV} && \
${VIRTUAL_ENV}/bin/python -m ensurepip --default-pip --upgrade

COPY requirements.txt requirements.txt
RUN ${VIRTUAL_ENV}/bin/python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} +

# This is a private production chain-guard image that is stored in DataRobot's private registry.
# Replace it with your own production chain-gaurd image if you build your own.
FROM datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11

USER root

# Required to run the entrypoint script
COPY --from=build /bin/sh /bin/sh

Expand All @@ -24,24 +33,12 @@ COPY --from=build /bin/mkdir /bin/mkdir
# Required for custom-models to install dependencies
COPY --from=build /usr/bin/pip /usr/bin/pip

# Cleanup '__pycache__' directories. It solves an AsymmetricPrivateKey scanning error.
COPY --from=build /usr/bin/rm /usr/bin/rm
COPY --from=build /usr/bin/find /usr/bin/find

# Just for convenience
COPY --from=build /bin/ls /bin/ls

COPY requirements.txt requirements.txt

ENV VIRTUAL_ENV=/opt/venv

RUN sh -c "python -m venv ${VIRTUAL_ENV} && \
. ${VIRTUAL_ENV}/bin/activate && \
python -m ensurepip --default-pip && \
python -m pip install --upgrade pip && \
python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} + && \
rm -rf /usr/bin/rm /usr/bin/find"
# Copy preinstalled virtualenv
COPY --from=build --chown=nonroot ${VIRTUAL_ENV} ${VIRTUAL_ENV}

ENV PATH=${VIRTUAL_ENV}/bin:${PATH}
ENV HOME=/opt
Expand All @@ -58,4 +55,9 @@ ENV WITH_ERROR_SERVER=1 \
COPY ./*.sh ${CODE_DIR}/
WORKDIR ${CODE_DIR}

USER root
RUN chmod -R 777 $HOME
# Security scanners require non-root user to be explicitly specified for the Docker image
USER nonroot

ENTRYPOINT ["sh", "-c", "exec ${CODE_DIR}/start_server.sh \"$@\"", "--"]
34 changes: 18 additions & 16 deletions public_dropin_environments/python311_genai/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@
ARG BASE_ROOT_IMAGE=datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11-dev
FROM ${BASE_ROOT_IMAGE} AS build

USER root

ENV VIRTUAL_ENV=/opt/venv

RUN python -m venv ${VIRTUAL_ENV} && \
${VIRTUAL_ENV}/bin/python -m ensurepip --default-pip --upgrade

COPY requirements.txt requirements.txt
RUN ${VIRTUAL_ENV}/bin/python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} +

# This is a private production chain-guard image that is stored in DataRobot's private registry.
# Replace it with your own production chain-gaurd image if you build your own.
FROM datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11

USER root

# Required to run the entrypoint script
COPY --from=build /bin/sh /bin/sh

Expand All @@ -24,24 +33,12 @@ COPY --from=build /bin/mkdir /bin/mkdir
# Required for custom-models to install dependencies
COPY --from=build /usr/bin/pip /usr/bin/pip

# Cleanup '__pycache__' directories. It solves an AsymmetricPrivateKey scanning error.
COPY --from=build /usr/bin/rm /usr/bin/rm
COPY --from=build /usr/bin/find /usr/bin/find

# Just for convenience
COPY --from=build /bin/ls /bin/ls

COPY requirements.txt requirements.txt

ENV VIRTUAL_ENV=/opt/venv

RUN sh -c "python -m venv ${VIRTUAL_ENV} && \
. ${VIRTUAL_ENV}/bin/activate && \
python -m ensurepip --default-pip && \
python -m pip install --upgrade pip && \
python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} + && \
rm -rf /usr/bin/rm /usr/bin/find"
# Copy preinstalled virtualenv
COPY --from=build --chown=nonroot ${VIRTUAL_ENV} ${VIRTUAL_ENV}

ENV PATH=${VIRTUAL_ENV}/bin:${PATH}
ENV HOME=/opt
Expand All @@ -58,4 +55,9 @@ ENV WITH_ERROR_SERVER=1 \
COPY ./*.sh ${CODE_DIR}/
WORKDIR ${CODE_DIR}

USER root
RUN chmod -R 777 $HOME
# Security scanners require non-root user to be explicitly specified for the Docker image
USER nonroot

ENTRYPOINT ["sh", "-c", "exec ${CODE_DIR}/start_server.sh \"$@\"", "--"]
33 changes: 18 additions & 15 deletions public_dropin_environments/python3_keras/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@
ARG BASE_ROOT_IMAGE=datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11-dev
FROM ${BASE_ROOT_IMAGE} AS build

USER root

ENV VIRTUAL_ENV=/opt/venv

RUN python -m venv ${VIRTUAL_ENV} && \
${VIRTUAL_ENV}/bin/python -m ensurepip --default-pip --upgrade

COPY requirements.txt requirements.txt
RUN ${VIRTUAL_ENV}/bin/python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} +

# This is a private production chain-guard image that is stored in DataRobot's private registry.
# Replace it with your own production chain-gaurd image if you build your own.
FROM datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11

USER root

# Required to run the entrypoint script
COPY --from=build /bin/sh /bin/sh

Expand All @@ -24,24 +33,13 @@ COPY --from=build /bin/mkdir /bin/mkdir
# Required for custom-models to install dependencies
COPY --from=build /usr/bin/pip /usr/bin/pip

# Cleanup '__pycache__' directories. It solves an AsymmetricPrivateKey scanning error.
COPY --from=build /usr/bin/rm /usr/bin/rm
COPY --from=build /usr/bin/find /usr/bin/find

# Just for convenience
COPY --from=build /bin/ls /bin/ls

COPY requirements.txt requirements.txt

ENV VIRTUAL_ENV=/opt/venv

RUN sh -c "python -m venv ${VIRTUAL_ENV} && \
. ${VIRTUAL_ENV}/bin/activate && \
python -m ensurepip --default-pip && \
python -m pip install --upgrade pip && \
python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} + && \
rm -rf /usr/bin/rm /usr/bin/find"
# Copy preinstalled virtualenv
COPY --from=build --chown=nonroot ${VIRTUAL_ENV} ${VIRTUAL_ENV}

ENV PATH=${VIRTUAL_ENV}/bin:${PATH}
ENV HOME=/opt
Expand All @@ -57,4 +55,9 @@ ENV WITH_ERROR_SERVER=1 \
COPY ./*.sh ${CODE_DIR}/
WORKDIR ${CODE_DIR}

USER root
RUN chmod -R 777 $HOME
# Security scanners require non-root user to be explicitly specified for the Docker image
USER nonroot

ENTRYPOINT ["sh", "-c", "exec ${CODE_DIR}/start_server.sh \"$@\"", "--"]
31 changes: 18 additions & 13 deletions public_dropin_environments/python3_onnx/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@
ARG BASE_ROOT_IMAGE=datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11-dev
FROM ${BASE_ROOT_IMAGE} AS build

USER root

ENV VIRTUAL_ENV=/opt/venv

RUN python -m venv ${VIRTUAL_ENV} && \
${VIRTUAL_ENV}/bin/python -m ensurepip --default-pip --upgrade

COPY requirements.txt requirements.txt
RUN ${VIRTUAL_ENV}/bin/python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} +

# This is a private production chain-guard image that is stored in DataRobot's private registry.
# Replace it with your own production chain-gaurd image if you build your own.
FROM datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11

USER root

# Required to run the entrypoint script
COPY --from=build /bin/sh /bin/sh

Expand All @@ -24,24 +33,15 @@ COPY --from=build /bin/mkdir /bin/mkdir
# Required for custom-models to install dependencies
COPY --from=build /usr/bin/pip /usr/bin/pip

# Cleanup '__pycache__' directories. It solves an AsymmetricPrivateKey scanning error.
COPY --from=build /usr/bin/rm /usr/bin/rm
COPY --from=build /usr/bin/find /usr/bin/find

# Just for convenience
COPY --from=build /bin/ls /bin/ls

COPY requirements.txt requirements.txt

ENV VIRTUAL_ENV=/opt/venv

RUN sh -c "python -m venv ${VIRTUAL_ENV} && \
. ${VIRTUAL_ENV}/bin/activate && \
python -m ensurepip --default-pip && \
python -m pip install --upgrade pip && \
python -m pip install --no-cache-dir -r requirements.txt && \
find ${VIRTUAL_ENV} -type d -name '__pycache__' -exec rm -rf {} + && \
rm -rf /usr/bin/rm /usr/bin/find"
# Copy preinstalled virtualenv
COPY --from=build --chown=nonroot ${VIRTUAL_ENV} ${VIRTUAL_ENV}

ENV PATH=${VIRTUAL_ENV}/bin:${PATH}
ENV HOME=/opt
Expand All @@ -58,4 +58,9 @@ ENV WITH_ERROR_SERVER=1 \
COPY ./*.sh ${CODE_DIR}/
WORKDIR ${CODE_DIR}

USER root
RUN chmod -R 777 $HOME
# Security scanners require non-root user to be explicitly specified for the Docker image
USER nonroot

ENTRYPOINT ["sh", "-c", "exec ${CODE_DIR}/start_server.sh \"$@\"", "--"]
Loading