@GlitchOrb
VulnGate is an open-source, offline-first CI/CD vulnerability scanner and policy gate. The MVP is a single-binary CLI with SARIF 2.1.0 to stdout and logs/errors on stderr.
- Go 1.23+ (or use CI artifacts)
- Linux/macOS/Windows shell
Build locally:
go build -o ./bin/vulngate ./cmd/vulngate
./bin/vulngate --helpOr install into GOBIN:
go install ./cmd/vulngate
vulngate --helpIf installed via go install, use:
vulngate db init --db ./vulngate.db
vulngate db import --db ./vulngate.db --source ./examples/vulndb/osvOne-liner form:
vulngate db init --db ./vulngate.db && vulngate db import --db ./vulngate.db --source ./examples/vulndb/osvIf using local build output, replace vulngate with ./bin/vulngate.
vulngate scan --db ./vulngate.db . > results.sarifExit codes:
0: policy pass1: policy fail (gate violation)2: tool error
Add this step in a GitHub Actions job after creating results.sarif:
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarifA complete ready-to-use workflow is provided at:
examples/ci/github-actions-code-scanning.yml
name: VulnGate SARIF Scan
on: [push, pull_request]
permissions:
contents: read
security-events: write
jobs:
vulngate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- run: go build -o ./bin/vulngate ./cmd/vulngate
- run: |
./bin/vulngate db init --db ./vulngate.db
./bin/vulngate db import --db ./vulngate.db --source ./examples/vulndb/osv
- run: |
set +e
./bin/vulngate scan --db ./vulngate.db . > results.sarif
CODE=$?
echo "scan_exit=$CODE" >> "$GITHUB_OUTPUT"
test "$CODE" -ne 2
id: scan
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: results.sarif
- run: test "${{ steps.scan.outputs.scan_exit }}" != "1"Full file: examples/ci/github-actions-code-scanning.yml
stages: [scan]
vulngate_scan:
stage: scan
image: golang:1.24
script:
- go build -o ./bin/vulngate ./cmd/vulngate
- ./bin/vulngate db init --db ./vulngate.db
- ./bin/vulngate db import --db ./vulngate.db --source ./examples/vulndb/osv
- |
set +e
./bin/vulngate scan --db ./vulngate.db . > results.sarif
SCAN_EXIT=$?
set -e
if [ "$SCAN_EXIT" -eq 2 ]; then exit 2; fi
if [ "$SCAN_EXIT" -eq 1 ]; then exit 1; fi
artifacts:
when: always
paths: [results.sarif, vulngate.db]Full file: examples/ci/gitlab-ci.yml
pipeline {
agent any
stages {
stage('Build and Scan') {
steps {
sh '''
go build -o ./bin/vulngate ./cmd/vulngate
./bin/vulngate db init --db ./vulngate.db
./bin/vulngate db import --db ./vulngate.db --source ./examples/vulndb/osv
set +e
./bin/vulngate scan --db ./vulngate.db . > results.sarif
SCAN_EXIT=$?
set -e
echo "$SCAN_EXIT" > .vulngate_scan_exit
if [ "$SCAN_EXIT" -eq 2 ]; then exit 2; fi
'''
}
}
}
post {
always { archiveArtifacts artifacts: 'results.sarif', fingerprint: true }
}
}Full file: examples/ci/Jenkinsfile
Ready-to-use fixtures are under examples/:
examples/vulndb/osv/- sample OSV JSON dataset fordb importexamples/vulndb/osv-real/- real OSV advisory dataset for reproducible real-vulnerability testsexamples/repos/policy-fail/- deterministic policy-fail scan targetexamples/repos/policy-pass/- deterministic policy-pass scan targetexamples/repos/real-vuln-npm-lodash/- real vulnerable dependency fixture (lodash@4.17.20)tests/stress/large-repo/- stress fixture for performance validation
Fixture walkthrough:
./bin/vulngate scan --db ./vulngate.db ./examples/repos/policy-fail > fail.sarif
./bin/vulngate scan --db ./vulngate.db ./examples/repos/policy-pass > pass.sarifReal vulnerability demo:
./examples/scripts/run_real_vuln_demo.shMIT