Skip to content

Tutorial: Setting Up GitHub CI

This tutorial sets up continuous CRA assessment in GitHub Actions — every PR gets scanned, findings appear in Code Scanning, and merges are gated on compliance.

  • Fleet scanner binary available (or use the Docker image)
  • GitHub repository with Actions enabled
  • Fleet API URL and key (optional, for dashboard integration)

Create .github/workflows/fleet-cra.yml:

name: CRA Compliance
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
checks: write
security-events: write
jobs:
cra-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run CRA Assessment
run: |
fleet scan \
--path . \
--ci \
--output json \
--output-file $RUNNER_TEMP/results.json \
--sbom --cbom \
--report $RUNNER_TEMP/cra-report.md
- name: Upload Evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: cra-evidence
path: |
${{ runner.temp }}/results.json
${{ runner.temp }}/cra-report.md
retention-days: 3650

SARIF integration puts findings directly in GitHub’s Security tab:

- name: Generate SARIF
if: always()
run: |
jq '{
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
version: "2.1.0",
runs: [{
tool: { driver: { name: "Fleet CRA Scanner", version: .catalog.version } },
results: [.findings[] | select(.source_locations and (.source_locations | length) > 0) | {
ruleId: .requirement_id,
message: { text: .message },
level: (if .status == "fail" then "error" else "warning" end),
locations: [.source_locations[] | {
physicalLocation: {
artifactLocation: { uri: .file },
region: { startLine: .line }
}
}]
}]
}]
}' $RUNNER_TEMP/results.json > $RUNNER_TEMP/results.sarif
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ${{ runner.temp }}/results.sarif

Make the scan fail PRs with critical findings:

- name: Compliance Gate
run: |
FAIL=$(jq '.summary.fail' $RUNNER_TEMP/results.json)
if [ "$FAIL" -gt 0 ]; then
echo "::error::CRA compliance failed: $FAIL findings"
exit 1
fi

Then in repository Settings > Branches > Branch protection:

  • Enable “Require status checks to pass”
  • Add “CRA Compliance / cra-scan” as required

The --ci flag automatically detects GitHub Actions and adds a Job Summary:

### Fleet CRA Assessment
| Metric | Count |
|--------|-------|
| Total | 152 |
| Pass | 55 |
| Fail | 40 |
| Needs Review | 57 |

CRA requires 10-year evidence retention. The workflow above uses retention-days: 3650 (10 years) for artifacts. For additional security, upload results to the Fleet API:

- name: Upload to Fleet
if: github.ref == 'refs/heads/main'
env:
FLEET_API_URL: ${{ secrets.FLEET_API_URL }}
FLEET_API_KEY: ${{ secrets.FLEET_API_KEY }}
run: |
fleet scan --path . --ci \
--api-url $FLEET_API_URL \
--api-key $FLEET_API_KEY

After setup, every PR shows:

  1. CRA compliance check status (pass/fail)
  2. Findings in GitHub Code Scanning (Security tab)
  3. Summary in the Actions job log
  4. Evidence artifacts retained for 10 years