Program · CI

CI — Scan in your pipeline

Scan every push and pull request with CodesGuard — your code and its dependencies, in one scan — and let your organisation's policy decide whether the build may pass.

What a CI scan does

The job's result is the policy's verdict
0 passed · 1 failed · 2 not decided (part of the analysis did not finish; --allow-undecided lets the job pass) · 3 the scan could not be run or read.
A pull request is judged on what it changes
The scan is compared with the latest scan of the target branch, and only the findings the change introduces count (your policy's “new findings only” rule, on by default). Scan the branch itself too — on pushes to it — so there is a scan to compare with.
Each failing finding is named
The package, its version and the version that fixes it — or the file and line — in the job log and summary (the first 50; the count is always printed), as an annotation on the line in GitHub (the first 10, GitHub's limit per step) and on the merge request in GitLab (code quality report). Every one of them is in CodesGuard, on the scan.
A results file
SARIF 2.1.0, for GitHub code scanning: every finding on the repository's Security tab.

1. Create a CI token

An owner or admin creates one under Security → CI tokens (see Security & 2FA): give it a name, optionally limit it to one project, and choose when it expires. The token (cgci_…) is shown once — store it as a secret in your CI system.

What a CI token can do Start scans in your organisation (in its one project, when made for one) and read their results — nothing else: it cannot sign in, manage members or billing, or change policies. Revoking it in the same place stops it at once.

2. The CI client

One Python file (Python 3.9 or later, standard library only) uploads the code, waits for the scan and turns the verdict into the job's result:

Download
codeguard_ci.py (version 1.0.0)
SHA-256
2b10dc80dc68f614f1fe608f7d1176f189931617e10dccc695a261fe1878278c

Keep a copy in your repository, or download it in the job and check it against the checksum above, as the examples below do.

3. GitHub Actions

Add the token as the repository secret CODEGUARD_TOKEN, and your organisation and project ids as the variables CODEGUARD_ORG_ID and CODEGUARD_PROJECT_ID (the project id is optional for a token made for one project). Then add .github/workflows/codeguard.yml:

name: CodesGuard
on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read
  security-events: write   # for the code scanning upload

jobs:
  codeguard:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: CodesGuard scan
        env:
          CODEGUARD_TOKEN: ${{ secrets.CODEGUARD_TOKEN }}
          CODEGUARD_ORG_ID: ${{ vars.CODEGUARD_ORG_ID }}
          CODEGUARD_PROJECT_ID: ${{ vars.CODEGUARD_PROJECT_ID }}
          CODEGUARD_APP_URL: https://codesguard.io
        run: |
          curl -fsSL -o codeguard_ci.py https://docs.codesguard.io/assets/ci/codeguard_ci.py
          echo "2b10dc80dc68f614f1fe608f7d1176f189931617e10dccc695a261fe1878278c  codeguard_ci.py" | sha256sum -c -
          python3 codeguard_ci.py --path . --sarif codeguard.sarif
      - name: Upload to code scanning
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: codeguard.sarif

In a pull request the client compares with the target branch's latest scan by itself; set --base-branch to compare with another branch, or --no-diff to judge the whole scan.

4. GitLab CI

Set CODEGUARD_TOKEN (masked), CODEGUARD_ORG_ID and CODEGUARD_PROJECT_ID under Settings → CI/CD → Variables, and add the job to .gitlab-ci.yml:

codeguard:
  stage: test
  image: python:3.12-slim
  variables:
    CODEGUARD_APP_URL: https://codesguard.io
  script:
    - python3 -c "import urllib.request; urllib.request.urlretrieve('https://docs.codesguard.io/assets/ci/codeguard_ci.py', 'codeguard_ci.py')"
    - echo "2b10dc80dc68f614f1fe608f7d1176f189931617e10dccc695a261fe1878278c  codeguard_ci.py" | sha256sum -c -
    - python3 codeguard_ci.py --path . --sarif codeguard.sarif --codequality gl-code-quality-report.json
  artifacts:
    when: always
    paths:
      - codeguard.sarif
    reports:
      codequality: gl-code-quality-report.json
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

The failing findings of a merge request appear on it, in its code quality report.

5. Any other pipeline

export CODEGUARD_TOKEN=cgci_… CODEGUARD_ORG_ID=… CODEGUARD_PROJECT_ID=…
python3 codeguard_ci.py --path . --sarif codeguard.sarif --base-branch main
--api-url · CODEGUARD_API_URL
The CodesGuard API (default https://sast.codesguard.io).
--token · CODEGUARD_TOKEN
The CI token.
--org · CODEGUARD_ORG_ID
Your organisation's id.
--project · CODEGUARD_PROJECT_ID
The project to scan into.
--base-branch / --no-diff
What to compare with.
--exclude
A directory or pattern left out of the upload (repeatable; .git, .hg and .svn always are).
--allow-undecided
Pass the job when the verdict is not decided.

The scan has no time limit of its own: the job waits until it is done. Use your CI system's job timeout if you want one.

Programmatic access — API & webhooks

The release gate is one use of the platform API. The same authenticated access lets you drive CodesGuard from your own tools:

REST API
Start scans, read findings and manage projects over an authenticated REST API — available on every plan. The CI client above is a thin wrapper over it.
Webhooks
New findings — including the hourly re-check of your dependencies against fresh advisories (see SCA) — are delivered to the endpoints you choose, so your chat, ticketing or SIEM hears about them without polling.
Email notifications
Route new findings to the mailboxes your team already watches.
Results as data
Findings export as SARIF, CSV or JSON; dependency inventories as CycloneDX or SPDX SBOMs and OpenVEX statements — ready for code scanning, dashboards or audit.
Exact request and response shapes live in-app The authenticated API reference — endpoints, parameters and payloads — is available in your workspace. This page covers the pipeline workflow; use the in-app reference for the precise contract.

IAST in your pipeline

The CI scan above analyses your source and dependencies before the app runs. IAST adds the runtime half: attach its in-process agent to your JVM service in the same CI or staging job with a single -javaagent flag and a project token, then run your test suite or a DAST scan. Confirmed vulnerabilities — each with the request, code path and stack trace — stream into the same Findings queue. IAST is in early access (JVM first).

The policy

What fails a scan is your organisation's scan policy (Organization → Scan policy), or a project's own (the project's Settings tab → Scan policy → Customize): a severity threshold for code and dependency findings, fixable-only, malicious packages, possible typosquats, licenses your license policy denies, known-exploited vulnerabilities, an exploit-likelihood threshold, the age of an advisory, and whether a pull request is judged only on what it introduces. Until you change it, a scan fails on any open critical or high finding, a malicious package, a possible typosquat, or a package whose license your license policy denies. Marking a finding remediated or not processed, or a package not affected, counts at once — no rescan.