Skip to content
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

ASH Running as non-root user #109

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
f8d6c23
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
13c903c
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
ed5ff23
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
28f304a
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
6654e55
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
55f30df
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
89ad81d
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
f2bf018
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
ad8ccd8
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
82df7b0
feat: run ASH image using non-root user
climbertjh2 Apr 29, 2024
f681a3b
feat: run ASH image using non-root user
climbertjh2 Apr 30, 2024
f23f392
feat: run ASH image using non-root user
climbertjh2 May 1, 2024
683bf42
feat: run ASH image using non-root user
climbertjh2 May 1, 2024
46e15b1
feat: run ASH image using non-root user
climbertjh2 May 1, 2024
40f49b7
feat: run ASH image using non-root user
climbertjh2 May 1, 2024
0051166
Merge branch 'main' into feature/78/run-container-non-root
climbertjh2 May 3, 2024
0f748d7
chore: fix auto-merge updates
climbertjh2 May 3, 2024
ce6cfff
Merge branch 'main' into feature/78/run-container-non-root
climbertjh2 May 14, 2024
e41adbb
fix: always set UID/GID build-arg values when building the ASH contai…
climbertjh2 Jun 4, 2024
6e0c800
Merge branch 'main' into feature/78/run-container-non-root
climbertjh2 Jun 4, 2024
26c83de
chore: fix EOL characters in file
climbertjh2 Jun 4, 2024
e5d85fe
Merge branch 'awslabs:main' into feature/78/run-container-non-root
climbertjh2 Jun 5, 2024
b579ef1
Merge branch 'feature/78/run-container-non-root' of github.com:climbe…
climbertjh2 Jun 5, 2024
20b7e71
Merge remote-tracking branch 'origin/main' into climbertjh2-feature/7…
rapgaws Oct 25, 2024
e8b4621
Fixed Grype database permissions
rafaelpereyra Oct 28, 2024
9e02015
Added environment variable for ash user and group
rafaelpereyra Oct 28, 2024
450311f
updated Dockerfile to multi-stage build to support generating CI targ…
scrthq Oct 30, 2024
7072698
updated help docs in code and readme
scrthq Oct 30, 2024
8e0915b
moved documentation workflow to main one to make debugging failed pip…
scrthq Oct 30, 2024
7e29e52
renamed pipeline
scrthq Oct 30, 2024
8daf3dd
updated help docs in code and readme
scrthq Oct 30, 2024
04ef4d8
updated help docs in code and readme
scrthq Oct 30, 2024
c6596c6
updated help docs in code and readme
scrthq Oct 30, 2024
aef7c49
feat: #comment adjusted permissions based on feedback
scrthq Oct 31, 2024
245584a
feat: #comment adjusted permissions based on feedback
scrthq Nov 1, 2024
5e5c50a
feat: #comment bumped version to 1.6.0
scrthq Nov 1, 2024
be0474d
Added Changelog information
rafaelpereyra Nov 12, 2024
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
46 changes: 45 additions & 1 deletion .github/workflows/ash-build-and-scan.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build & run ASH against itself
name: ASH - Core Pipeline
on:
push:
branches:
Expand All @@ -15,6 +15,8 @@ permissions:
id-token: write
security-events: write
pull-requests: write
env:
PYTHON_VERSION: "3.12"
jobs:
build:
strategy:
Expand Down Expand Up @@ -152,3 +154,45 @@ jobs:
name: ash_output
path: ash_output
if-no-files-found: error

build-docs:
name: Build documentation
needs: []
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref != 'refs/heads/main')

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'

- name: Install dependencies
run: pip install -r requirements.txt

- name: Build documentation
run: mkdocs build --clean

deploy-docs:
name: Deploy documentation
needs: []
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'

- name: Install dependencies
run: pip install -r requirements.txt

- name: Deploy documentation
run: mkdocs gh-deploy --clean --force
55 changes: 0 additions & 55 deletions .github/workflows/docs-build-and-deploy.yml

This file was deleted.

118 changes: 45 additions & 73 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,63 +1,27 @@
#checkov:skip=CKV_DOCKER_7: Base image is using a non-latest version tag by default, Checkov is unable to parse due to the use of ARG
#
# Enable BASE_IMAGE as an overrideable ARG for proxy cache + private registry support
#
ARG BASE_IMAGE=public.ecr.aws/docker/library/python:3.10-bullseye


# First stage: Build poetry requirements
FROM ${BASE_IMAGE} as poetry-reqs

ENV PYTHONDONTWRITEBYTECODE 1

RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
python3-venv && \
apt-get install -y python3-venv && \
rm -rf /var/lib/apt/lists/*

RUN python3 -m pip install -U pip poetry

WORKDIR /src

COPY pyproject.toml pyproject.toml
COPY poetry.lock poetry.lock
COPY README.md README.md
COPY pyproject.toml poetry.lock README.md ./
COPY src/ src/

RUN poetry build


FROM ${BASE_IMAGE} as ash
# Second stage: Core ASH image
FROM ${BASE_IMAGE} as core
SHELL ["/bin/bash", "-c"]
ARG OFFLINE="NO"
ARG OFFLINE_SEMGREP_RULESETS="p/ci"

ENV OFFLINE="${OFFLINE}"
ENV OFFLINE_AT_BUILD_TIME="${OFFLINE}"
ENV OFFLINE_SEMGREP_RULESETS="${OFFLINE_SEMGREP_RULESETS}"
#
# Allow for UID and GID to be set as build arguments to this Dockerfile.
#
# Set the default values of UID/GID to non-zero (and above typical low-number UID/GID values which
# are defined by default). 500 and 100 are not special values or depended upon.
# Their selection as default values is only to set the default for this container to be non-zero.
#
# The actions performed in this image (CMD command) do not require root privileges.
# Thus, UID/GID are set non-zero to avoid someone inadvertantly running this image in a container
# that runs privileged and as as root(UID 0).
#
# If the environment in which the container will run requires a specific UID/GID, then --build-arg
# arguments on the ${OCI_RUNNER} build command can be used to over-ride these values.
#
ARG UID=500
ARG GID=100
ARG ASH_USER=ash-user
ARG ASH_GROUP=ash-group
ARG ASHUSER_HOME=/home/${ASH_USER}

#
# Setting timezone in the container to UTC to ensure logged times are universal.
#
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

Expand Down Expand Up @@ -136,10 +100,11 @@ RUN echo "gem: --no-document" >> /etc/gemrc && \
#

#
# Grype/Syft/Semgrep
# Grype/Syft/Semgrep - Also sets default location env vars for root user for CI compat
#
ENV GRYPE_DB_CACHE_DIR="${HOME}/.grype"
ENV SEMGREP_RULES_CACHE_DIR="${HOME}/.semgrep"
ENV GRYPE_DB_CACHE_DIR="/deps/.grype"
ENV SEMGREP_RULES_CACHE_DIR="/deps/.semgrep"
RUN mkdir -p ${GRYPE_DB_CACHE_DIR} ${SEMGREP_RULES_CACHE_DIR}

RUN curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | \
sh -s -- -b /usr/local/bin
Expand Down Expand Up @@ -198,7 +163,40 @@ RUN python3 -m pip install *.whl && rm *.whl
#
# Make sure the ash script is executable
#
RUN chmod -R +r /ash && chmod +x /ash/ash
RUN chmod -R 777 /ash /src /out /deps && chmod +x /ash/ash
rafaelpereyra marked this conversation as resolved.
Show resolved Hide resolved

#
# Flag ASH as local execution mode since we are running in a container already
#
ENV _ASH_EXEC_MODE="local"

#
# Append /ash to PATH to allow calling `ash` directly
#
ENV PATH="$PATH:/ash"


# CI stage -- any customizations specific to CI platform compatibility should be added
# in this stage if it is not applicable to ASH outside of CI usage
FROM core as ci

ENV ASH_TARGET=ci
climbertjh2 marked this conversation as resolved.
Show resolved Hide resolved


# Final stage: Non-root user final version. This image contains all dependencies
# for ASH from the `core` stage, but ensures it is launched as a non-root user.
# Running as a non-root user impacts the ability to run ASH reliably across CI
# platforms and other orchestrators where the initialization and launch of the image
# is not configurable for customizing the running UID/GID.
FROM core as non-root

ENV ASH_TARGET=non-root

ARG UID=500
ARG GID=100
ARG ASH_USER=ash-user
ARG ASH_GROUP=ash-group
ARG ASHUSER_HOME=/home/${ASH_USER}

#
# Create a non-root user in the container and run as this user
Expand All @@ -222,41 +220,15 @@ WORKDIR ${ASHUSER_HOME}
USER ${UID}:${GID}

#
# Set the HOME environment variable to be the HOME folder for the non-root user
# Set the HOME environment variable to be the HOME folder for the non-root user,
# along with any additional details that were set to root user values by default
#
ENV HOME=${ASHUSER_HOME}
ENV ASH_USER=${ASH_USER}
ENV ASH_GROUP=${ASH_GROUP}
#
# Set the location for Grype DB inside ASH_USER folder
#
ENV GRYPE_DB_CACHE_DIR=${HOME}/.grypedb
RUN mkdir -p ${GRYPE_DB_CACHE_DIR}

#
# Flag ASH as local execution mode since we are running in a container already
#
ENV _ASH_EXEC_MODE="local"

#
# Append /ash to PATH to allow calling `ash` directly
#
ENV PATH="$PATH:/ash"

# nosemgrep
HEALTHCHECK --interval=12s --timeout=12s --start-period=30s \
CMD type ash || exit 1

#
# The ENTRYPOINT needs to be NULL for CI platform support
# This needs to be an empty array ([ ]), as nerdctl-based runners will attempt to
# resolve an empty string in PATH, unlike Docker which treats an empty string the
# same as a literal NULL
#
ENTRYPOINT [ ]

#
# CMD will be run when invoking it via `$OCI_RUNNER run ...`, but will
# be overridden during CI execution when used as the job image directly.
#
CMD [ "ash" ]
53 changes: 35 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,26 +207,43 @@ ash --source-dir . --ext py
## Synopsis

```text
$ ash --help
NAME:
ash
ash
SYNOPSIS:
ash [OPTIONS] --source-dir /path/to/dir --output-dir /path/to/dir
ash [OPTIONS] --source-dir /path/to/dir --output-dir /path/to/dir
OPTIONS:
-v | --version Prints version number.

-p | --preserve-report Add timestamp to the final report file to avoid overwriting it after multiple executions.
--source-dir Path to the directory containing the code/files you wish to scan. Defaults to $(pwd)
--output-dir Path to the directory that will contain the report of the scans. Defaults to $(pwd)
--ext | -extension Force a file extension to scan. Defaults to identify files automatically.
--offline Build ASH for offline execution. Defaults to false.
--offline-semgrep-rulesets Specify Semgrep rulesets for use in ASH offline mode. Defaults to 'p/ci'.
--force Rebuild the Docker images of the scanning tools, to make sure software is up-to-date.
--no-cleanup Don't cleanup the work directory where temp reports are stored during scans.
--debug Print ASH debug log information where applicable.
-q | --quiet Don't print verbose text about the build process.
-c | --no-color Don't print colorized output.
-s | --single-process Run ash scanners serially rather than as separate, parallel sub-processes.
-o | --oci-runner Use the specified OCI runner instead of docker to run the containerized tools.
--source-dir Path to the directory containing the code/files you wish to scan. Defaults to $(pwd)
--output-dir Path to the directory that will contain the report of the scans. Defaults to $(pwd)

--format Output format of the aggregated_results file segments.
Options: text, json
Default: text

--target Specify the target stage of the ASH image to build.
Options: non-root, ci
Default: non-root

--offline Build ASH for offline execution.
Default: false

--offline-semgrep-rulesets Specify Semgrep rulesets for use in ASH offline mode.
Default: p/ci

--no-cleanup Don't cleanup the work directory where temp reports are stored during scans.
--ext | -extension Force a file extension to scan. Defaults to identify files automatically.

-c | --no-color Don't print colorized output.
-s | --single-process Run ash scanners serially rather than as separate, parallel sub-processes.
-o | --oci-runner Use the specified OCI runner instead of docker to run the containerized tools.
-p | --preserve-report Add timestamp to the final report file to avoid overwriting it after multiple executions.

-d | --debug Print ASH debug log information where applicable.
-q | --quiet Don't print verbose text about the build process.
-v | --version Prints version number.

INFO:
For more information, please visit https://github.com/awslabs/automated-security-helper
```

## FAQ
Expand Down Expand Up @@ -260,7 +277,7 @@ OPTIONS:

- Q: How to run `ash` in an environment without internet connectivity/with an airgap?

A: From your environment which does have internet connectivity, build the ASH image using `--offline` and `--offline-semgrep-rulesets` to specify what resources to package into the image. Environment variable `$ASH_IMAGE_NAME` controls the name of the image. After building, push to your container repository of choice which will be available within the airgapped environment. When you go to execute ASH in your offline environment, passing `--no-build` to `ash` alongside `--offline` and `--offline-semgrep-rulesets` will use your offline image and skip the build. Specify `$ASH_IMAGE_NAME` to override ASH's container image to the previously-built image available within your airgapped environment.
A: From your environment which does have internet connectivity, build the ASH image using `--offline` and `--offline-semgrep-rulesets` to specify what resources to package into the image. Environment variable `$ASH_IMAGE_NAME` controls the name of the image. After building, push to your container repository of choice which will be available within the airgapped environment. When you go to execute ASH in your offline environment, passing `--no-build` to `ash` alongside `--offline` and `--offline-semgrep-rulesets` will use your offline image and skip the build. Specify `$ASH_IMAGE_NAME` to override ASH's container image to the previously-built image available within your airgapped environment.

## Feedback

Expand Down
Loading
Loading