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

IT-3421: Add vulnerability scanning to container build #3

Merged
merged 53 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
e354291
initial commit
brucehoff Jan 21, 2024
d7b77d5
remove 'ubuntu' user reference
brucehoff Jan 21, 2024
22b3a9b
typo
brucehoff Jan 21, 2024
2527a5d
add packages sudo, psmisc required by RStudio; move R package install…
brucehoff Jan 21, 2024
8a56612
remove unnecessary quotes
brucehoff Jan 21, 2024
985d7ba
updated build workflow
brucehoff Jan 21, 2024
f8babcd
updated workflow; added Dockerfile lint
brucehoff Jan 21, 2024
1953554
keep container alive; set auth-none in server.conf
brucehoff Jan 21, 2024
1cfe4e0
whitespace
brucehoff Jan 21, 2024
fac8961
update RStudio version to v2023.12.0; remove rstudio-server.service, …
brucehoff Jan 21, 2024
7678a4b
added rstudio user
brucehoff Jan 21, 2024
ba34e95
run rstudio as rstudio user
brucehoff Jan 21, 2024
8d78228
define rstudio user differently
brucehoff Jan 22, 2024
2890bae
added line continuation to Dockerfile
brucehoff Jan 22, 2024
578e58d
added quotes to dockerfile
brucehoff Jan 22, 2024
9a658e6
split up multiline command to find error
brucehoff Jan 22, 2024
9b42953
fixed quotes
brucehoff Jan 22, 2024
4d466aa
undid line split
brucehoff Jan 22, 2024
e4942bc
switch to rocker/rstudio to avoid infinite redirect problem
brucehoff Jan 22, 2024
e5ef2fe
clean up
brucehoff Jan 22, 2024
4f878d6
Let rstudio have sudo access without having to enter a password
brucehoff Jan 23, 2024
eae5335
suppress sudo warning; cleanup whitespace
brucehoff Jan 23, 2024
ec892e0
IT-3317 feedbqck from CR
brucehoff Jan 23, 2024
0ce0f8a
IT-3317 feedback from CR
brucehoff Jan 23, 2024
ebfb4c6
IT-3317 feedback from CR
brucehoff Jan 23, 2024
6e40d5b
install packages as 'rstudio' user, not as 'root'
brucehoff Jan 25, 2024
2cea41c
install boto3
brucehoff Jan 25, 2024
11820e4
clean up Dockerfile
brucehoff Jan 25, 2024
e5f73bf
install boto3
brucehoff Jan 25, 2024
6983503
upgrading build-push-action from v3 to v5; turning off caching
brucehoff Jan 25, 2024
6658a9e
revert 'no-cache' setting
brucehoff Jan 25, 2024
1ac8a58
corrected conflicts
brucehoff Jan 25, 2024
23ed829
Merge branch 'main' of https://github.com/Sage-Bionetworks-IT/rstudio…
brucehoff Jan 25, 2024
6fae8b2
IT-3421: Add Trivy container scan
brucehoff Jul 25, 2024
00ae542
IT-3421: Add tarball upload step
brucehoff Jul 25, 2024
d8bbd0a
IT-3421: upgraded to rstudio 4.4.1; streamlined build
brucehoff Jul 25, 2024
6b680fc
IT-3421: whitespace
brucehoff Jul 25, 2024
f3397ef
IT-3421 listed some files for Trivy to skip
brucehoff Jul 25, 2024
96bfb46
IT-3421: Whitespace
brucehoff Jul 25, 2024
9404c5f
IT-3421: add apt-get upgrade to docker build
brucehoff Jul 25, 2024
45f49a1
IT-3421: suppress apt-get-upgrade docker-lint check
brucehoff Jul 25, 2024
0d45263
IT-3421: Fixed comment
brucehoff Jul 25, 2024
2fa8125
IT-3421: Matrix build; ReadMe
brucehoff Jul 31, 2024
4f102ad
IT-3421: Ensure image name is lower case
brucehoff Jul 31, 2024
cc1cbb4
IT-3421: Fixed container metadata action
brucehoff Jul 31, 2024
e74128a
IT-3421: Fixed bug
brucehoff Jul 31, 2024
1094bcd
IT-3421: remove erroneous build matrix
brucehoff Aug 1, 2024
ceda40c
IT-3421: Rename yamllint file; set max length in yaml files
brucehoff Aug 2, 2024
7147ff4
IT-3421, use tags of the form 1.2.3, not v1.2.3
brucehoff Aug 2, 2024
785a1fb
IT-3421 fixed daily cron job for Trivy
brucehoff Aug 4, 2024
064897b
IT-3421: Clarify the need to make Docker images lower case
brucehoff Aug 12, 2024
d38652e
IT-3421: Clarify the need to make Docker images lower case
brucehoff Aug 12, 2024
5b22e06
IT-3421: Improve comments around uploading trivy results for a 'faile…
brucehoff Aug 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
1 change: 1 addition & 0 deletions .dockerfilelintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
rules:
apt-get_missing_rm: off
apt-get_recommends: off
apt-get-upgrade: off
sudo_usage: off
81 changes: 59 additions & 22 deletions .github/workflows/docker_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ on:
env:
REGISTRY: ghcr.io
IMAGE_PATH: ghcr.io/${{ github.repository }}
TARFILE_NAME: image.tar


