Skip to content

CI/CD Pipelines

Add a single Vygl step to your pipeline to scan every push and pull request. The CLI auto-detects branch, commit, and repository URL from CI environment variables — the only secret you need to configure is VYGL_API_KEY.

name: Vygl Security Scan
on:
push:
branches: [main]
pull_request:
jobs:
security-scan:
runs-on: ubuntu-latest
container:
image: vygl/vygl-cli:latest
options: --entrypoint ""
env:
VYGL_API_KEY: ${{ secrets.VYGL_API_KEY }}
steps:
- uses: actions/checkout@v4
- run: vygl scan --fail-on high .
# Optional: post scan summary as a PR comment.
# Add a Git Token in project settings, then uncomment:
# - run: vygl scan --fail-on high --pr ${{ github.event.pull_request.number }} .

Add VYGL_API_KEY under Settings → Secrets and variables → Actions. Branch, commit, and repo URL are auto-detected from the GitHub Actions environment.

On a large codebase most of the scan is SAST. Three things keep it inside a CI job.

Cache SAST results between runs. SAST keeps each file’s results and, next time, analyses only the files that changed. It is still a full scan, so findings that disappear are still closed as fixed. A file is reused only if its contents and path, the exact rules and the engine version all match, so a ruleset update or engine upgrade starts over, and a cache file that can’t be read is ignored. CI runners start empty, so keep the cache directory between pipeline runs:

env:
VYGL_API_KEY: ${{ secrets.VYGL_API_KEY }}
# Relative to the workspace, which the job can always write (in a container
# job ${{ github.workspace }} is the host's path). The CLI never scans its own cache.
VYGL_CACHE_DIR: .vygl-cache
steps:
- uses: actions/checkout@v4
# After checkout: checkout cleans the workspace.
- uses: actions/cache@v4
with:
path: .vygl-cache
key: vygl-sast-${{ github.ref_name }}-${{ github.run_id }}
restore-keys: |
vygl-sast-${{ github.ref_name }}-
vygl-sast-${{ github.event.repository.default_branch }}-
- run: vygl scan --fail-on high .

The cache holds excerpts of your code, the same as the checkout it came from. Restore a protected branch’s cache only from runs of that branch. On GitHub a pull request cannot write its base branch’s cache; on GitLab, keep Use separate caches for protected branches turned on.

Budget. SAST gets 45 minutes and every other engine 15. The engines run side by side, so the scan takes about as long as the slowest one. An engine that runs out of time is stopped, and the scan ends INCOMPLETE with exit code 2. Its results are missing everything that engine would have found, so it isn’t a pass. Raise the budget with scan.engine_timeout_seconds (keep it under your CI’s own job timeout), or accept incomplete scans with --allow-incomplete.

Files cut short. SAST also limits how long each rule may spend on one file, and gives up on a file after three rules run out of time — more likely on a busy runner. The scan output lists such files, and Vygl leaves their existing findings as they were rather than marking them fixed.

Skip code that isn’t yours. Generated and vendored code — bundled libraries, minified files, generated data — costs scan time and produces findings you won’t fix. List it under scan.sast.exclude_paths. Findings already open in those files are retired as Out of policy, not counted as fixed.

When run inside CI, the CLI reads environment variables to fill in scan metadata:

  • Repository URL, branch, commit SHA — from CI-native variables (GITHUB_REPOSITORY, CI_COMMIT_REF_NAME, BITBUCKET_BRANCH, etc.).
  • PR number — auto-detected on GitHub Actions, GitLab CI, and Bitbucket Pipelines (from GITHUB_REF=refs/pull/N/merge, CI_MERGE_REQUEST_IID, and BITBUCKET_PR_ID respectively). Use --pr only to override or in unsupported CI systems.
  • Trigger type (push / pull_request / scheduled) — derived from CI variables.
  • Commit author (email, name, external ID) — from CI env or git log. Disable with scan.send_committer: false in .vygl.yml if you don’t want author metadata in the dashboard.

If detection fails, override with --repo-url, --branch, --commit, --pr, or --git-provider flags (VYGL_GIT_PROVIDER env var also works).