▸ CODESCAN
DocsSupportScanner
QUALITY GATES

Quality Gates

A quality gate is a hard pass/fail verdict attached to every scan. It answers one question: “Is this codebase safe enough to ship?” — and stops a CI build automatically if the answer is no.

Without a gate, teams see findings but nothing enforces action. With a gate, a PR with a new critical vulnerability cannot merge until it is fixed.

How it works — step by step

1
Scan
CodeScan runs the 5-step AI pipeline across your files and produces a list of findings — each with a severity (critical / high / medium / low).
2
Score
The findings are converted into a single numeric score (0–100) using the deduction formula. Every critical costs 25 points, every high costs 10, and so on. The score is clamped to [0, 100].
3
Compare against thresholds
The score and per-severity counts are checked against your gate config (defaults: max 0 critical, max 3 high, max 10 medium, min score 70). Any check that fails becomes a violation.
4
Verdict
If there are zero violations the gate passes and the build continues. If any violation exists the gate fails and the build exits with code 1 — blocking the merge.

The security score

The score starts at 100 and loses points for each finding. Deductions are weighted by severity so a single critical has the same impact as ten medium findings:

score = 100
       − (critical_count × 25)
       − (high_count     × 10)
       − (medium_count   ×  3)
       − (low_count      ×  1)

# clamped to [0, 100]

# Examples:
# 0 findings                    → 100  Grade A
# 1 critical                    →  75  Grade C
# 1 critical + 2 high           →  55  Grade F
# 3 high + 5 medium             →  55  Grade F
# 10 medium only                →  70  Grade C

The score maps to a letter grade displayed in every scan summary and PR comment:

GradeScoreMeaningTypical state
A90–100ExcellentNo critical or high findings
B80–89GoodA handful of low findings only
C70–79AcceptableSome medium findings — needs monitoring
D60–69Needs workHigh findings present — fix before ship
F0–59FailingCritical or many high findings — block now

Gate thresholds

A gate can have up to four checks. All four run every time — if any one fails, the gate fails. You can raise or lower each threshold independently to match your team's risk tolerance.

CheckDefaultWhat it testsCLI flag
max_critical0Number of critical findings ≤ threshold--gate-max-critical
max_high3Number of high findings ≤ threshold--gate-max-high
max_medium10Number of medium findings ≤ threshold--gate-max-medium
min_score70Security score ≥ threshold--gate-min-score

Using the gate — CLI

The score is always computed and shown. Add --gate to enforce it — the CLI exits with code 1 if any threshold is violated.

Quickstart

codescan scan --dir ./src --gate

Terminal output — gate passed

────────────────────────────────────────────────────────────
SCAN SUMMARY
────────────────────────────────────────────────────────────
  Files scanned : 12
  Files skipped : 0
  Duration      : 8.4s

  HIGH      : 2
  MEDIUM    : 4
  LOW       : 1
  Total     : 7

  SCORE         : 83/100  Grade B
  QUALITY GATE  : ✓ PASSED
────────────────────────────────────────────────────────────

Terminal output — gate failed

────────────────────────────────────────────────────────────
SCAN SUMMARY
────────────────────────────────────────────────────────────
  Files scanned : 12
  Files skipped : 0
  Duration      : 9.1s

  CRITICAL  : 1
  HIGH      : 4
  MEDIUM    : 6
  Total     : 11

  SCORE         : 51/100  Grade F
  QUALITY GATE  : ✗ FAILED
    ✗ Critical: 1 (max 0)
    ✗ High: 4 (max 3)
    ✗ Score: 51/100 (min 70)
────────────────────────────────────────────────────────────

Quality gate failed — 3 violation(s). Score: 51/100 (Grade F)
exit code 1

Custom thresholds per run

codescan scan --dir ./src --gate \
  --gate-max-critical 0   \   # zero tolerance for criticals
  --gate-max-high 2       \   # allow up to 2 highs
  --gate-max-medium 5     \   # allow up to 5 mediums
  --gate-min-score 80         # require at least B

Persisting config — .codescanrc.json

Instead of repeating flags on every run, drop a .codescanrc.json in your project root. The CLI reads it automatically. CLI flags always override the file.

// .codescanrc.json
{
  "gate": {
    "maxCritical": 0,
    "maxHigh": 2,
    "maxMedium": 5,
    "minScore": 80
  }
}

# Now this is enough — rc file supplies the thresholds:
codescan scan --dir ./src --gate

GitHub Actions integration

