[TASK] Add keyboard navigation tests for report comparison view #923 #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docker Hardening Checks | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "backend/Dockerfile" | |
| - "frontend/Dockerfile" | |
| - ".github/workflows/docker-hardening.yml" | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - "backend/Dockerfile" | |
| - "frontend/Dockerfile" | |
| - ".github/workflows/docker-hardening.yml" | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| name: Build ${{ matrix.service }} image | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - service: backend | |
| context: ./backend | |
| dockerfile: ./backend/Dockerfile | |
| image: secuscan-backend | |
| - service: frontend | |
| context: ./frontend | |
| dockerfile: ./frontend/Dockerfile | |
| image: secuscan-frontend | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build ${{ matrix.service }} image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: ${{ matrix.context }} | |
| file: ${{ matrix.dockerfile }} | |
| push: false | |
| load: true | |
| tags: ${{ matrix.image }}:ci | |
| cache-from: type=gha,scope=${{ matrix.service }} | |
| cache-to: type=gha,scope=${{ matrix.service }},mode=max | |
| - name: Save image as tar | |
| run: docker save ${{ matrix.image }}:ci -o /tmp/${{ matrix.image }}.tar | |
| - name: Upload image artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.image }}-tar | |
| path: /tmp/${{ matrix.image }}.tar | |
| retention-days: 1 | |
| hardening-check: | |
| name: Hardening checks – ${{ matrix.service }} | |
| runs-on: ubuntu-latest | |
| needs: build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - service: backend | |
| image: secuscan-backend | |
| - service: frontend | |
| image: secuscan-frontend | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Download image artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.image }}-tar | |
| path: /tmp | |
| - name: Load image | |
| run: docker load -i /tmp/${{ matrix.image }}.tar | |
| # Non-root user check | |
| - name: Assert container does NOT run as root | |
| run: | | |
| WHOAMI=$(docker run --rm ${{ matrix.image }}:ci whoami 2>/dev/null || true) | |
| UID_VAL=$(docker run --rm ${{ matrix.image }}:ci id -u 2>/dev/null || echo "0") | |
| echo "Container user: ${WHOAMI} (UID=${UID_VAL})" | |
| if [ "${UID_VAL}" = "0" ]; then | |
| echo "FAIL: ${{ matrix.service }} container runs as root (UID 0)." | |
| echo " Add a non-root USER instruction to the Dockerfile." | |
| exit 1 | |
| fi | |
| echo "PASS: running as non-root user '${WHOAMI}' (UID=${UID_VAL})" | |
| # No SUID/SGID binaries | |
| - name: Check for unexpected SUID/SGID binaries | |
| run: | | |
| SUID_FILES=$(docker run --rm --entrypoint find ${{ matrix.image }}:ci \ | |
| / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null || true) | |
| if [ -n "${SUID_FILES}" ]; then | |
| echo "WARNING: SUID/SGID binaries found in ${{ matrix.service }} image:" | |
| echo "${SUID_FILES}" | |
| # Warn but don't fail – some base images include ping/su; document if intentional | |
| else | |
| echo "PASS: No unexpected SUID/SGID binaries." | |
| fi | |
| # No secrets baked into image | |
| - name: Scan image layers for secrets (Trivy secret scanner) | |
| uses: aquasecurity/trivy-action@v0.36.0 | |
| with: | |
| image-ref: ${{ matrix.image }}:ci | |
| format: table | |
| exit-code: "1" | |
| scanners: secret | |
| severity: CRITICAL,HIGH,MEDIUM | |
| # Dockerfile lint (hadolint) | |
| - name: Lint ${{ matrix.service }} Dockerfile with hadolint | |
| uses: hadolint/hadolint-action@v3.1.0 | |
| with: | |
| dockerfile: ./${{ matrix.service }}/Dockerfile | |
| failure-threshold: error |