CI/CD integration
Vulkro is built to run in CI. This page covers the common setups. For more depth, see Integrations.
If this repository is connected to Vulkro Cloud, you do not need a pipeline step for pull requests: Vulkro Cloud scans each pull request into a tracked branch and reports back on it with a status and a summary comment (pull-request checks are on every Vulkro Cloud plan). See Pull requests in Vulkro Cloud.
How the exit code works
vulkro scan exits 1 if it finds any Critical or High issue, and 0
otherwise. It also exits 1 with license_required if the runner has no
licence (see Licence the runner). That is the whole
contract, so it drops into any CI runner:
vulkro scan . # fails the build on Critical/High
vulkro scan . --fail-on critical,high,medium # also fail on Medium
vulkro scan . --all-confidence # show everything; still gates on severity
--min-confidence controls which findings are shown. --fail-on controls
which severities fail the build.
Licence the runner
Vulkro needs an active trial or Pro on every machine that scans, CI runners
included. Create a CI key in the customer portal
(app.vulkro.com), store it as a secret in your CI
system, expose it to the job as VULKRO_ACCOUNT_TOKEN, and run
vulkro login before the first scan. A CI key works for the trial and for
paid plans, uses no device seat, and can be revoked. On an air-gapped
runner, set VULKRO_LICENSE_B64 to the base64 of a .lic licence file
instead.
Without either, the scan step fails with exit code 1 and the marker
license_required. See Accounts and licensing.
GitHub Actions
name: vulkro
on:
push:
branches: [main]
pull_request:
jobs:
scan:
runs-on: ubuntu-latest
env:
VULKRO_ACCOUNT_TOKEN: ${{ secrets.VULKRO_ACCOUNT_TOKEN }} # CI key from the portal
permissions:
contents: read
security-events: write # required to upload SARIF
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # required to scan git history for secrets
- name: Install vulkro
run: curl -fsSL https://dist.vulkro.com/install.sh | bash
- name: Sign in with the CI key
run: vulkro login
- name: Run scan (SARIF)
run: vulkro scan . --format sarif > vulkro.sarif
- name: Upload to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: vulkro.sarif
- name: Block the PR on Critical/High
run: vulkro scan . --min-confidence high
There are two scan steps on purpose. The first always succeeds and produces SARIF, so the results always show up in GitHub Code Scanning. The second is the gate: it fails the build if there are unresolved Critical or High findings.
GitLab CI
vulkro:
stage: test
image: ubuntu:24.04
# VULKRO_ACCOUNT_TOKEN: a masked CI/CD variable holding your CI key
script:
- curl -fsSL https://dist.vulkro.com/install.sh | bash
- vulkro login
- vulkro scan . --format junit > vulkro-junit.xml
- vulkro scan . --min-confidence high
artifacts:
when: always
reports:
junit: vulkro-junit.xml
paths:
- vulkro-junit.xml
expire_in: 30 days
The JUnit output shows up directly in GitLab's merge-request report, with every finding as a failed test and its file and line attached.
pre-commit (fast local check)
repos:
- repo: local
hooks:
- id: vulkro-fast
name: vulkro (fast, source only)
entry: vulkro scan . --min-confidence high --scope src
language: system
pass_filenames: false
stages: [pre-commit]
--scope src skips Dockerfiles, lockfiles, and templates to keep the hook fast.
Post results as a PR comment
vulkro scan . --format gh-pr > comment.md
gh pr comment "$PR_NUMBER" --body-file comment.md
The comment summarizes the severity counts and links each Critical and High finding straight to the line of code.
Gate only on new problems
To fail the build only on issues that are new compared to main:
vulkro gate --base origin/main
vulkro gate scans both your branch and the base, then fails only on findings
that are new. Existing tech debt, re-ordering, and whitespace changes never fail
the build. See Baselines explained.
Useful environment variables
| Variable | Effect |
|---|---|
VULKRO_ACCOUNT_TOKEN | The CI key that licenses the runner (vulkro login exchanges it for a lease). |
VULKRO_LICENSE_B64 | The base64 of a .lic licence file, for air-gapped runners. |
VULKRO_OFFLINE=1 | Skip the CVE download in air-gapped runners. |
VULKRO_GIT_BLAME=1 | Attach the code owner to each finding for reports. |
What's next
- GitHub Actions deep-dive -> - caching, monorepos, and matrices.
- Output formats -> - SBOMs, GDPR reports, and executive HTML.
- Compliance gating -> - block PRs on PCI DSS, SOC 2, or HIPAA control failures.