diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3938344..ed29de7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,3 +4,21 @@ updates: directory: "/" schedule: interval: "daily" + open-pull-requests-limit: 10 + groups: + go-dependencies: + patterns: ["*"] + - package-ecosystem: "docker" + directory: "/containerssh" + schedule: + interval: "daily" + groups: + docker-deps: + patterns: ["*"] + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + groups: + actions: + patterns: ["*"] diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..c8c6086 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,71 @@ +name: Docker Build +on: + push: + branches: [main] + tags: ['v*'] + pull_request: + branches: [main] + schedule: + - cron: "0 3 * * 1" + +env: + CONTAINERSSH_VERSION: v0.6.0 + +jobs: + build-containerssh: + name: Build ContainerSSH + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0 + - name: Login to Docker Hub + if: github.event_name != 'pull_request' + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Login to Quay.io + if: github.event_name != 'pull_request' + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: quay.io + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_PASSWORD }} + - name: Login to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Docker metadata + id: meta + uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 + with: + images: | + containerssh/containerssh + quay.io/containerssh/containerssh + ghcr.io/${{ github.repository_owner }}/containerssh + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=sha,prefix=sha-,format=short + type=ref,event=tag + - name: Build and push + uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 + with: + context: ./containerssh + push: ${{ github.event_name != 'pull_request' }} + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + CONTAINERSSH_VERSION=${{ env.CONTAINERSSH_VERSION }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml new file mode 100644 index 0000000..06dcaa3 --- /dev/null +++ b/.github/workflows/trivy.yml @@ -0,0 +1,41 @@ +name: Trivy Security Scan +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '0 6 * * 1' +jobs: + scan-containerssh: + name: Scan ContainerSSH Image + runs-on: ubuntu-latest + permissions: + security-events: write + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0 + - name: Build ContainerSSH image + uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 + with: + context: ./containerssh + push: false + load: true + tags: containerssh/containerssh:scan + build-args: | + CONTAINERSSH_VERSION=v0.6.0 + - name: Run Trivy + uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 + with: + image-ref: 'containerssh/containerssh:scan' + format: 'sarif' + output: 'trivy-containerssh.sarif' + severity: 'CRITICAL,HIGH' + - name: Upload results + uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + if: always() + with: + sarif_file: 'trivy-containerssh.sarif' + category: 'containerssh' diff --git a/containerssh/Dockerfile b/containerssh/Dockerfile index c891557..d725d32 100644 --- a/containerssh/Dockerfile +++ b/containerssh/Dockerfile @@ -2,10 +2,11 @@ ARG CONTAINERSSH_VERSION ARG GITHUB_TOKEN ARG SOURCE_REPO=https://github.com/ContainerSSH/ContainerSSH -FROM alpine AS download +FROM alpine:3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 AS download ARG CONTAINERSSH_VERSION ARG GITHUB_TOKEN ARG SOURCE_REPO +ARG TARGETARCH RUN if [ -z "${CONTAINERSSH_VERSION}" ]; then echo "Error: No CONTAINERSSH_VERSION specified." >&2; exit 1; fi RUN if [ -z "${GITHUB_TOKEN}" ]; then echo "Warning: No GITHUB_TOKEN specified, build may fail." >&2; fi RUN apk add --no-cache curl @@ -16,7 +17,7 @@ RUN mkdir -p /containerssh && \ # Drop privileges for download USER 1022:1022 RUN cd /containerssh && \ - URL=${SOURCE_REPO}/releases/download/${CONTAINERSSH_VERSION}/containerssh_${CONTAINERSSH_VERSION/v/}_linux_amd64.tar.gz && \ + URL=${SOURCE_REPO}/releases/download/${CONTAINERSSH_VERSION}/containerssh_${CONTAINERSSH_VERSION/v/}_linux_${TARGETARCH}.tar.gz && \ if [ -n "${GITHUB_TOKEN}" ]; then \ curl -L -o containerssh.tar.gz --header 'authorization: Bearer ${GITHUB_TOKEN}' ${URL}; \ else \ @@ -27,7 +28,7 @@ RUN cd /containerssh && \ USER 0:0 RUN chown -R root:root /containerssh -FROM alpine +FROM alpine:3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 RUN apk upgrade --no-cache && apk add --no-cache 'libssl3' 'libcrypto3' COPY --from=download /containerssh/containerssh / COPY --from=download /containerssh/LICENSE* /