diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb5f5b7..6475b5e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,3 +38,17 @@ jobs: run: | docker run --rm --entrypoint sh cerberus:ci -c \ 'cerberus version && semgrep --version && gitleaks version && trivy --version' + + # Dogfood: run the published image on this repo through the action itself. + # Also exercises the private-image pull path — ghcr packages are private + # unless the org allows public ones, so an unauthenticated pull would 403. + dogfood: + runs-on: ubuntu-latest + permissions: + contents: read + packages: read + steps: + - uses: actions/checkout@v4 + - uses: ./ + with: + mode: "off" diff --git a/README.md b/README.md index 829fdf9..0cefae6 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,17 @@ one job line covers pushes and merge requests. Add a nightly scheduled pipeline for dependency scanning: new CVEs land in code that never changed, so pushes alone will not surface them. +### Pulling a private image + +Container packages are private by default, and some organizations disallow public ones. Then the +runner has to authenticate: + +- **GitLab** — add a `DOCKER_AUTH_CONFIG` CI variable (group-level): + `{"auths":{"ghcr.io":{"auth":""}}}` where the token is a GitHub PAT with + `read:packages`. +- **GitHub** — nothing to do: the action logs in with the job's `GITHUB_TOKEN`. Give the job + `permissions: packages: read`. + Configuration lives in [`cerberus.yml`](cerberus.example.yml) in the repo root — scanners, extra args, custom SARIF-emitting checks, gate policy. diff --git a/action.yml b/action.yml index 9137f09..0ef9fb6 100644 --- a/action.yml +++ b/action.yml @@ -6,11 +6,13 @@ branding: inputs: url: - description: Ingest URL from the tracker's integration settings. - required: true + description: Ingest URL from the tracker's integration settings. Not needed when mode is `off`. + required: false + default: "" secret: - description: Ingest secret (store it as a repository or organization secret). - required: true + description: Ingest secret (store it as a repository or organization secret). Not needed when mode is `off`. + required: false + default: "" path: description: Directory to scan. required: false @@ -23,6 +25,13 @@ inputs: description: Cerberus image to run. required: false default: ghcr.io/startmatter/cerberus:latest + registry-token: + description: > + Token used to pull the image when it is private (the default GITHUB_TOKEN + works for images in the same organization; needs the `packages: read` + permission on the job). Leave empty for a public image. + required: false + default: ${{ github.token }} runs: using: composite @@ -33,6 +42,21 @@ runs: shell: bash run: git -C "${{ github.workspace }}" fetch --deepen=2 --quiet || true + # ghcr images are private unless the org allows public packages; an + # anonymous pull of a private image fails with 403. + - name: Log in to the registry + if: inputs.registry-token != '' + shell: bash + env: + REGISTRY_TOKEN: ${{ inputs.registry-token }} + run: | + registry="${{ inputs.image }}" + registry="${registry%%/*}" + case "$registry" in + *.*) echo "$REGISTRY_TOKEN" | docker login "$registry" -u "${{ github.actor }}" --password-stdin ;; + *) echo "cerberus: image has no registry host, skipping login" ;; + esac + - name: Run Cerberus shell: bash env: diff --git a/templates/gitlab-ci.yml b/templates/gitlab-ci.yml index 36d8be1..9037d9d 100644 --- a/templates/gitlab-ci.yml +++ b/templates/gitlab-ci.yml @@ -9,6 +9,13 @@ # K_SARIF_URL — the ingest URL from the tracker's integration settings # K_SARIF_SECRET — the secret (mask it) # +# If the image is private (ghcr packages are private unless the organization +# allows public ones), add a third group variable so the runner can pull it: +# DOCKER_AUTH_CONFIG (type: File is not needed — plain variable): +# {"auths":{"ghcr.io":{"auth":"BASE64_OF_username:github_pat_with_read:packages"}}} +# Build the value with: +# printf '%s' 'USER:TOKEN' | base64 +# # Pushes to the default branch report (tasks are created/closed); every other # branch and merge request runs a read-only check that gates the pipeline. #