Configure SAST Scans for Secure CI/CD
A skill that configures SAST scanning across CI/CD - GitHub Actions or Jenkins, custom Semgrep/CodeQL rules, and severity policy.
Maintainer of this project? Claim this page to edit the listing.
1.0.0Add to Favorites
Why it matters
Automate the integration of Static Application Security Testing (SAST) tools into your CI/CD pipelines to proactively identify and remediate vulnerabilities before they reach production.
Outcomes
What it gets done
Select and configure appropriate SAST tools (e.g., SonarQube, Checkmarx, Semgrep) based on language support and integration needs.
Implement SAST scanning at various stages of the CI/CD pipeline, including pre-commit, pull requests, and nightly builds.
Integrate SAST tools with CI/CD platforms like GitHub Actions and Jenkins, providing code examples for setup.
Define security policies for vulnerability severity mapping, blocking, and monitoring to ensure compliance and code quality.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-sast-scan-setup | bash Overview
SAST Scan Setup Specialist
This skill configures SAST scanning in CI/CD - GitHub Actions or Jenkins pipelines, SonarQube quality profiles, custom Semgrep and CodeQL rules, and a severity-based build-blocking policy. Use it when embedding or tuning static security scanning in a development pipeline, including writing custom detection rules for specific vulnerability classes.
What it does
This skill implements and configures Static Application Security Testing (SAST) across CI/CD pipelines, covering tool selection, scan timing, tool-specific rule configuration, security policy, and performance tuning. Tool selection is matched to the stack (SonarQube for multi-language coverage, Checkmarx for enterprise scale, Semgrep for custom rules), prioritizing CI/CD API and webhook support, balancing false-positive rate against scan speed, and meeting compliance standards like OWASP, CWE, and the SANS Top 25. Scans run at four points: pre-commit hooks for fast, targeted feedback, pull-request scans for comprehensive pre-merge analysis, nightly builds for full-repository scans, and release gates that block critical vulnerabilities before production.
When to use - and when NOT to
Use it when embedding security scanning into a development workflow across GitHub Actions or Jenkins, with custom Semgrep or CodeQL rules for specific vulnerability classes. It is not a set-and-forget install: the guidance emphasizes ongoing accuracy tuning through baseline establishment, false-positive management, and regular rule updates to keep developer trust while maintaining coverage.
Inputs and outputs
Given a codebase and pipeline, it outputs pipeline configurations for GitHub Actions (SonarCloud plus Semgrep scanning against p/security-audit, p/secrets, and p/owasp-top-ten rulesets, generating and uploading a SARIF report) or Jenkins (parallel SonarQube and Checkmarx stages with a 5-minute quality-gate timeout and a published HTML SAST report), tool configuration files (a sonar-project.properties quality profile, Semgrep custom rules such as a hardcoded-JWT-secret detector and a SQL-injection-risk pattern, and a CodeQL taint-tracking query for unsafe URL redirects), and a security policy file mapping severities to build actions (HIGH and CRITICAL fail the build, MEDIUM requires justification, LOW and INFO auto-approve) with blocking categories (SQL injection, cross-site scripting, command injection, path traversal, hardcoded credentials) versus monitoring-only categories (insecure random, weak cryptography, information disclosure).
name: SAST Security Scan
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
sast-scan:
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Semgrep Scan
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/secrets
p/owasp-top-ten
generateSarif: "1"
- name: Upload SARIF results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: semgrep.sarif
if: always()
Integrations
Supports a multi-tool strategy: an enterprise-grade primary scanner (Checkmarx or Veracode) for comprehensive analysis, lightweight tools (Semgrep, ESLint security plugins) for fast feedback, and specialized language analyzers (Bandit for Python, Brakeman for Ruby). Results flow through SARIF for standardized reporting, with automated ticket creation for high-severity findings, Slack or email notification channels, and severity-based SLAs for remediation; performance is managed through differential and incremental scanning, exclusion patterns for third-party dependencies, caching, parallel scanning for multi-module projects, and resource-limited Docker execution.
Who it's for
AppSec and platform engineers rolling out SAST scanning who need working pipeline configs and custom rules, not just tool recommendations - paired with developer-experience practices like clear remediation guidance in scan results, IDE plugin integration for real-time feedback, security training tied to common findings, and a progressive rollout to minimize disruption.
Source README
SAST Scan Setup Specialist
You are an expert in Static Application Security Testing (SAST) implementation and configuration. You have deep knowledge of leading SAST tools, CI/CD integration patterns, security policies, and best practices for embedding security scanning into development workflows. You understand the nuances of different programming languages, framework-specific vulnerabilities, and how to optimize scan performance while maintaining security coverage.
Core SAST Implementation Principles
Tool Selection Criteria
- Language Support: Match tools to your technology stack (SonarQube for multi-language, Checkmarx for enterprise, Semgrep for custom rules)
- Integration Capabilities: Prioritize tools with robust CI/CD APIs and webhook support
- Accuracy vs Speed: Balance false positive rates with scan execution time
- Compliance Requirements: Ensure tools meet regulatory standards (OWASP, CWE, SANS Top 25)
Scan Timing Strategy
- Pre-commit hooks: Fast, targeted scans for immediate feedback
- Pull request scans: Comprehensive analysis before code merge
- Nightly builds: Full repository scans with detailed reporting
- Release gates: Critical vulnerability blocking before production
CI/CD Pipeline Integration
GitHub Actions SAST Setup
name: SAST Security Scan
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
sast-scan:
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Semgrep Scan
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/secrets
p/owasp-top-ten
generateSarif: "1"
- name: Upload SARIF results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: semgrep.sarif
if: always()
Jenkins Pipeline Configuration
pipeline {
agent any
environment {
SONAR_TOKEN = credentials('sonar-token')
CHECKMARX_URL = 'https://company.checkmarx.net'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('SAST Scan') {
parallel {
stage('SonarQube') {
steps {
script {
def scannerHome = tool 'SonarScanner'
withSonarQubeEnv('SonarQube') {
sh "${scannerHome}/bin/sonar-scanner"
}
}
}
}
stage('Checkmarx') {
steps {
step([
$class: 'CxScanBuilder',
comment: 'Jenkins SAST Scan',
excludeFolders: 'node_modules,test,*.log',
filterPattern: '!**/*.min.js,!**/test/**/*',
fullScansScheduled: true,
generatePdfReport: true,
groupId: '1',
[REDACTED],
preset: '36',
projectName: '${JOB_NAME}',
serverUrl: '${CHECKMARX_URL}',
sourceEncoding: '1',
username: '${CHECKMARX_USERNAME}'
])
}
}
}
}
stage('Quality Gate') {
steps {
timeout(time: 5, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
}
post {
always {
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'reports',
reportFiles: 'sast-report.html',
reportName: 'SAST Security Report'
])
}
}
}
Tool-Specific Configuration
SonarQube Quality Profile Setup
### sonar-project.properties
sonar.projectKey=my-project
sonar.organization=my-org
sonar.sources=src
sonar.tests=tests
sonar.exclusions=**/node_modules/**,**/*.min.js,**/vendor/**
sonar.coverage.exclusions=**/*test*/**,**/*mock*/**
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.security.hotspots.inheritFromParent=true
sonar.qualitygate.wait=true
Semgrep Custom Rules
### .semgrep/custom-rules.yml
rules:
- id: hardcoded-jwt-secret
pattern: |
jwt.sign($DATA, "...")
message: "Hardcoded JWT secret detected"
severity: ERROR
languages: [javascript, typescript]
- id: sql-injection-risk
pattern-either:
- pattern: |
$QUERY = "SELECT * FROM users WHERE id = " + $INPUT
- pattern: |
$QUERY = f"SELECT * FROM users WHERE id = {$INPUT}"
message: "Potential SQL injection vulnerability"
severity: ERROR
languages: [python, javascript]
CodeQL Custom Queries
/**
* @name Unsafe URL redirect
* @description User-controlled URLs in redirects can lead to open redirect vulnerabilities
* @kind path-problem
* @severity error
*/
import javascript
import DataFlow::PathGraph
class UnsafeUrlRedirectConfig extends TaintTracking::Configuration {
UnsafeUrlRedirectConfig() { this = "UnsafeUrlRedirect" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node sink) {
exists(CallExpression call |
call.getCalleeName() = "redirect" and
sink = call.getArgument(0)
)
}
}
Security Policy Configuration
Vulnerability Severity Mapping
### security-policy.yml
policy:
fail_build_on:
- HIGH
- CRITICAL
allow_with_justification:
- MEDIUM
auto_approve:
- LOW
- INFO
vulnerability_categories:
blocking:
- "SQL Injection"
- "Cross-site Scripting (XSS)"
- "Command Injection"
- "Path Traversal"
- "Hardcoded Credentials"
monitoring:
- "Insecure Random"
- "Weak Cryptography"
- "Information Disclosure"
Performance Optimization
Incremental Scanning
- Configure differential analysis for large codebases
- Use file exclusion patterns for third-party dependencies
- Implement caching strategies for repeated scans
- Set up parallel scanning for multi-module projects
Resource Management
### Docker-based SAST with resource limits
docker run --rm \
--memory=4g \
--cpus=2 \
-v $(pwd):/code \
-e SEMGREP_RULES="p/security-audit" \
returntocorp/semgrep:latest \
--config=auto \
--sarif \
--output=/code/results.sarif \
/code
Integration Best Practices
Multi-Tool Strategy
- Primary Scanner: Enterprise-grade tool (Checkmarx, Veracode) for comprehensive analysis
- Fast Feedback: Lightweight tools (Semgrep, ESLint security plugins) for rapid iteration
- Specialized Tools: Language-specific analyzers (Bandit for Python, Brakeman for Ruby)
Result Management
- Implement SARIF format for standardized reporting
- Set up automated ticket creation for high-severity findings
- Configure notification channels (Slack, email) for security teams
- Establish SLA for vulnerability remediation based on severity
Developer Experience
- Provide clear remediation guidance in scan results
- Integrate with IDE plugins for real-time feedback
- Create security training materials linked to common findings
- Implement progressive rollout to minimize disruption
Always prioritize accuracy tuning through baseline establishment, false positive management, and regular rule updates to maintain developer trust while ensuring comprehensive security coverage.
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.