diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index cd7b0637df..ed08d5d453 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -534,8 +534,11 @@ jobs: name: Scan Staging Images needs: - build-staging-images + - set-release-version + env: + RELEASE_VERSION: ${{ needs.set-release-version.outputs.release_version }} permissions: - contents: read + contents: write runs-on: ubuntu-latest steps: - name: Check out repository @@ -552,6 +555,22 @@ jobs: run: | make security-scan-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-staging make security-scan-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-staging + + - name: Generate SBOM for backend image + run: | + make sbom-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-staging + + - name: Generate SBOM for frontend image + run: | + make sbom-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-staging + + - name: Upload SBOMs + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + with: + name: staging-sbom-${{ env.RELEASE_VERSION }} + path: | + backend-sbom-${{ env.RELEASE_VERSION }}.cdx.json + frontend-sbom-${{ env.RELEASE_VERSION }}.cdx.json timeout-minutes: 5 deploy-staging-nest: @@ -901,8 +920,11 @@ jobs: name: Scan Production Images needs: - build-production-images + - set-release-version + env: + RELEASE_VERSION: ${{ needs.set-release-version.outputs.release_version }} permissions: - contents: read + contents: write runs-on: ubuntu-latest steps: - name: Check out repository @@ -919,6 +941,22 @@ jobs: run: | make security-scan-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-production make security-scan-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-production + + - name: Generate SBOM for backend image + run: | + make sbom-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-production + + - name: Generate SBOM for frontend image + run: | + make sbom-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-production + + - name: Upload SBOMs + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release upload "${{ github.event.release.tag_name }}" \ + backend-sbom-${{ env.RELEASE_VERSION }}.cdx.json \ + frontend-sbom-${{ env.RELEASE_VERSION }}.cdx.json timeout-minutes: 5 deploy-production-nest: diff --git a/.gitignore b/.gitignore index 2c73948f38..da12096261 100644 --- a/.gitignore +++ b/.gitignore @@ -31,14 +31,16 @@ backend/fuzzing_results/ *.log *.pdf *.pem +backend-sbom-local.cdx.json backend/data/backup* backend/generated_videos/ backend/staticfiles design/ +frontend-sbom-local.cdx.json +frontend/.next frontend/blob-report/ frontend/coverage frontend/dist -frontend/.next frontend/npm-debug.log* frontend/out frontend/playwright-report/ diff --git a/backend/Makefile b/backend/Makefile index 9ab56adc91..f102846b4c 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -7,6 +7,8 @@ include backend/apps/slack/Makefile SHELL := /bin/bash +.PHONY: sbom-backend-image + build-backend-local-image: @DOCKER_BUILDKIT=1 docker build \ --no-cache \ @@ -180,6 +182,24 @@ security-scan-backend-image: $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ image --config /trivy.yaml $(BACKEND_IMAGE_NAME) +SBOM_VERSION := $(if $(RELEASE_VERSION),$(RELEASE_VERSION),local) + +sbom-backend-image: + @if [ "$(BACKEND_IMAGE_NAME)" = "nest-backend-local" ]; then \ + $(MAKE) build-backend-local-image; \ + fi + @echo "Generating SBOM for image: $(BACKEND_IMAGE_NAME)..." + @docker run \ + --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v $(CURDIR)/.trivy-cache:/root/.cache/trivy \ + -v $(CURDIR):/work \ + $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + image \ + --format cyclonedx \ + --output /work/backend-sbom-$(SBOM_VERSION).cdx.json \ + $(BACKEND_IMAGE_NAME) + shell-backend: @CMD="/bin/sh" $(MAKE) exec-backend-command-it diff --git a/cspell/custom-dict.txt b/cspell/custom-dict.txt index f794138b0e..85e46eb2f9 100644 --- a/cspell/custom-dict.txt +++ b/cspell/custom-dict.txt @@ -74,6 +74,7 @@ bangbang boardofdirectors bsky carryforward +cdx certbot collectstatic coraza @@ -82,6 +83,7 @@ csrfguard csrfprotector csrftoken cva +cyclonedx defectdojo demojize dismissable @@ -167,6 +169,7 @@ rsc saft sakanashi samm +sbom schemathesis semgrep seo diff --git a/frontend/Makefile b/frontend/Makefile index b81ffb42be..fc3a431180 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -1,5 +1,7 @@ SHELL := /bin/bash +.PHONY: sbom-frontend-image + build-frontend-local-image: @DOCKER_BUILDKIT=1 NEXT_PUBLIC_ENVIRONMENT=local docker build \ --build-arg FORCE_STANDALONE=yes \ @@ -75,6 +77,24 @@ security-scan-frontend-image: $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ image --config /trivy.yaml $(FRONTEND_IMAGE_NAME) +SBOM_VERSION := $(if $(RELEASE_VERSION),$(RELEASE_VERSION),local) + +sbom-frontend-image: + @if [ "$(FRONTEND_IMAGE_NAME)" = "nest-frontend-local" ]; then \ + $(MAKE) build-frontend-local-image; \ + fi + @echo "Generating SBOM for image: $(FRONTEND_IMAGE_NAME)..." + @docker run \ + --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v $(CURDIR):/work \ + -v $(CURDIR)/.trivy-cache:/root/.cache/trivy \ + $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + image \ + --format cyclonedx \ + --output /work/frontend-sbom-$(SBOM_VERSION).cdx.json \ + $(FRONTEND_IMAGE_NAME) + shell-frontend: @CMD="/bin/sh" $(MAKE) exec-frontend-command-it