Return 503 for expired proxy tokens #9039
Workflow file for this run
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: Security Scan | |
| on: | |
| workflow_call: | |
| workflow_dispatch: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| schedule: | |
| # Run daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| permissions: | |
| contents: read | |
| security-events: write | |
| jobs: | |
| grype-repo-scan: | |
| name: Grype Repository Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Run Grype vulnerability scanner | |
| id: grype-scan | |
| uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0 | |
| with: | |
| path: "." | |
| output-format: "sarif" | |
| fail-build: false | |
| - name: Upload Grype scan results to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v4 | |
| if: always() | |
| with: | |
| sarif_file: ${{ steps.grype-scan.outputs.sarif }} | |
| category: "grype" | |
| govulncheck: | |
| name: Go Vulnerability Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - name: Run govulncheck | |
| uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee # v1 | |
| with: | |
| go-version-input: 'stable' | |
| go-package: ./... | |
| repo-checkout: false | |
| output-format: json | |
| output-file: govulncheck-output.json | |
| - name: Check for vulnerabilities (with exclusions) | |
| run: | | |
| # Ignored vulnerabilities with justification: | |
| # GO-2025-4192: sigstore/timestamp-authority excessive memory allocation (CVE-2025-66564) | |
| # Indirect dependency via sigstore-go (used for container signature verification). | |
| # The vulnerability affects timestamp-authority server request parsing endpoints. | |
| # ToolHive only uses sigstore-go as a client to verify signatures, it does not | |
| # expose any timestamp-authority server endpoints. Fix requires sigstore-go to | |
| # upgrade to timestamp-authority/v2 which hasn't been released yet. | |
| # GO-2026-4514: buger/jsonparser Delete function DoS via malformed JSON (CVE-2025-54410) | |
| # Indirect dependency via mcp-go, invopop/jsonschema, wk8/go-ordered-map. | |
| # The vulnerability is in the Delete function which is not called by ToolHive | |
| # or any of its dependencies. No fixed version exists yet (all versions affected). | |
| # GO-2026-4883: Off-by-one error in Moby plugin privilege validation (CVE-2026-33997) | |
| # Affects the Docker daemon's plugin privilege handling code. ToolHive only uses | |
| # the Docker client SDK to manage containers, not the daemon plugin subsystem. | |
| # No fixed version exists for github.com/docker/docker; fix is only in | |
| # github.com/moby/moby/v2 v2.0.0-beta.8+ which is not yet available as a | |
| # docker/docker release. | |
| # GO-2026-4887: AuthZ plugin bypass with oversized request bodies (CVE-2026-34040) | |
| # Affects the Docker daemon's AuthZ plugin mechanism. ToolHive only uses the | |
| # Docker client SDK and does not run or configure AuthZ plugins. No fixed version | |
| # exists for github.com/docker/docker; fix is only in github.com/moby/moby/v2 | |
| # v2.0.0-beta.8+ which is not yet available as a docker/docker release. | |
| IGNORED_VULNS="GO-2025-4192 GO-2026-4514 GO-2026-4883 GO-2026-4887" | |
| # Show the raw output for debugging | |
| echo "::group::govulncheck raw output" | |
| cat govulncheck-output.json | |
| echo "::endgroup::" | |
| # Extract vulnerability IDs that have actual findings (called symbols) | |
| # The JSON has "finding" objects with "osv" field only for vulnerabilities | |
| # where vulnerable code paths are actually called | |
| FOUND_VULNS=$(jq -r 'select(.finding != null) | .finding.osv' govulncheck-output.json | sort -u | grep -E '^GO-' || true) | |
| if [ -z "$FOUND_VULNS" ]; then | |
| echo "✅ No vulnerabilities found" | |
| exit 0 | |
| fi | |
| echo "Found vulnerabilities: $FOUND_VULNS" | |
| # Check if all found vulnerabilities are in the ignore list | |
| UNIGNORED="" | |
| for vuln in $FOUND_VULNS; do | |
| if ! echo "$IGNORED_VULNS" | grep -qw "$vuln"; then | |
| UNIGNORED="$UNIGNORED $vuln" | |
| fi | |
| done | |
| UNIGNORED=$(echo "$UNIGNORED" | xargs) | |
| if [ -z "$UNIGNORED" ]; then | |
| echo "⚠️ All vulnerabilities are ignored: $FOUND_VULNS" | |
| exit 0 | |
| fi | |
| echo "❌ Vulnerabilities need attention: $UNIGNORED" | |
| exit 1 |