The full CI setup does four things in one step: scans the code, enforces the gate, exports a SARIF file to the GitHub Security tab, and posts a formatted comment directly on the PR.

Secrets setup

Add one secret to your GitHub repository: Settings → Secrets → Actions → New repository secret

CODESCAN_TOKENYour API token — get it from codesscan.com/scan
GITHUB_TOKENAlready available in every GitHub Actions run — no setup needed

Workflow file

# .github/workflows/codescan.yml
name: CodeScan Security

on:
  pull_request:          # runs on every PR
  push:
    branches: [main]     # runs on merges to main

jobs:
  security:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write   # required to upload SARIF
      pull-requests: write     # required to post PR comment

    steps:
      - uses: actions/checkout@v4

      - name: Run CodeScan
        run: |
          npx codescan-flowlog scan \
            --dir ./src \
            --gate \
            --sarif-out results.sarif \
            --pr-comment \
            --save-history \
            --fail-on high
        env:
          CODESCAN_TOKEN: ${{ secrets.CODESCAN_TOKEN }}
          GITHUB_TOKEN:   ${{ secrets.GITHUB_TOKEN }}

      # Upload findings to GitHub Security tab (runs even if gate fails)
      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

What happens on a PR

  • PR comment posted automatically — score, grade, gate status, and a table of the top findings appear as a comment the moment the scan finishes
  • Findings shown inline on the diff — SARIF upload surfaces each finding at the exact line in the Files Changed tab
  • Gate blocks the merge — if the gate fails the job exits with code 1 and GitHub marks the required check as failed
  • History saved — the scan result is stored to your account so you can track the score trend with codescan history

Example PR comment

🔍 CodeScan Security Report
Score: 83/100 (🟢 Grade B)  |  Gate: ✅ PASSED  |  Files: 12
Findings
SeverityCount
🟠 High2
🟡 Medium4
🔵 Low1
Powered by CodeScan · AI security scanning

SARIF export — standalone

Export a SARIF 2.1.0 file from any scan without running the full CI workflow:

codescan scan --dir ./src --sarif-out results.sarif

SARIF files can be uploaded to GitHub, imported into VS Code extensions, or consumed by any tool that supports the OASIS SARIF 2.1.0 standard. SARIF export requires the Starter plan or above.

Scan history & trend tracking

Every scan run with --save-history is stored to your account. Run codescan history any time to see how your score has moved:

# Save history during a scan
codescan scan --dir ./src --gate --save-history

# View the trend
codescan history --limit 10

  DATE                   SCORE    GRADE  VULNS  CRIT  TARGET
  ────────────────────────────────────────────────────────────
  13 May 2026 09:15      88/100   B      3      0     src
  12 May 2026 14:30      72/100   C      9      0     src
  11 May 2026 11:00      61/100   D      14     1     src
  Trend: ↑ +27 pts vs 3 scans ago

Each row is one scan run. The trend line at the bottom compares the latest score against the oldest in the window — so you can see at a glance whether the codebase is getting safer or drifting the wrong way.

Gate REST API

Call the gate directly from any custom tool or script — no CLI required. Pipe the results from /api/scan straight into /api/gate:

# Request
POST https://codesscan.com/api/gate
Content-Type: application/json

{
  "results": [ /* FileScanResult[] from /api/scan */ ],
  "config": {           # all fields optional — defaults shown
    "maxCritical": 0,
    "maxHigh": 3,
    "maxMedium": 10,
    "minScore": 70
  }
}

# Response — gate passed
{
  "score": 83,
  "grade": "B",
  "passed": true,
  "violations": [],
  "counts": { "critical": 0, "high": 2, "medium": 4, "low": 1 },
  "summary": { "files": 12, "totalVulnerabilities": 7 }
}

# Response — gate failed
{
  "score": 51,
  "grade": "F",
  "passed": false,
  "violations": [
    { "rule": "max_critical", "actual": 1, "threshold": 0, "message": "Critical: 1 (max 0)" },
    { "rule": "min_score",    "actual": 51, "threshold": 70, "message": "Score: 51/100 (min 70)" }
  ],
  "counts": { "critical": 1, "high": 4, "medium": 6, "low": 0 },
  "summary": { "files": 12, "totalVulnerabilities": 11 }
}

History REST API

# List your last N scans (max 100)
GET /api/scan/history?limit=20
Authorization: Bearer <token>

# Save a scan result manually
POST /api/scan/history
Authorization: Bearer <token>
{ "results": [...], "target": "./src", "source": "cli" }