Skip to content

feat: SAST — quality gate on deployment branch #20

@ms280690

Description

@ms280690

Context

Stage: Deployment branch (merge to main / staging / prod)
Tool: sonarqube
Scope: Application source code — all languages supported by SonarQube (30+)
Parent: (see SAST parent issue)

IaC and Helm/Kustomize are out of scope for Step 4 SAST. SonarQube has partial Terraform/CF support but Step 17 (checkov) is the designated IaC security scanner.

Why sonarqube at deployment branch

codeql (#19) provides deep semantic analysis on every PR. SonarQube serves a different function at the deployment branch stage:

  • Quality gate: a named pass/fail threshold (coverage %, new bugs, new code smells, new security hotspots) that must be green before a branch is considered promotable to production
  • Historical trend analysis: tracks code quality and security debt over time across all branches — identifies regressions introduced between releases
  • PR decoration: posts a summary comment on the PR with the delta (new issues introduced by this PR) even when the PR scan is run by codeql
  • 30+ language support: same SonarQube server instance covers the full Sparkgeo stack without per-language configuration

codeql does not provide quality gates or trend dashboards — it surfaces findings per scan without aggregation. SonarQube fills that gap. Together they provide: deep semantic analysis (codeql) + quality gate enforcement + longitudinal visibility (SonarQube).

Infrastructure prerequisite

SonarQube Community Edition (free, self-hosted) must be deployed before consuming repos can use this workflow. Deploy once per organisation:

# Recommended: SonarQube via Helm on the existing EKS cluster
helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
helm upgrade --install sonarqube sonarqube/sonarqube \
  --namespace sonarqube --create-namespace \
  --set sonarqube.edition=community

Store the following as GitHub org secrets / variables once SonarQube is deployed:

  • SONAR_HOST_URL (org variable): SonarQube server URL
  • SONAR_TOKEN (org secret): analysis token scoped to the project

Reusable workflow — sast-gate.yml

name: SAST Gate
on:
  workflow_call:
    inputs:
      project-key:
        description: 'SonarQube project key (unique per repo)'
        required: true
        type: string
      sources:
        description: 'Comma-separated source directories to analyse'
        default: '.'
        type: string
      quality-gate-wait:
        description: 'Block until Quality Gate result is available'
        default: true
        type: boolean
    secrets:
      SONAR_TOKEN:
        required: true
      SONAR_HOST_URL:
        required: true

Consuming repo usage

# .github/workflows/sast-gate.yml
name: SAST Gate
on:
  push:
    branches: [main, staging]
jobs:
  sonarqube:
    uses: sparkgeo/github-actions/.github/workflows/sast-gate.yml@main
    with:
      project-key: prescient-platform-api
    secrets:
      SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
      SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}

sonar-project.properties (in consuming repo root)

sonar.projectKey=prescient-platform-api
sonar.projectName=Prescient Platform API
sonar.sources=src
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml

Quality gate configuration (recommended baseline)

Configure in SonarQube UI under Administration → Quality Gates:

Condition Threshold Blocks deploy
New security hotspots reviewed 100% Yes
New bugs 0 Yes
New code coverage ≥ 80% Yes
New duplicated lines < 3% No (warning)

Relationship to codeql (#19)

codeql (#19) sonarqube (#20)
Trigger Every PR Merge to deployment branch
Analysis type Deep data-flow / taint analysis Pattern-based + quality metrics
Output Inline PR annotations via SARIF Quality gate pass/fail + trend dashboard
Infrastructure Zero (GitHub-hosted) Self-hosted SonarQube server
Best for Catching semantic vulnerabilities at PR Enforcing quality gates before promotion + tracking debt over time

Metadata

Metadata

Assignees

Labels

No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions