Skip to content
Merged
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
120 changes: 114 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v7
with:
# build-docker and build-docker-alpine download ubuntu-latest-11; a docker-job
# re-run after retention-days needs "Re-run all jobs"
name: ${{ matrix.os }}-${{ matrix.java }}
retention-days: 5
path: |
Expand All @@ -123,7 +125,14 @@ jobs:
OpenICF-xml-connector/target/*.jar
!**/*-sources.jar
build-docker:
needs: build-maven
# run even when an unrelated matrix leg failed; the download below still
# fails if the ubuntu-latest-11 leg itself did
if: ${{ !cancelled() }}
runs-on: 'ubuntu-latest'
permissions:
contents: read
security-events: write
services:
registry:
image: registry:2
Expand All @@ -133,11 +142,22 @@ jobs:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v7
with:
name: ubuntu-latest-11
- name: Prepare Dockerfile
# build the image from the ZIP of this commit, not from the last release
shell: bash
run: |
sed -i -E '/^#COPY OpenICF/s/^#//' ./Dockerfile
grep '^COPY OpenICF-java-framework/openicf-zip/target/' ./Dockerfile
ls -l OpenICF-java-framework/openicf-zip/target/*.zip
# Authenticated: the anonymous api.github.com limit is per runner IP
# and, once hit, the empty answer left the metadata step with no tag.
# The tag is what the Dockerfile's releases/download URL needs, and that
# URL is upstream's, so a fork build asks upstream too. `|| true` keeps a
# failed lookup going to the `last release:` line, and `test -n` stops it.
# The tag only names the locally built image; the ZIP comes from build-maven.
# `|| true` keeps a failed lookup going to the `last release:` line, and
# `test -n` stops it.
- name: Get latest release version
shell: bash
env:
Expand All @@ -147,6 +167,7 @@ jobs:
echo "last release: $release_version"
test -n "$release_version"
echo "release_version=$release_version" >> "$GITHUB_ENV"
echo "image_repository=${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"
- name: Docker meta
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
Expand Down Expand Up @@ -179,8 +200,49 @@ jobs:
docker run --rm -it -d --memory="1g" --name=test localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}
timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test | grep -q \"healthy\"; do sleep 10; done'
docker logs test
- name: Install Trivy
# cached, unlike the DBs: trivy-action's `cache: false` would also skip the binary
# cache and leave an anonymous github.com release lookup in every run
continue-on-error: true
uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.6
with:
version: v0.70.0
cache: true
- name: Scan image for vulnerabilities (Trivy)
# trivy resolves the image from the local Docker daemon, so only the runner's
# linux/amd64 manifest is scanned; cache: false keeps the ~1GB trivy DBs from
# evicting the m2-repository caches out of the repo's 10GB actions-cache quota.
# Findings do not fail the step; a Trivy or trivy-db registry outage does, and
# must not fail the image smoke test above
continue-on-error: true
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
skip-setup-trivy: true
image-ref: localhost:5000/${{ env.image_repository }}:${{ env.release_version }}
format: sarif
output: trivy-results.sarif
severity: CRITICAL,HIGH
limit-severities-for-sarif: true
ignore-unfixed: true
scanners: vuln
cache: false
- name: Upload Trivy report to GitHub Security
uses: github/codeql-action/upload-sarif@v4
# upload even if a preceding step failed, but not without a report to upload
if: ${{ always() && hashFiles('trivy-results.sarif') != '' }}
with:
sarif_file: trivy-results.sarif
# distinct from the docker-scan.yml categories, which track the published images
category: trivy-build-default
build-docker-alpine:
needs: build-maven
# run even when an unrelated matrix leg failed; the download below still
# fails if the ubuntu-latest-11 leg itself did
if: ${{ !cancelled() }}
runs-on: 'ubuntu-latest'
permissions:
contents: read
security-events: write
services:
registry:
image: registry:2
Expand All @@ -190,11 +252,22 @@ jobs:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v7
with:
name: ubuntu-latest-11
- name: Prepare Dockerfile
# build the image from the ZIP of this commit, not from the last release
shell: bash
run: |
sed -i -E '/^#COPY OpenICF/s/^#//' ./Dockerfile-alpine
grep '^COPY OpenICF-java-framework/openicf-zip/target/' ./Dockerfile-alpine
ls -l OpenICF-java-framework/openicf-zip/target/*.zip
# Authenticated: the anonymous api.github.com limit is per runner IP
# and, once hit, the empty answer left the metadata step with no tag.
# The tag is what the Dockerfile's releases/download URL needs, and that
# URL is upstream's, so a fork build asks upstream too. `|| true` keeps a
# failed lookup going to the `last release:` line, and `test -n` stops it.
# The tag only names the locally built image; the ZIP comes from build-maven.
# `|| true` keeps a failed lookup going to the `last release:` line, and
# `test -n` stops it.
- name: Get latest release version
shell: bash
env:
Expand All @@ -204,6 +277,7 @@ jobs:
echo "last release: $release_version"
test -n "$release_version"
echo "release_version=$release_version" >> "$GITHUB_ENV"
echo "image_repository=${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"
- name: Docker meta
id: meta
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
Expand Down Expand Up @@ -237,3 +311,37 @@ jobs:
docker run --rm -it -d --memory="1g" --name=test localhost:5000/${GITHUB_REPOSITORY,,}:${{ env.release_version }}-alpine
timeout 3m bash -c 'until docker inspect --format="{{json .State.Health.Status}}" test | grep -q \"healthy\"; do sleep 10; done'
docker logs test
- name: Install Trivy
# cached, unlike the DBs: trivy-action's `cache: false` would also skip the binary
# cache and leave an anonymous github.com release lookup in every run
continue-on-error: true
uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.6
with:
version: v0.70.0
cache: true
- name: Scan image for vulnerabilities (Trivy)
# trivy resolves the image from the local Docker daemon, so only the runner's
# linux/amd64 manifest is scanned; cache: false keeps the ~1GB trivy DBs from
# evicting the m2-repository caches out of the repo's 10GB actions-cache quota.
# Findings do not fail the step; a Trivy or trivy-db registry outage does, and
# must not fail the image smoke test above
continue-on-error: true
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
skip-setup-trivy: true
image-ref: localhost:5000/${{ env.image_repository }}:${{ env.release_version }}-alpine
format: sarif
output: trivy-results.sarif
severity: CRITICAL,HIGH
limit-severities-for-sarif: true
ignore-unfixed: true
scanners: vuln
cache: false
- name: Upload Trivy report to GitHub Security
uses: github/codeql-action/upload-sarif@v4
# upload even if a preceding step failed, but not without a report to upload
if: ${{ always() && hashFiles('trivy-results.sarif') != '' }}
with:
sarif_file: trivy-results.sarif
# distinct from the docker-scan.yml categories, which track the published images
category: trivy-build-alpine
72 changes: 72 additions & 0 deletions .github/workflows/docker-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions copyright [year] [name of copyright owner]".
#
# Copyright 2026 3A Systems, LLC.

# Scans the published Docker images for known vulnerabilities: new CVEs surface in
# already-released images (mostly via the base image), without any change in this repository.
# Its trivy-image-* categories exist only on master, so once it has run, every PR that
# uploads both trivy-build-* categories gets a "Trivy" check that concludes neutral
# with "2 configurations not found".
name: Docker Scan

on:
schedule:
- cron: '30 5 * * 1'
workflow_dispatch:

permissions:
contents: read

jobs:
scan:
# Do not run the scheduled scan in forks; manual runs are always allowed.
if: github.event_name == 'workflow_dispatch' || github.repository == 'OpenIdentityPlatform/OpenICF'
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
tag: [ 'latest', 'alpine' ]
steps:
- uses: actions/checkout@v7
- name: Install Trivy
# cached, unlike the DBs: trivy-action's `cache: false` would also skip the binary
# cache and leave an anonymous github.com release lookup in every run
uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.6
with:
version: v0.70.0
cache: true
- name: Scan openidentityplatform/openicf:${{ matrix.tag }} (Trivy)
# unlike the build.yml scan, unfixed CVEs are reported too: surfacing them in
# already-released images is the point of this workflow. Trivy pulls only the
# linux/amd64 manifest (no --platform is passed); the other published platforms
# are not scanned (alpine on linux/386 ships openjdk11-jre instead of openjdk25-jre)
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
skip-setup-trivy: true
image-ref: openidentityplatform/openicf:${{ matrix.tag }}
format: sarif
output: trivy-${{ matrix.tag }}.sarif
severity: CRITICAL,HIGH
limit-severities-for-sarif: true
scanners: vuln
cache: false
- name: Upload report to GitHub Security
uses: github/codeql-action/upload-sarif@v4
# upload even if a preceding step failed, but not without a report to upload
if: ${{ always() && hashFiles(format('trivy-{0}.sarif', matrix.tag)) != '' }}
with:
sarif_file: trivy-${{ matrix.tag }}.sarif
category: trivy-image-${{ matrix.tag }}
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ ARG VERSION

WORKDIR /opt

# build.yml uncomments the COPY to build the image from the ZIP of the commit under test;
# without it the openicf-$VERSION.zip of the release is downloaded
#COPY OpenICF-java-framework/openicf-zip/target/*.zip ./

RUN apt-get update \
&& apt-get install -y --no-install-recommends curl unzip \
&& bash -c 'if [ ! -z "$VERSION" ] ; then rm -rf ./*.zip ; curl -L https://github.com/OpenIdentityPlatform/OpenICF/releases/download/$VERSION/openicf-$VERSION.zip --output openicf-$VERSION.zip ; fi' \
&& bash -c 'if [ ! -z "$VERSION" ] && ! ls ./openicf-*.zip >/dev/null 2>&1 ; then curl -L https://github.com/OpenIdentityPlatform/OpenICF/releases/download/$VERSION/openicf-$VERSION.zip --output openicf-$VERSION.zip ; fi' \
&& unzip openicf-*.zip && rm -rf *.zip \
&& apt-get remove -y --purge unzip \
&& rm -rf /var/lib/apt/lists/* \
Expand Down
4 changes: 3 additions & 1 deletion Dockerfile-alpine
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ ARG TARGETARCH

WORKDIR /opt

# build.yml uncomments the COPY to build the image from the ZIP of the commit under test;
# without it the openicf-$VERSION.zip of the release is downloaded
#COPY OpenICF-java-framework/openicf-zip/target/*.zip ./

RUN apk add --update --no-cache --virtual builddeps curl unzip \
&& apk upgrade --update --no-cache \
&& if [ "$TARGETARCH" = "386" ]; then JDK=openjdk11-jre; else JDK=openjdk25-jre; fi \
&& apk add bash "$JDK" \
&& bash -c 'if [ ! -z "$VERSION" ] ; then rm -rf ./*.zip ; curl -L https://github.com/OpenIdentityPlatform/OpenICF/releases/download/$VERSION/openicf-$VERSION.zip --output openicf-$VERSION.zip ; fi' \
&& bash -c 'if [ ! -z "$VERSION" ] && ! ls ./openicf-*.zip >/dev/null 2>&1 ; then curl -L https://github.com/OpenIdentityPlatform/OpenICF/releases/download/$VERSION/openicf-$VERSION.zip --output openicf-$VERSION.zip ; fi' \
&& unzip openicf-*.zip && rm -rf *.zip \
&& apk del unzip \
&& addgroup -S $USER \
Expand Down
Loading