jobs:
tests:
Expand All @@ -25,41 +27,76 @@ jobs:
- name: Static Analysis
uses: pre-commit/[email protected]

- name: Build (but Don't Push) Docker Image
uses: docker/build-push-action@v5
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/[email protected]
with:
images: ${{ env.IMAGE_PATH }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}} # major.minor.patch
type=semver,pattern={{major}}.{{minor}}

- name: Check that build works, save for scanning, but don't push yet
uses: docker/[email protected]
with:
context: .
push: false
outputs: type=tar,dest=${{ env.TARFILE_NAME }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Upload tarball for use by Trivy job
uses: actions/upload-artifact@v4
with:
name: ${{ env.TARFILE_NAME }}
path: ${{ env.TARFILE_NAME }}

build-and-push-image:
outputs:
meta_json: ${{ steps.meta.outputs.json }}
tarfile_artifact: ${{ env.TARFILE_NAME }}

trivy-scan:
needs: tests
uses: "./.github/workflows/trivy.yml"
with:
SOURCE_TYPE: tar
IMAGE_NAME: image-name
TARFILE_NAME: ${{ needs.tests.outputs.tarfile_artifact }}
EXIT_CODE: 1

push-image:
if: ${{ github.event_name == 'push' }}
needs: [tests]
needs: [tests, trivy-scan]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
strategy:
matrix:
value: ${{ fromJSON(needs.tests.outputs.meta_json).tags }}

steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download tar file
id: tar-download
uses: actions/download-artifact@v4
with:
name: ${{ env.TARFILE_NAME }}
path: /tmp

- name: Log in to the Container registry
uses: docker/[email protected]
- name: Load Docker image from tar
run: cat
${{ steps.tar-download.outputs.download-path}}/${{ env.TARFILE_NAME}}
| docker import - ${{ matrix.value }}

- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/[email protected]
with:
images: ${{ env.IMAGE_PATH }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Push Docker image
run: docker push ${{ matrix.value }}
...
90 changes: 90 additions & 0 deletions .github/workflows/trivy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
#
# This workflow runs Trivy on a Docker image
# It can pull the image from a container registry
# or download a tar file. The latter is used
# to check a container image prior to publishing
# to the registry.

name: Run Trivy on a Docker image and push results to GitHub

on:
workflow_call:
inputs:
SOURCE_TYPE: # 'tar' or 'image'
required: true
type: string
TARFILE_NAME: # only used if SOURCE_TYPE=='tar'
required: false
type: string
IMAGE_NAME:
required: true
type: string
EXIT_CODE: # return code for failed scan. 0 means OK
required: false
type: number
default: 0

env:
sarif_file_name: trivy-results.sarif

jobs:
trivy:
name: Trivy
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Download tar file
id: tar-download
uses: actions/download-artifact@v4
if: ${{ inputs.SOURCE_TYPE == 'tar' }}
with:
name: ${{ inputs.TARFILE_NAME }}
path: /tmp

- name: load docker image from tar file
if: ${{ inputs.SOURCE_TYPE == 'tar' }}
run: cat ${{ steps.tar-download.outputs.download-path
}}/${{ inputs.TARFILE_NAME
}} | docker import - ${{ inputs.IMAGE_NAME }}

- name: Run Trivy vulnerability scanner for any major issues
uses: aquasecurity/[email protected]
id: trivy
with:
image-ref: ${{ inputs.IMAGE_NAME }}
ignore-unfixed: true # skip vul'ns for which there is no fix
# list files to skip, each with a justification
skip-files: |
/usr/local/lib/R/site-library/gargle/extdata/fake_service_account.json
/usr/local/lib/R/site-library/openssl/doc/keys.html
# fake_service_account.json is a fake account that gets flagged as a credentials file
# keys.html is a documentation file that appears to contain cred's
severity: 'CRITICAL,HIGH'
format: 'sarif'
# only output findings for configured severities
limit-severities-for-sarif: true
output: ${{ env.sarif_file_name }}
exit-code: ${{ inputs.EXIT_CODE }}

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/[email protected]
# This is the recommended way to upload scan results
# after Trivy exits with HIGH/CRITICAL findings
# See https://github.com/aquasecurity/trivy-action?\
# tab=readme-ov-file#using-trivy-with-github-code-scanning
# Note that here instead of using `always()` which would
# allow the step to run if *any* preceeding step failed,
# this logic ensures that the step ony runs if all steps
# succeed or if only the 'trivy' step fails.
if: ${{ success() || steps.trivy.conclusion=='failure' }}
zaro0508 marked this conversation as resolved.
Show resolved Hide resolved
with:
sarif_file: ${{ env.sarif_file_name }}
wait-for-processing: true
...
35 changes: 35 additions & 0 deletions .github/workflows/trivy_periodic_image_scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
#
# This workflow scans the published container images
# for new vulnerabilities daily, publishing findings.
# Findings will be associated with the 'main' branch
# of the repo' in the GitHub Security tab.
#
name: Trivy Periodic Image Scan

on:
schedule:
# run daily
- cron: "0 0 * * *"

jobs:
to-lower-case:
runs-on: ubuntu-latest
steps:
- name: Ensure image name is lower case
id: repo_name
uses: vishalmamidi/lowercase-action@v1
with:
string: ghcr.io/${{ github.repository }}:main
outputs:
lowercase-repo-name: ${{ steps.repo_name.outputs.lowercase }}

periodic-scan:
needs: lower-case
uses: "./.github/workflows/trivy.yml"
with:
SOURCE_TYPE: image
# While GitHub repo's can be mixed (upper and lower) case,
# Docker images can only be lower case
IMAGE_NAME: ${{ needs.to-lower-case.outputs.lowercase-repo-name }}
...
12 changes: 12 additions & 0 deletions .trivyignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# List vulnerabilities flagged by Trivy but for which
# the affected code is not used or the risk is acceptable.
# Enter the ID of the vulnerability along with the
# justification as comment, for example:
#
# # Accept the risk
# CVE-2018-14618
#
# More here:
# https://aquasecurity.github.io/trivy/v0.22.0/vulnerability/examples/filter/
#
7 changes: 7 additions & 0 deletions .yamllint
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
extends: default

rules:
# allow long lines, needed for long file paths
line-length:
max: 200
level: error
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
FROM rocker/rstudio:4.3.2
FROM rocker/rstudio:4.4.1

# no login required
ENV DISABLE_AUTH=true

RUN apt-get -y update && \
apt-get -y upgrade && \
apt-get -y install libpng-dev \
zaro0508 marked this conversation as resolved.
Show resolved Hide resolved
python3 \
python3-pip \
Expand Down
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,28 @@ To run:


```
docker run -d -p 8787:8787 ghcr.io/sage-bionetworks-it/rstudio-service-catalog:v1.0.0
docker run -d -p 8787:8787 ghcr.io/sage-bionetworks-it/rstudio-service-catalog:1.0.0
```

## Versioning

Semantic versioning is used and containers are tagged based on GitHub tags: If a tag,
1.2.3 is pushed to GitHub then a container image is built with tags `1.2.3` as well as `1.2`.
Thus the `major.minor` tag is overwritten when the repo' is patched.


## Security

Trivy is run on each built container and they will not be published
to `ghcr.io` if any CRITICAL or HIGH
vulnerabilites are found. Trivy is also run daily to check for new
vulnerabilities in existing images. So periodic review of new findings
is needed: Go to the Security tab in GitHub, select Code Scanning at left,
and then select Branch > Main to check for new findings. To suppress
false positives, either:

- Enter the CVE in `.trivyignore`, or

- Enter the file to skip while scanning in the `trivy.yml` workflow.

In either case, add a comment justifying why the finding is suppressed.
Loading