Skip to content

CI integration

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

On this page

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

- 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

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:

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:

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.