fix(scanner): wire ramparts v0.8.x URL/stdio scanning via static replay shim #23
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: scanner-images | |
| # Build and publish the custom security scanner Docker images to | |
| # ghcr.io/smart-mcp-proxy/scanner-*. Vendor images (trivy, semgrep, the | |
| # AI scanner which lives in a separate repo) are NOT built here. | |
| # | |
| # Triggers: | |
| # - push to main that touches docker/scanners/** or this workflow file | |
| # - manual dispatch (for ad-hoc rebuilds) | |
| # - pull requests: builds without pushing (to catch Dockerfile drift) | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'docker/scanners/**' | |
| - '.github/workflows/scanner-images.yml' | |
| pull_request: | |
| paths: | |
| - 'docker/scanners/**' | |
| - '.github/workflows/scanner-images.yml' | |
| workflow_dispatch: | |
| inputs: | |
| scanner: | |
| description: 'Scanner id to rebuild (blank = all)' | |
| required: false | |
| default: '' | |
| permissions: | |
| contents: read | |
| packages: write | |
| security-events: write # required for SARIF upload to the Security tab | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # `platforms` defaults to multi-arch. ramparts overrides to linux/amd64 | |
| # only: it is the lone Rust-from-source wrapper, and `cargo install | |
| # ramparts` for an emulated linux/arm64 leg runs under QEMU (~5-10x | |
| # slower). A cold build of both arches blows past the runner budget and | |
| # the job gets cancelled mid-compile (MCP-2395). amd64-only finishes in | |
| # time; the binary is consumed on the host arch by Docker isolation. | |
| include: | |
| - id: snyk | |
| image: ghcr.io/smart-mcp-proxy/scanner-snyk | |
| context: docker/scanners/snyk | |
| platforms: linux/amd64,linux/arm64 | |
| - id: cisco | |
| image: ghcr.io/smart-mcp-proxy/scanner-cisco | |
| context: docker/scanners/cisco | |
| platforms: linux/amd64,linux/arm64 | |
| - id: ramparts | |
| image: ghcr.io/smart-mcp-proxy/scanner-ramparts | |
| context: docker/scanners/ramparts | |
| platforms: linux/amd64 | |
| - id: proximity | |
| image: ghcr.io/smart-mcp-proxy/scanner-proximity | |
| context: docker/scanners/proximity | |
| platforms: linux/amd64,linux/arm64 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - name: Skip if not selected | |
| if: ${{ github.event_name == 'workflow_dispatch' && inputs.scanner != '' && inputs.scanner != matrix.id }} | |
| run: echo "Skipping ${{ matrix.id }} (workflow_dispatch selected ${{ inputs.scanner }})" && exit 0 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 | |
| - name: Set up Buildx | |
| uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 | |
| - name: Log in to GHCR | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Derive tags | |
| id: tags | |
| run: | | |
| set -euo pipefail | |
| short_sha="${GITHUB_SHA:0:7}" | |
| echo "short_sha=$short_sha" >> "$GITHUB_OUTPUT" | |
| if [ "${GITHUB_REF}" = "refs/heads/main" ]; then | |
| echo "tags=${{ matrix.image }}:latest,${{ matrix.image }}:$short_sha" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "tags=${{ matrix.image }}:pr-${{ github.event.pull_request.number || 'dev' }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Build and push | |
| uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0 | |
| with: | |
| context: ${{ matrix.context }} | |
| platforms: ${{ matrix.platforms }} | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.tags.outputs.tags }} | |
| cache-from: type=gha,scope=scanner-${{ matrix.id }} | |
| cache-to: type=gha,scope=scanner-${{ matrix.id }},mode=max | |
| labels: | | |
| org.opencontainers.image.source=https://github.com/smart-mcp-proxy/mcpproxy-go | |
| org.opencontainers.image.revision=${{ github.sha }} | |
| # Trivy image scan — runs only on push/workflow_dispatch (not pull_request) because | |
| # multi-platform builds (linux/amd64,linux/arm64) cannot be loaded to the runner with | |
| # `load: true`, so there is no local image to scan on PRs. On push the image is | |
| # already in GHCR and Trivy pulls it directly. | |
| # exit-code: '0' → report-only, never fails the build. Scanner base images routinely | |
| # carry unfixable CVEs (upstream OS packages); blocking builds on those would create | |
| # constant noise with no actionable remediation. Visibility via the Security tab and | |
| # the workflow log is the goal. | |
| - name: Scan image with Trivy | |
| if: github.event_name != 'pull_request' | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 | |
| with: | |
| image-ref: ${{ matrix.image }}:${{ steps.tags.outputs.short_sha }} | |
| scan-type: image | |
| severity: 'CRITICAL,HIGH' | |
| ignore-unfixed: true | |
| exit-code: '0' | |
| format: table | |
| - name: Upload Trivy SARIF to Security tab | |
| if: github.event_name != 'pull_request' | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 | |
| with: | |
| image-ref: ${{ matrix.image }}:${{ steps.tags.outputs.short_sha }} | |
| scan-type: image | |
| severity: 'CRITICAL,HIGH' | |
| ignore-unfixed: true | |
| exit-code: '0' | |
| format: sarif | |
| output: trivy-results-${{ matrix.id }}.sarif | |
| - name: Upload SARIF | |
| if: github.event_name != 'pull_request' | |
| uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 | |
| with: | |
| sarif_file: trivy-results-${{ matrix.id }}.sarif | |
| category: trivy-${{ matrix.id }} |