diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml index 26d87b9..2bb9c33 100644 --- a/.gitea/workflows/ci-cd.yml +++ b/.gitea/workflows/ci-cd.yml @@ -124,14 +124,10 @@ jobs: run: | # Install syft curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin - echo "${{ secrets.HARBOR_TOKEN }}" - echo "${{ env.REGISTRY }}" - echo "${{ secrets.HARBOR_USERNAME }}" - echo "${{ env.IMAGE_NAME }}" - # Login to registry - use the REGISTRY variable for the URL - echo "${{ secrets.HARBOR_TOKEN }}" | docker login ${{ env.REGISTRY }} -u '${{ secrets.HARBOR_USERNAME }}' --password-stdin - # Generate SBOM using latest tag - syft ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest -o spdx-json > sbom.spdx.json + + # Generate SBOM using the specific image digest + syft ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }} -o spdx-json > sbom.spdx.json + # Verify SBOM was created if [ ! -f sbom.spdx.json ]; then echo "Failed to generate SBOM" @@ -149,12 +145,22 @@ jobs: # Get the image digest from the build step IMAGE_DIGEST="${{ steps.build.outputs.digest }}" - # Attach SBOM to the specific image digest + # Try method 1: Use oras attach with proper media type + echo "Attempting to attach SBOM with oras attach..." oras attach ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \ + --artifact-type application/vnd.cyclonedx+json \ + --annotation "org.opencontainers.artifact.description=SBOM for ${{ env.IMAGE_NAME }}" \ + sbom.spdx.json:application/spdx+json || echo "oras attach failed, trying alternative method..." + + # Alternative method: Push as separate artifact with clear naming + echo "Uploading SBOM as separate artifact..." + oras push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sbom-${{ github.sha }} \ --artifact-type application/spdx+json \ + --annotation "org.opencontainers.artifact.description=SBOM for ${{ env.IMAGE_NAME }}@${IMAGE_DIGEST}" \ + --annotation "org.opencontainers.artifact.source=${IMAGE_DIGEST}" \ sbom.spdx.json:application/spdx+json - echo "SBOM attached successfully to image digest: ${IMAGE_DIGEST}" + echo "SBOM uploaded successfully" # Job 4: Image Security Scan scan: @@ -164,66 +170,71 @@ jobs: if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' steps: - name: Login to Harbor Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ secrets.HARBOR_USERNAME }} - password: ${{ secrets.HARBOR_TOKEN }} - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - format: 'sarif' - output: 'trivy-results.sarif' - - - name: Generate JSON scan results - uses: aquasecurity/trivy-action@master - with: - image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - format: 'json' - output: 'trivy-results.json' - - - name: Upload scan results artifacts + run: | + echo "${{ secrets.HARBOR_TOKEN }}" | docker login ${{ env.REGISTRY }} -u '${{ secrets.HARBOR_USERNAME }}' --password-stdin + + - name: Install Trivy + run: | + sudo apt-get update + sudo apt-get install -y wget + # Get the latest Trivy version dynamically + TRIVY_VERSION=$(curl -s "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' | sed 's/v//') + wget https://github.com/aquasecurity/trivy/releases/latest/download/trivy_${TRIVY_VERSION}_Linux-64bit.deb + sudo dpkg -i trivy_${TRIVY_VERSION}_Linux-64bit.deb + + - name: Run Trivy scan (SARIF) + run: | + trivy image --format sarif --output trivy-results.sarif \ + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.image-digest }} + + - name: Run Trivy scan (JSON) + run: | + trivy image --format json --output trivy-results.json \ + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.image-digest }} + + - name: Install ORAS + run: | + curl -LO https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_amd64.tar.gz + tar -xzf oras_1.1.0_linux_amd64.tar.gz + sudo mv oras /usr/local/bin/ + + - name: Attach scan results to Harbor image + run: | + IMAGE_DIGEST="${{ needs.build.outputs.image-digest }}" + + # Attach SARIF results + oras attach ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \ + --artifact-type application/sarif+json \ + --annotation "org.opencontainers.artifact.description=Trivy SARIF scan results" \ + trivy-results.sarif:application/sarif+json + + # Attach JSON results + oras attach ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \ + --artifact-type application/json \ + --annotation "scan.type=vulnerability" \ + --annotation "scan.tool=trivy" \ + --annotation "org.opencontainers.artifact.description=Trivy JSON scan results" \ + trivy-results.json:application/json + + echo "Scan results attached successfully" + + - name: Upload scan artifacts (backup) uses: actions/upload-artifact@v3 with: name: trivy-scan-results path: | trivy-results.sarif trivy-results.json - - - name: Attach scan results to Harbor image - run: | - # Install ORAS - curl -LO https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_amd64.tar.gz - tar -xzf oras_1.1.0_linux_amd64.tar.gz - sudo mv oras /usr/local/bin/ - - # Get the image digest from the build job - IMAGE_DIGEST="${{ needs.build.outputs.digest }}" - - # Attach SARIF scan results - oras attach ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \ - --artifact-type application/sarif+json \ - trivy-results.sarif:application/sarif+json - - # Attach JSON scan results - oras attach ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \ - --artifact-type application/json \ - trivy-results.json:application/json \ - --annotation "scan.type=vulnerability" \ - --annotation "scan.tool=trivy" - - echo "Scan results attached successfully to image digest: ${IMAGE_DIGEST}" - + - name: Check for HIGH/CRITICAL vulnerabilities - uses: aquasecurity/trivy-action@master - with: - image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - format: 'json' - output: 'trivy-critical.json' - exit-code: '1' - severity: 'HIGH,CRITICAL' + run: | + trivy image \ + --format json \ + --output trivy-critical.json \ + --severity HIGH,CRITICAL \ + --exit-code 1 \ + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.image-digest }} + # # Job 5: Deploy to Development # deploy-dev: