name: "security" permissions: actions: read contents: read on: workflow_dispatch: # Uncomment when testing. # pull_request: schedule: # Run every 6 hours Monday-Friday! - cron: "0 0/6 * * 1-5" # Cancel in-progress runs for pull requests when developers push # additional changes concurrency: group: ${{ github.workflow }}-${{ github.ref }}-security cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: codeql: permissions: security-events: write runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }} steps: - name: Harden Runner uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 with: egress-policy: audit - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Setup Go uses: ./.github/actions/setup-go - name: Initialize CodeQL uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.29.5 with: languages: go, javascript # Workaround to prevent CodeQL from building the dashboard. - name: Remove Makefile run: | rm Makefile - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.29.5 - name: Send Slack notification on failure if: ${{ failure() }} run: | msg="❌ CodeQL Failed\n\nhttps://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" curl \ -qfsSL \ -X POST \ -H "Content-Type: application/json" \ --data "{\"content\": \"$msg\"}" \ "${{ secrets.SLACK_SECURITY_FAILURE_WEBHOOK_URL }}" trivy: permissions: security-events: write runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }} steps: - name: Harden Runner uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 with: egress-policy: audit - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - name: Setup Go uses: ./.github/actions/setup-go - name: Setup Node uses: ./.github/actions/setup-node - name: Setup sqlc uses: ./.github/actions/setup-sqlc - name: Install cosign uses: ./.github/actions/install-cosign - name: Install syft uses: ./.github/actions/install-syft - name: Install yq run: go run github.com/mikefarah/yq/v4@v4.44.3 - name: Install mockgen run: ./.github/scripts/retry.sh -- go install go.uber.org/mock/mockgen@v0.6.0 - name: Install protoc-gen-go run: ./.github/scripts/retry.sh -- go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.30 - name: Install protoc-gen-go-drpc run: ./.github/scripts/retry.sh -- go install storj.io/drpc/cmd/protoc-gen-go-drpc@v0.0.34 - name: Install Protoc run: | # protoc must be in lockstep with our dogfood Dockerfile or the # version in the comments will differ. This is also defined in # ci.yaml. set -euxo pipefail cd dogfood/coder mkdir -p /usr/local/bin mkdir -p /usr/local/include DOCKER_BUILDKIT=1 docker build . --target proto -t protoc protoc_path=/usr/local/bin/protoc docker run --rm --entrypoint cat protoc /tmp/bin/protoc > $protoc_path chmod +x $protoc_path protoc --version # Copy the generated files to the include directory. docker run --rm -v /usr/local/include:/target protoc cp -r /tmp/include/google /target/ ls -la /usr/local/include/google/protobuf/ stat /usr/local/include/google/protobuf/timestamp.proto - name: Build Coder linux amd64 Docker image id: build run: | set -euo pipefail version="$(./scripts/version.sh)" image_job="build/coder_${version}_linux_amd64.tag" # This environment variable force make to not build packages and # archives (which the Docker image depends on due to technical reasons # related to concurrent FS writes). export DOCKER_IMAGE_NO_PREREQUISITES=true # This environment variables forces scripts/build_docker.sh to build # the base image tag locally instead of using the cached version from # the registry. CODER_IMAGE_BUILD_BASE_TAG="$(CODER_IMAGE_BASE=coder-base ./scripts/image_tag.sh --version "$version")" export CODER_IMAGE_BUILD_BASE_TAG # We would like to use make -j here, but it doesn't work with the some recent additions # to our code generation. make "$image_job" echo "image=$(cat "$image_job")" >> "$GITHUB_OUTPUT" - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.34.0 with: image-ref: ${{ steps.build.outputs.image }} format: sarif output: trivy-results.sarif severity: "CRITICAL,HIGH" - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3.29.5 with: sarif_file: trivy-results.sarif category: "Trivy" - name: Upload Trivy scan results as an artifact uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: trivy path: trivy-results.sarif retention-days: 7 - name: Send Slack notification on failure if: ${{ failure() }} run: | msg="❌ Trivy Failed\n\nhttps://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" curl \ -qfsSL \ -X POST \ -H "Content-Type: application/json" \ --data "{\"content\": \"$msg\"}" \ "${{ secrets.SLACK_SECURITY_FAILURE_WEBHOOK_URL }}"