# CI integration

> Gating a pipeline on scan results, and publishing the evidence it produces.

Source: https://refpoint.dev/docs/guides/ci-integration

This guide covers picking a gate that matches your risk posture, wiring
refpoint into GitHub Actions or GitLab CI, and treating the output as evidence
rather than log noise.

## Choosing a gate

| Goal | Command shape |
|------|---------------|
| Hard gate on any failure | `refpoint run baseline` and let exit 1 fail the job |
| Tolerate low-severity failures | `--threshold 90`, gate on exit 5 |
| Gate on severity instead | `--impact 0.7` so only high-impact controls run |
| Gate on drift, not absolute state | `refpoint diff prev.json new.json --fail-on-regression` |
| Report only, never fail | Capture the exit code and ignore it, publish the artifact |

Errors deserve their own treatment. An unreachable target, exit code 2, is
neither a pass nor a policy failure. It is a broken scan, and it usually means
the job should be retried or investigated rather than the fleet remediated.

## GitHub Actions

```yaml
- name: Compliance scan
  run: |
    refpoint run profiles/linux-baseline \
      --targets-file fleet.rptargets \
      --host-tag env=prod \
      --reporter gha \
      --reporter json:result.json \
      --reporter html:report.html \
      --audit-log audit.ndjson \
      --signing-key "$RUNNER_TEMP/signing.key" \
      --threshold 95

- uses: actions/upload-artifact@v4
  if: always()
  with:
    name: compliance-evidence
    path: |
      result.json
      report.html
      audit.ndjson
```

The `gha` reporter emits workflow commands on stdout, so failed and errored
controls appear as inline annotations rather than being buried in the log, plus
one notice per profile carrying its score.

## GitLab CI

```yaml
compliance:
  script:
    - refpoint run profiles/linux-baseline
        --targets-file fleet.rptargets
        --reporter gitlab:gl-code-quality-report.json
        --reporter junit:report.xml
        --reporter json:result.json
  artifacts:
    when: always
    reports:
      codequality: gl-code-quality-report.json
      junit: report.xml
    paths:
      - result.json
```

The `gitlab` reporter produces Code Quality JSON, which renders inline in merge
requests and the pipeline widget, with severity derived from control impact.

## Gating on drift

Absolute state is a harsh gate for a fleet you inherited. Gating on change is
often the useful one. Keep the previous result as an artifact and compare:

```shell
refpoint run baseline --targets-file fleet.rptargets \
  --format json --output new.json || true

refpoint diff prev.json new.json --fail-on-regression
```

A target that produced results last time but is unreachable now counts as a
regression, because an unreachable host hides any number of real regressions.

## Verifying evidence downstream

A job that consumes a report produced elsewhere should verify it before trusting
it:

```shell
refpoint verify result.json --pubkey refpoint-signing.pub --audit-log audit.ndjson
```

It exits non-zero on any mismatch, so this is a gate in its own right.