diff --git a/CHANGELOG.md b/CHANGELOG.md index f56f9cd..4123343 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,16 @@ after 1.0. ([#38]). The same check stops an older patch line, re-released after a newer one, from becoming Latest. `v1` already refused to move backwards for that case. +### Security + +- **The GitHub Action warns when the job token is readable by the cifail image.** The action + mounts the workspace into the container, and `actions/checkout` v5 and earlier store the + job token in `.git/config` unless given `persist-credentials: false`. The action now checks + the workspace's `.git/config`, and those of `path:` checkouts one level down, and warns + when it finds a persisted credential ([#39]). Checkout v6 and later keep the token outside + the workspace and do not trigger it. The README's example now checks out with + `persist-credentials: false`. + ## [0.3.1] - 2026-08-21 A fix release for the reporting path: the GitHub Action could not explain a failure, because @@ -519,6 +529,7 @@ documented install instructions can find them. Fixed in 0.2.0. [#21]: https://github.com/SebHenn/ci-failure-intelligence/issues/21 [#37]: https://github.com/SebHenn/ci-failure-intelligence/issues/37 [#38]: https://github.com/SebHenn/ci-failure-intelligence/issues/38 +[#39]: https://github.com/SebHenn/ci-failure-intelligence/issues/39 [0.3.1]: https://github.com/SebHenn/ci-failure-intelligence/compare/v0.3.0...v0.3.1 [0.3.0]: https://github.com/SebHenn/ci-failure-intelligence/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/SebHenn/ci-failure-intelligence/compare/v0.1.0...v0.2.0 diff --git a/README.md b/README.md index 364d829..bc4ff13 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,10 @@ Capture a failing step's output, then let the action explain it — the analysis the job's **step summary**. No install needed; it runs the Docker image for you. ```yaml +- uses: actions/checkout@v7 + with: + persist-credentials: false + - name: Build run: dotnet build 2>&1 | tee build.log @@ -340,6 +344,12 @@ the job's **step summary**. No install needed; it runs the Docker image for you. > `windows-*` / `macos-*` runners have no Docker daemon. On those, install the binary and call > it directly — see [Anywhere else](#anywhere-else-plain-pipe). +> **Check out with `persist-credentials: false`.** The action mounts the workspace into the +> cifail container, so the image can read everything in it. That includes the job token that +> `actions/checkout` v5 and earlier store in `.git/config` by default. v6 and later keep the +> token outside the workspace, so the setting matters less there, but it costs nothing. The +> action warns when it finds a token in the workspace's `.git/config`. + **`@v1` is a moving tag**: it follows the newest release, so you get fixes without editing your workflow. The flip side is that the ref you wrote doesn't identify a build — so the step prints one line naming what actually ran, first thing in its log and at the foot of the step @@ -357,8 +367,9 @@ release, so one pin covers both: pin by version if you'd rather upgrade delibera Inputs: `log` (file, **directory or glob** to analyze), `mode` (`analyze`, the default, or `gate`), `args` (extra flags, e.g. `--type node`), `image` (run a different image; by -default, the one from the action's own release), `summary` (write to the step summary, default `true`), `fail` (propagate cifail's -exit code; off by default since it runs after a failed build), `comment` (post the analysis as +default, the one from the action's own release), `summary` (write to the step summary, +default `true`), `fail` (propagate cifail's exit code; off by default since it runs after a +failed build), `comment` (post the analysis as a pull-request comment, default `false`), and `sarif` (also write a SARIF report to that path). For shared history, set `CIFAIL_DB_PROVIDER` / `CIFAIL_DB_CONNECTION` in the job env. diff --git a/action.yml b/action.yml index 9810cd7..79a1604 100644 --- a/action.yml +++ b/action.yml @@ -126,6 +126,19 @@ runs: INPUT_IMAGE="ghcr.io/sebhenn/cifail:$CIFAIL_ACTION_VERSION" fi + # The whole workspace is mounted into the container below, so a token persisted in it is + # readable by the image (#39). actions/checkout v5 and earlier write the job token into + # .git/config unless given `persist-credentials: false`. v6 and later keep it under + # $RUNNER_TEMP, which is not mounted, so only config files inside the workspace are + # checked: the root checkout and one level down, for `path:` checkouts. The container + # needs the workspace (the log, the reports, git history), so this warns rather than + # hiding .git. + for git_config in .git/config ./*/.git/config; do + if [ -f "$git_config" ] && grep -qi 'extraheader' "$git_config"; then + echo "::warning::cifail: $git_config holds a persisted credential, and the workspace is mounted into the cifail container, so the image can read it. Check out with 'persist-credentials: false', or use actions/checkout v6 or later." + fi + done + docker pull "$INPUT_IMAGE" >/dev/null 2>&1 || true # ---- provenance ----------------------------------------------------------------