fix(oauth): align client metadata with secret authentication #3540
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: Trivy | |
| # Scans the Docker image for OS-layer and dependency CVEs — the one gap | |
| # gitleaks/CodeQL/Dependabot leave open: Debian base-image packages and | |
| # post-release CVE drift live only in the published image. | |
| # | |
| # Two targets: | |
| # - trivy-published (cron + merges to main + dispatch): the GHCR :latest | |
| # image users pull today, so a CVE disclosed after a release still | |
| # surfaces — merges also keep the README status badge current. | |
| # - trivy-pr (pull_request): an image built from the branch, so a CVE | |
| # entering via Dockerfile/base-image changes surfaces before merge. | |
| # Its job ID is the required-status-check context in the branch | |
| # ruleset — tool-prefixed so it's unambiguous in that flat namespace. | |
| # | |
| # Scope is vulnerability scanning only — secrets are gitleaks' job, and | |
| # the IaC here is Pulumi TypeScript, which Trivy doesn't parse. | |
| # | |
| # trivy-pr gates merges: it exits non-zero on CRITICAL/HIGH findings, | |
| # and is a required status check in the branch ruleset. trivy-published | |
| # stays report-only — its findings land in the Security tab; there is | |
| # no merge to block. | |
| on: | |
| schedule: | |
| - cron: "23 9 * * 1" # weekly, Monday 09:23 UTC | |
| push: | |
| branches: [main] | |
| pull_request: | |
| workflow_dispatch: | |
| # Top-level token is read-only; each job grants its own SARIF upload. | |
| permissions: | |
| contents: read | |
| jobs: | |
| trivy-published: | |
| if: github.event_name != 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write # SARIF upload to the Security tab | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| # The images may not be pullable — a fresh fork, or a repo that | |
| # hasn't cut its first release — and this job also fires on every | |
| # push to main, so gate the scans on the manifests existing rather | |
| # than failing the run (and the README badge). | |
| - name: Check published images exist | |
| id: images | |
| run: | | |
| if docker manifest inspect "ghcr.io/${{ vars.GHCR_USER }}/vault-cortex:latest" >/dev/null 2>&1; then | |
| echo "latest=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "latest=false" >> "$GITHUB_OUTPUT" | |
| echo "::notice::vault-cortex:latest not published yet — skipping scan" | |
| fi | |
| if docker manifest inspect "ghcr.io/${{ vars.GHCR_USER }}/vault-cortex:remote" >/dev/null 2>&1; then | |
| echo "remote=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "remote=false" >> "$GITHUB_OUTPUT" | |
| echo "::notice::vault-cortex:remote not published yet — skipping scan" | |
| fi | |
| - name: Scan published image (local target) | |
| if: steps.images.outputs.latest == 'true' | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 | |
| with: | |
| # Manifest list resolves per-runner (amd64 here); the Debian OS | |
| # package set is identical across arches, so amd64-only is fine. | |
| image-ref: ghcr.io/${{ vars.GHCR_USER }}/vault-cortex:latest | |
| scanners: vuln | |
| severity: CRITICAL,HIGH | |
| ignore-unfixed: true | |
| format: sarif | |
| output: trivy-results.sarif | |
| exit-code: "0" | |
| # hashFiles guards: skip the upload when the corresponding scan was | |
| # skipped or died before writing its SARIF, instead of layering a | |
| # missing-file error on top of the real outcome. | |
| - name: Upload SARIF to the Security tab | |
| if: always() && hashFiles('trivy-results.sarif') != '' | |
| uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0 | |
| with: | |
| sarif_file: trivy-results.sarif | |
| category: trivy-published-image | |
| # The :remote target layers s6-overlay + obsidian-headless on top of | |
| # the local target — its extra packages need their own CVE watch. | |
| - name: Scan published image (remote target) | |
| if: steps.images.outputs.remote == 'true' | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 | |
| with: | |
| image-ref: ghcr.io/${{ vars.GHCR_USER }}/vault-cortex:remote | |
| scanners: vuln | |
| severity: CRITICAL,HIGH | |
| ignore-unfixed: true | |
| format: sarif | |
| output: trivy-results-remote.sarif | |
| exit-code: "0" | |
| - name: Upload remote SARIF to the Security tab | |
| if: always() && hashFiles('trivy-results-remote.sarif') != '' | |
| uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0 | |
| with: | |
| sarif_file: trivy-results-remote.sarif | |
| category: trivy-published-image-remote | |
| trivy-pr: | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write # SARIF upload to the Security tab | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 | |
| # The base stage's apt-get upgrade layer is content-addressed — it | |
| # caches indefinitely until the Dockerfile or base image changes. | |
| # Passing today's date as APT_UPGRADE_DATE busts that layer daily so | |
| # Debian security patches are always current in the scanned image. | |
| - name: Cache-bust date for apt-get upgrade | |
| id: date | |
| run: echo "date=$(date +'%Y-%m-%d')" >> "$GITHUB_OUTPUT" | |
| # Both Dockerfile targets build and scan as steps of this one job — | |
| # its job ID is the required-status-check context in the branch | |
| # ruleset, so adding a job would need a ruleset update. | |
| - name: Build image from branch (local target) | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: . | |
| target: local | |
| # Make the built image visible to the local Docker daemon so the | |
| # scan step can reference it by tag. | |
| load: true | |
| tags: vault-cortex:pr-scan | |
| build-args: APT_UPGRADE_DATE=${{ steps.date.outputs.date }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build image from branch (remote target) | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| with: | |
| context: . | |
| target: remote | |
| load: true | |
| tags: vault-cortex:pr-scan-remote | |
| build-args: APT_UPGRADE_DATE=${{ steps.date.outputs.date }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Scan branch image (local target) | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 | |
| with: | |
| image-ref: vault-cortex:pr-scan | |
| scanners: vuln | |
| severity: CRITICAL,HIGH | |
| ignore-unfixed: true | |
| format: sarif | |
| output: trivy-results.sarif | |
| exit-code: "1" # gate: fail the PR on CRITICAL/HIGH findings | |
| # Runs even when the local scan gates first (exit-code 1), so a | |
| # vulnerability in the shared base image can't mask remote-only | |
| # findings in the extra packages (s6-overlay, obsidian-headless). | |
| - name: Scan branch image (remote target) | |
| if: success() || failure() | |
| uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 | |
| with: | |
| image-ref: vault-cortex:pr-scan-remote | |
| scanners: vuln | |
| severity: CRITICAL,HIGH | |
| ignore-unfixed: true | |
| format: sarif | |
| output: trivy-results-remote.sarif | |
| exit-code: "1" # gate: fail the PR on CRITICAL/HIGH findings | |
| # Fork PRs don't get security-events write access, so the upload | |
| # would 403 — scan results still show in the job log for forks. | |
| # hashFiles guard: no SARIF exists if the build failed before the scan. | |
| - name: Upload SARIF to the Security tab | |
| if: always() && hashFiles('trivy-results.sarif') != '' && github.event.pull_request.head.repo.full_name == github.repository | |
| uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0 | |
| with: | |
| sarif_file: trivy-results.sarif | |
| category: trivy-published-image | |
| # hashFiles guard: the remote SARIF doesn't exist when the local scan | |
| # gates the job first (exit-code 1) or the remote build fails. | |
| - name: Upload remote SARIF to the Security tab | |
| if: always() && hashFiles('trivy-results-remote.sarif') != '' && github.event.pull_request.head.repo.full_name == github.repository | |
| uses: github/codeql-action/upload-sarif@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0 | |
| with: | |
| sarif_file: trivy-results-remote.sarif | |
| category: trivy-published-image-remote |