> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pipefort.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CI integration

> Use pipefort as a self-scanning step in GitHub Actions.

The CLI is a single static binary and exits non-zero on findings above a threshold, so it drops straight into any CI step.

## GitHub Action

The quickest path is the official Pipefort Action, which runs the scanner in a
container — no install step:

```yaml theme={null}
name: pipefort

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  scan:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v4
      - uses: raphabot/pipefort@v0.1.0
        with:
          path: .
          ruleset: owasp
          fail-on: HIGH
          output: console
```

| Input          | Default            | Description                                                                                                                                                                                                                                                       |
| -------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `path`         | `.`                | Path to scan for workflow files.                                                                                                                                                                                                                                  |
| `ruleset`      | `all`              | `all`, `owasp`, `slsa`, or a specific level (e.g. `slsa-build-l3`).                                                                                                                                                                                               |
| `fail-on`      | `MEDIUM`           | Fail the job at or above this severity: `HIGH`/`MEDIUM`/`LOW`/`INFO`/`NONE`.                                                                                                                                                                                      |
| `output`       | `sarif`            | `sarif`, `json`, or `console`.                                                                                                                                                                                                                                    |
| `sarif-file`   | `pipefort.sarif`   | Where the SARIF report is written (when `output: sarif`).                                                                                                                                                                                                         |
| `github-token` | the workflow token | Token for the [online supply-chain pin audits](/rules/overview#online-pinned-action-audits) (known-vulnerable, impostor-commit, ref/version-mismatch, typosquat). They run automatically with the default token; set `github-token: ''` for a fully offline scan. |

To publish findings to the **Security → Code scanning** tab, leave `output` at its
`sarif` default and add an upload step — see
[SARIF for GitHub code scanning](#sarif-for-github-code-scanning) below.

### Manual install (without the Action)

If you'd rather not use a container action, install the released binary directly:

```yaml theme={null}
      - name: Install scanner
        run: |
          curl -sSL -o pipefort.tar.gz \
            https://github.com/raphabot/pipefort/releases/latest/download/pipefort_$(curl -s https://api.github.com/repos/raphabot/pipefort/releases/latest | grep tag_name | cut -d'"' -f4)_linux_amd64.tar.gz
          tar -xzf pipefort.tar.gz
          sudo mv pipefort /usr/local/bin/

      - name: Scan workflows
        run: pipefort -p . -s HIGH -r owasp
        env:
          GITHUB_TOKEN: ${{ github.token }}  # enables the online pin audits
```

A few things worth calling out:

* **`-s HIGH`** — only fail the build on HIGH findings. Start strict-but-quiet, then tighten to `MEDIUM` once the baseline is clean.
* **`-r owasp`** — keep the gate focused on the five OWASP categories; treat the three best-practice checks as advisory until you're ready to enforce them.
* **`permissions: contents: read`** — this scanner job itself follows [CICD-SEC-5](/rules/cicd-sec-5). It only reads code.
* **`timeout-minutes: 5`** — follows [BEST-PRAC-2](/rules/best-prac-2).

<Tip>
  For reproducible builds, pin a specific version (e.g. `download/v0.1.0/pipefort_v0.1.0_linux_amd64.tar.gz`) rather than `latest`.
</Tip>

## SARIF for GitHub code scanning

Emit SARIF 2.1.0 with `-o sarif` and upload it with `github/codeql-action/upload-sarif`.
Findings then show up in the repo's **Security → Code scanning** tab and as inline
annotations on pull requests — the same surface zizmor, poutine, and OpenSSF
Scorecard integrate with.

Each result carries a stable `partialFingerprints` entry (`pipefort/v1`) built
from the rule, file, and finding content — not line numbers — so code scanning
tracks a finding across commits instead of closing and reopening it whenever
unrelated edits shift it down the file. It's the same identity the
[web app's triage](/webapp/finding-triage) uses.

```yaml theme={null}
name: pipefort

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read
  security-events: write  # required to upload SARIF

jobs:
  scan:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4

      - name: Scan workflows (SARIF)
        run: pipefort -p . -o sarif -s NONE > pipefort.sarif

      - name: Upload to code scanning
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: pipefort.sarif
```

<Note>
  Use `-s NONE` on the scan step so a finding doesn't fail the job before the SARIF
  is uploaded — let the **Code scanning** alerts (or a separate gating step) enforce
  policy. Severities map to SARIF levels as `HIGH→error`, `MEDIUM→warning`, and
  `LOW`/`INFO`→`note`, and each result carries a `security-severity` score so GitHub
  sorts them correctly. Toxic combinations ("Attacker Mind") have no SARIF analog and
  are omitted from this format — use `-o json` for the complete envelope.
</Note>

The same SARIF export is available from the web app on a repository's page
(**Export → Download SARIF**).

## JSON output for downstream tooling

Pipe to `jq` for custom policy:

```yaml theme={null}
      - name: Scan workflows (JSON)
        run: pipefort -p . -o json -s NONE > findings.json

      - uses: actions/upload-artifact@v4
        with:
          name: pipefort-findings
          path: findings.json
```

`-s NONE` keeps the step from failing so the artifact is always uploaded; gate separately on the JSON content with `jq` if you want richer policy.

## Pre-commit hook

Pipefort ships a [pre-commit](https://pre-commit.com/) hook. Add it to your
`.pre-commit-config.yaml`:

```yaml theme={null}
repos:
  - repo: https://github.com/raphabot/pipefort
    rev: v0.1.0
    hooks:
      - id: pipefort
```

The hook builds the Go CLI and scans the repo's GitHub Actions and GitLab CI
workflow files on every commit. The scanner is fast enough (sub-second on most
repos) to run inline.

Prefer a raw git hook? A one-liner works too:

```bash theme={null}
# .git/hooks/pre-commit
#!/usr/bin/env bash
set -e
pipefort -p . -s HIGH -r owasp
```
